You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
281 lines
8.0 KiB
281 lines
8.0 KiB
package pay_service
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"github.com/iGoogle-ink/gopay/v2"
|
|
"github.com/iGoogle-ink/gopay/v2/wechat"
|
|
"github.com/ouxuanserver/osmanthuswine/src/core"
|
|
"hudongzhuanjia/libs/wx"
|
|
"hudongzhuanjia/logger"
|
|
"hudongzhuanjia/models"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
const CALLBACK_ORDER_URL = "https://api.ouxuanhudong.com/PcClient/common/WeChatOauthCtl/callbackOrder"
|
|
|
|
func Order(content, ip, openid string, fee, goodType int, userId, activityId int64) (map[string]interface{}, error) {
|
|
client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true)
|
|
|
|
//设置国家
|
|
client.SetCountry(wechat.China)
|
|
now := time.Now()
|
|
|
|
outTradeNo := gopay.GetRandomString(32)
|
|
nonceStr := gopay.GetRandomString(32)
|
|
timeStart := now.Format("20060101150405")
|
|
timeExpire := now.Add(2 * time.Hour).Format("20060101150405")
|
|
|
|
//初始化参数Map
|
|
body := make(gopay.BodyMap)
|
|
body.Set("nonce_str", nonceStr)
|
|
body.Set("body", content)
|
|
body.Set("out_trade_no", outTradeNo)
|
|
body.Set("total_fee", fee)
|
|
body.Set("spbill_create_ip", ip)
|
|
body.Set("notify_url", CALLBACK_ORDER_URL)
|
|
body.Set("trade_type", wechat.TradeType_JsApi)
|
|
body.Set("device_info", "WEB")
|
|
body.Set("sign_type", wechat.SignType_MD5)
|
|
body.Set("openid", openid)
|
|
body.Set("time_start", timeStart)
|
|
//body.Set("time_expire", timeExpire)
|
|
|
|
//请求支付下单,成功后得到结果
|
|
res, err := client.UnifiedOrder(body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
//ok, err := wechat.VerifySign(wx.ApiKey, wechat.SignType_MD5, res)
|
|
//if err != nil {
|
|
// return nil, err
|
|
//}
|
|
//if !ok {
|
|
// return nil, errors.New("签名验证失败")
|
|
//}
|
|
|
|
if res.ReturnCode != wx.CODE_SUCCESS {
|
|
return nil, fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
|
|
}
|
|
|
|
if res.ResultCode != wx.CODE_SUCCESS {
|
|
return nil, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
|
|
}
|
|
|
|
userOrder := new(models.UserOrder)
|
|
userOrder.DeviceInfo = "WEB"
|
|
userOrder.Desc = content
|
|
userOrder.UserId = userId
|
|
userOrder.ActivityId = activityId
|
|
userOrder.FeeType = "CNY"
|
|
userOrder.GoodType = goodType
|
|
userOrder.OpenId = openid
|
|
userOrder.OutTradeNo = outTradeNo
|
|
userOrder.TimeStart = timeStart
|
|
userOrder.TimeExpire = timeExpire
|
|
userOrder.TotalFee = fee
|
|
userOrder.TradeType = wechat.TradeType_JsApi
|
|
userOrder.PrepayId = res.PrepayId
|
|
userOrder.Status = 0
|
|
userOrder.IsDelete = false
|
|
userOrder.CreatedAt = time.Now()
|
|
userOrder.UpdatedAt = time.Now()
|
|
if _, err := core.GetXormAuto().InsertOne(userOrder); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
|
|
//获取H5支付需要的paySign
|
|
pac := "prepay_id=" + res.PrepayId
|
|
paySign := wechat.GetH5PaySign(wx.Appid, res.NonceStr, pac, wechat.SignType_MD5, timestamp, wx.ApiKey)
|
|
return map[string]interface{}{
|
|
"appid": wx.Appid,
|
|
"timestamp": timestamp,
|
|
"nonce_str": res.NonceStr,
|
|
"package": pac,
|
|
"sign_type": wechat.SignType_MD5,
|
|
"pay_sign": paySign,
|
|
"out_trade_no": outTradeNo,
|
|
"user_order_id": userOrder.Id,
|
|
}, nil
|
|
}
|
|
|
|
func CallbackOrder(req *http.Request) error {
|
|
res, err := wechat.ParseNotifyResult(req)
|
|
if err != nil {
|
|
logger.Sugar.Error("解析微信毁掉结果失败")
|
|
return err
|
|
}
|
|
//ok, err := wechat.VerifySign(wx.ApiKey, wechat.SignType_MD5, res)
|
|
//if err != nil {
|
|
// return err
|
|
//}
|
|
//if !ok {
|
|
// return errors.New("sign verify failed")
|
|
//}
|
|
|
|
if res.ReturnCode != wx.CODE_SUCCESS {
|
|
return fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
|
|
}
|
|
|
|
if res.ResultCode != wx.CODE_SUCCESS {
|
|
return fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
|
|
}
|
|
|
|
userOrder := new(models.UserOrder)
|
|
exist, err := userOrder.GetByOutTradeNo(res.OutTradeNo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !exist {
|
|
return fmt.Errorf("user order not exist")
|
|
}
|
|
userOrder.TimeEnd = res.TimeEnd
|
|
userOrder.TransactionId = res.TransactionId
|
|
userOrder.Status = 1
|
|
if _, err := core.GetXormAuto().Id(userOrder.Id).Cols("time_end, transaction_id, status").Update(userOrder); err != nil {
|
|
return err
|
|
}
|
|
// 设置一下
|
|
if userOrder.GoodType == 1 { // 霸屏
|
|
history := new(models.BullyScreenHistory)
|
|
history.Status = 0
|
|
_, err := core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrder.Id).Cols("status").Update(history)
|
|
return err
|
|
} else if userOrder.GoodType == 2 {
|
|
history := new(models.RewardHistory)
|
|
history.Status = 0
|
|
_, err := core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrder.Id).Cols("status").Update(history)
|
|
return err
|
|
}
|
|
logger.Sugar.Infof("%+v", res)
|
|
return nil
|
|
}
|
|
|
|
func Query(outTradeNo string) (*wechat.QueryOrderResponse, error) {
|
|
client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true)
|
|
|
|
client.SetCountry(wechat.China)
|
|
|
|
body := make(gopay.BodyMap)
|
|
body.Set("out_trade_no", outTradeNo)
|
|
body.Set("nonce_str", gopay.GetRandomString(32))
|
|
body.Set("sign_type", wechat.SignType_MD5)
|
|
|
|
// 请求订单查询,成功后得到结果
|
|
res, err := client.QueryOrder(body)
|
|
if err != nil {
|
|
logger.Sugar.Errorf("wechat query order error, %s", err)
|
|
return nil, err
|
|
}
|
|
|
|
if res.TradeState == wx.CODE_SUCCESS { // 付款成功
|
|
userOrder := new(models.UserOrder)
|
|
userOrder.Status = 1
|
|
if _, err := core.GetXormAuto().Where("is_delete=0 and out_trade_no=?", outTradeNo).
|
|
Cols("status").Update(userOrder); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
func BatchQueryByUserId(userId int64) error {
|
|
orders := make([]*models.UserOrder, 0)
|
|
if err := core.GetXormAuto().Where("is_delete = 0 and status = 0 and user_id = ?", userId).Find(&orders); err != nil {
|
|
return err
|
|
}
|
|
|
|
return batchQuery(orders)
|
|
}
|
|
|
|
func BatchQueryByActivityId(activityId int64) error {
|
|
orders := make([]*models.UserOrder, 0)
|
|
if err := core.GetXormAuto().Where("is_delete = 0 and status = 0 and activity_id = ?", activityId).Find(&orders); err != nil {
|
|
return err
|
|
}
|
|
|
|
return batchQuery(orders)
|
|
}
|
|
|
|
func batchQuery(orders []*models.UserOrder) error {
|
|
for _, order := range orders {
|
|
res, err := Query(order.OutTradeNo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if res.TradeState == wx.CODE_SUCCESS { // 付款成功
|
|
order.Status = 1 // 已支付
|
|
order.TransactionId = res.TransactionId
|
|
|
|
if _, err := core.GetXormAuto().ID(order.Id).Cols("status, transaction_id").Update(order); err != nil {
|
|
return err
|
|
}
|
|
if order.GoodType == 1 {
|
|
history := new(models.BullyScreenHistory)
|
|
exist, err := history.GetByUserOrderId(order.Id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !exist {
|
|
return errors.New("BullyScreenHistory not exist")
|
|
}
|
|
if history.Status == -1 {
|
|
if _, err := history.UpdateStatus(history.Id, 0); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
} else if order.GoodType == 2 {
|
|
history := new(models.RewardHistory)
|
|
exist, err := history.GetByUserOrderId(order.Id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !exist {
|
|
return errors.New("RewardHistory not exist")
|
|
}
|
|
if history.Status == 0 {
|
|
break
|
|
}
|
|
if history.Status == -1 {
|
|
if _, err := history.UpdateStatus(history.Id, 0); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
} else {
|
|
logger.Sugar.Info("支付测试")
|
|
}
|
|
} else if order.TimeExpire <= time.Now().Format("20060101150405") {
|
|
Close(order.OutTradeNo)
|
|
order.Status = -1 // 关闭支付
|
|
order.TransactionId = res.TransactionId
|
|
if _, err := core.GetXormAuto().ID(order.Id).Cols("status, transaction_id").Update(order); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func Close(outTradeNo string) (*wechat.CloseOrderResponse, error) {
|
|
client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true)
|
|
|
|
// 初始化参数结构体
|
|
body := make(gopay.BodyMap)
|
|
body.Set("out_trade_no", outTradeNo)
|
|
body.Set("nonce_str", gopay.GetRandomString(32))
|
|
body.Set("sign_type", wechat.SignType_MD5)
|
|
|
|
// 请求关闭订单,成功后得到结果
|
|
wxRsp, err := client.CloseOrder(body)
|
|
if err != nil {
|
|
fmt.Println("Error:", err)
|
|
return nil, err
|
|
}
|
|
fmt.Println("wxRsp:", *wxRsp)
|
|
return wxRsp, nil
|
|
}
|