784 lines
20 KiB
Go
784 lines
20 KiB
Go
package mainservice
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"f5"
|
|
"fmt"
|
|
"io"
|
|
"main/constant"
|
|
"main/model"
|
|
"main/mt"
|
|
"main/service"
|
|
"q5"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type MainServiceApi struct {
|
|
}
|
|
|
|
func (this *MainServiceApi) RefreshToken(c *gin.Context) {
|
|
reqtime := q5.SafeToInt64(c.Query("time"))
|
|
reqsign := c.Query("sign")
|
|
nowTime := f5.GetApp().GetRealSeconds()
|
|
if reqtime > nowTime+30 || reqtime+30 < nowTime {
|
|
f5.RspErr(c, 400, "request error")
|
|
return
|
|
}
|
|
|
|
sign := service.Wxpay.GenSHA256Signature(c.Query("time")+constant.GLOBAL_SALT, constant.GLOBAL_SALT)
|
|
if reqsign != sign {
|
|
f5.RspErr(c, 400, "request error 2")
|
|
return
|
|
}
|
|
|
|
rspObj := struct {
|
|
Data []service.TokenInfo `json:"data"`
|
|
ErrCode int64 `json:"errcode"`
|
|
ErrMsg string `json:"errmsg"`
|
|
}{}
|
|
|
|
service.Wxpay.GetAccessTokenList(&rspObj.Data)
|
|
c.JSON(200, rspObj)
|
|
}
|
|
|
|
func (this *MainServiceApi) WxTNotify(c *gin.Context) {
|
|
f5.GetSysLog().Debug("wx test notify:%s, %s", c.Param("gameid"), c.Request.URL.RawQuery)
|
|
|
|
signature := c.Query("signature")
|
|
timestamp := c.Query("timestamp")
|
|
nonce := c.Query("nonce")
|
|
echostr := c.Query("echostr")
|
|
gameid := q5.SafeToInt64(c.Param("gameid"))
|
|
cfg := mt.Table.Wxconfig.GetById(gameid)
|
|
if cfg == nil {
|
|
c.String(200, "wrong")
|
|
return
|
|
}
|
|
|
|
strs := []string{cfg.GetWxNotifyToken(), timestamp, nonce}
|
|
sort.Strings(strs)
|
|
sb := strings.Builder{}
|
|
sb.WriteString(strs[0])
|
|
sb.WriteString(strs[1])
|
|
sb.WriteString(strs[2])
|
|
m := sha1.New()
|
|
io.WriteString(m, sb.String())
|
|
sign := string(hex.EncodeToString(m.Sum(nil)))
|
|
|
|
f5.GetSysLog().Debug("game:%d, wx sign:%s, %s", gameid, sign, signature)
|
|
|
|
if sign != signature {
|
|
c.String(200, "wrong")
|
|
return
|
|
}
|
|
|
|
c.String(200, echostr)
|
|
}
|
|
|
|
func (this *MainServiceApi) WxNotifyPurchase(c *gin.Context) {
|
|
f5.GetSysLog().Debug("wx notify purchase:%s, %s", c.Param("gameid"), c.Request.URL.RawQuery)
|
|
|
|
timestamp := c.Query("timestamp")
|
|
nonce := c.Query("nonce")
|
|
|
|
rspObj := struct {
|
|
ErrorCode int32 `json:"ErrCode"`
|
|
ErrMsg string `json:"ErrMsg"`
|
|
}{
|
|
ErrorCode: 99999,
|
|
ErrMsg: "internal error",
|
|
}
|
|
|
|
gameid := q5.SafeToInt64(c.Param("gameid"))
|
|
cfg := mt.Table.Wxconfig.GetById(gameid)
|
|
if cfg == nil {
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
msg_signature := c.Query("msg_signature")
|
|
if msg_signature != "" {
|
|
postObj := struct {
|
|
Encrypt string `json:"Encrypt"`
|
|
ToUserName string `json:"ToUserName"`
|
|
}{}
|
|
|
|
if err := c.ShouldBindJSON(&postObj); err != nil {
|
|
rspObj.ErrorCode = 401
|
|
rspObj.ErrMsg = "post data error"
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
smsg, appid := service.Wxpay.DecryptMsg(msg_signature, timestamp, nonce, postObj.Encrypt, cfg.GetWxNotifyToken(), cfg.GetWxNotifyEncodingAesKey())
|
|
if len(smsg) == 0 || len(appid) == 0 {
|
|
f5.GetSysLog().Debug("decrypt data error")
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
f5.GetSysLog().Debug("wx decrypt msg:%s", smsg)
|
|
|
|
wxnotifyobj := service.WxPurchaseNotify{}
|
|
if json.Unmarshal(smsg, &wxnotifyobj) != nil {
|
|
f5.GetSysLog().Debug("unmarshal data error")
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
gameid := int64(0)
|
|
appkey := ""
|
|
notifyurl := ""
|
|
mt.Table.Wxconfig.Traverse(func(w *mt.Wxconfig) bool {
|
|
if w.GetAppid() == string(appid) {
|
|
gameid = w.GetGameid()
|
|
appkey = w.GetAppkey()
|
|
notifyurl = w.GetNotifyurl()
|
|
return false
|
|
}
|
|
return true
|
|
})
|
|
|
|
if appkey == "" {
|
|
f5.GetSysLog().Error("wx app config error:%s", appid)
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
oristr := wxnotifyobj.Event + "&" + wxnotifyobj.MiniGame.Payload
|
|
sig := service.Wxpay.GenSHA256Signature(oristr, appkey)
|
|
if sig != wxnotifyobj.MiniGame.PayEventSig {
|
|
f5.GetSysLog().Error("pay event sig error:%s, %s, %s", appid, sig, wxnotifyobj.MiniGame.PayEventSig)
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
if wxnotifyobj.MiniGame.IsMock {
|
|
rspObj.ErrorCode = 0
|
|
rspObj.ErrMsg = "Success"
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
payloadobj := new(service.WxPayload)
|
|
if json.Unmarshal([]byte(wxnotifyobj.MiniGame.Payload), &payloadobj) != nil {
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
envpass := true
|
|
if f5.IsOnlineEnv() {
|
|
if payloadobj.Env != 0 {
|
|
f5.GetSysLog().Error("notify test info to prod url")
|
|
envpass = false
|
|
}
|
|
} else {
|
|
if payloadobj.Env != 1 {
|
|
f5.GetSysLog().Error("notify prod info to test url")
|
|
envpass = false
|
|
}
|
|
}
|
|
|
|
if !envpass {
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
orderModel := new(model.InAppOrder)
|
|
if err, found := orderModel.FindByOrderId(payloadobj.OutTradeNo); err != nil {
|
|
c.JSON(200, rspObj)
|
|
return
|
|
} else if !found {
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
if orderModel.ItemId != q5.SafeToInt32(payloadobj.GoodsInfo.ProductId) {
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
if orderModel.Status > 1 {
|
|
rspObj.ErrorCode = 0
|
|
rspObj.ErrMsg = "Success"
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
rediskey := "ls:accountid:" + orderModel.AccountId
|
|
str, err := service.Redis.Get(constant.LOGIN_REDIS, rediskey)
|
|
if err != nil {
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
data := map[string]interface{}{}
|
|
if json.Unmarshal([]byte(str), &data) != nil {
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
openid := q5.SafeToString(data["openid"])
|
|
if openid != payloadobj.OpenId {
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
orderModel.GameId = int32(gameid)
|
|
orderModel.Status = 1
|
|
|
|
rspObj.ErrorCode = 0
|
|
rspObj.ErrMsg = "Success"
|
|
f5.GetSysLog().Debug("notify url:%s, %s", appid, notifyurl)
|
|
|
|
nowtimestr := q5.SafeToString(f5.GetApp().GetRealSeconds())
|
|
originstr := "account_id=" + orderModel.AccountId
|
|
originstr += "&goodsid=" + payloadobj.GoodsInfo.ProductId
|
|
originstr += "&orderid=" + orderModel.OrderId
|
|
originstr += "&amount=" + q5.SafeToString(payloadobj.GoodsInfo.ActualPrice)
|
|
originstr += ":" + nowtimestr + constant.NOFITY_GAMESERVER_SALT
|
|
params := map[string]string{
|
|
"c": "Recharge",
|
|
"a": "purchaseNotify",
|
|
"account_id": orderModel.AccountId,
|
|
"orderid": orderModel.OrderId,
|
|
"timestamp": nowtimestr,
|
|
"goodsid": payloadobj.GoodsInfo.ProductId,
|
|
"amount": q5.SafeToString(payloadobj.GoodsInfo.ActualPrice),
|
|
"sign": q5.Md5Str(originstr),
|
|
}
|
|
f5.GetHttpCliMgr().SendGoStyleRequest(
|
|
notifyurl,
|
|
params,
|
|
func(hcr f5.HttpCliResponse) {
|
|
if hcr.GetErr() != nil {
|
|
return
|
|
}
|
|
|
|
gamerspObj := struct {
|
|
ErrCode int64 `json:"errcode"`
|
|
ErrMsg string `json:"errmsg"`
|
|
}{}
|
|
|
|
f5.GetSysLog().Debug("get game rsp:%s", hcr.GetRawData())
|
|
if json.Unmarshal([]byte(hcr.GetRawData()), &gamerspObj) != nil {
|
|
return
|
|
}
|
|
|
|
if gamerspObj.ErrCode == 0 {
|
|
orderModel.Status = 2
|
|
}
|
|
})
|
|
|
|
orderModel.UpdateFields([]string{"status", "gameid"})
|
|
}
|
|
|
|
c.JSON(200, rspObj)
|
|
}
|
|
|
|
func (this *MainServiceApi) WxMsgTNotify(c *gin.Context) {
|
|
f5.GetSysLog().Debug("wx msg test notify:%s, %s", c.Param("gameid"), c.Request.URL.RawQuery)
|
|
|
|
signature := c.Query("signature")
|
|
timestamp := c.Query("timestamp")
|
|
nonce := c.Query("nonce")
|
|
echostr := c.Query("echostr")
|
|
gameid := q5.SafeToInt64(c.Param("gameid"))
|
|
cfg := mt.Table.Wxconfig.GetById(gameid)
|
|
if cfg == nil {
|
|
c.String(200, "wrong")
|
|
return
|
|
}
|
|
|
|
strs := []string{cfg.GetWxMsgNotifyToken(), timestamp, nonce}
|
|
sort.Strings(strs)
|
|
sb := strings.Builder{}
|
|
sb.WriteString(strs[0])
|
|
sb.WriteString(strs[1])
|
|
sb.WriteString(strs[2])
|
|
m := sha1.New()
|
|
io.WriteString(m, sb.String())
|
|
sign := string(hex.EncodeToString(m.Sum(nil)))
|
|
|
|
f5.GetSysLog().Debug("wx t msg sign:%s, %s", sign, signature)
|
|
|
|
if sign != signature {
|
|
c.String(200, "wrong")
|
|
return
|
|
}
|
|
c.String(200, echostr)
|
|
}
|
|
|
|
func (this *MainServiceApi) WxMsgNotify(c *gin.Context) {
|
|
f5.GetSysLog().Debug("wx msg notify:%s, %s", c.Param("gameid"), c.Request.URL.RawQuery)
|
|
|
|
timestamp := c.Query("timestamp")
|
|
nonce := c.Query("nonce")
|
|
|
|
rspObj := struct {
|
|
ErrorCode int32 `json:"ErrCode"`
|
|
ErrMsg string `json:"ErrMsg"`
|
|
}{
|
|
ErrorCode: 99999,
|
|
ErrMsg: "internal error",
|
|
}
|
|
|
|
gameid := q5.SafeToInt64(c.Param("gameid"))
|
|
cfg := mt.Table.Wxconfig.GetById(gameid)
|
|
if cfg == nil {
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
msg_signature := c.Query("msg_signature")
|
|
if msg_signature != "" {
|
|
postObj := struct {
|
|
ToUserName string `json:"ToUserName"` //小程序的原始 ID
|
|
Encrypt string `json:"Encrypt"`
|
|
}{}
|
|
|
|
if err := c.ShouldBindJSON(&postObj); err != nil {
|
|
f5.GetSysLog().Debug("post data error ")
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
smsg, appid := service.Wxpay.DecryptMsg(msg_signature, timestamp, nonce, postObj.Encrypt, cfg.GetWxMsgNotifyToken(), cfg.GetWxMsgNotifyEncodingAesKey())
|
|
if len(smsg) == 0 || len(appid) == 0 {
|
|
f5.GetSysLog().Debug("decrypt msg data error")
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
rspObj.ErrorCode = 0
|
|
rspObj.ErrMsg = "success"
|
|
defer c.JSON(200, rspObj)
|
|
|
|
wxmsg := struct {
|
|
ToUserName string `json:"ToUserName"` //小程序的原始 ID
|
|
FromUserName string `json:"FromUserName"` //发送者的 openid
|
|
CreateTime int64 `json:"CreateTime"`
|
|
MsgType string `json:"MsgType"`
|
|
Content string `json:"Content"`
|
|
MediaId string `json:"MediaId"`
|
|
PicUrl string `json:"PicUrl"`
|
|
MsgId int64 `json:"MsgId"`
|
|
Event string `json:"Event"`
|
|
SessionFrom string `json:"SessionFrom"`
|
|
}{}
|
|
|
|
f5.GetSysLog().Debug("wx msg notify decrypted data:%s", smsg)
|
|
if err := json.Unmarshal(smsg, &wxmsg); err != nil {
|
|
f5.GetSysLog().Debug("decrypt msg data error")
|
|
return
|
|
}
|
|
|
|
if wxmsg.MsgType != "event" || wxmsg.Event != "user_enter_tempsession" {
|
|
return
|
|
}
|
|
|
|
strs := q5.StrSplit(wxmsg.SessionFrom, ":")
|
|
if len(strs) < 2 || strs[0] != "prepare_pay_from_game" {
|
|
return
|
|
}
|
|
|
|
orderid := strs[1]
|
|
orderModel := new(model.InAppOrder)
|
|
if err, found := orderModel.FindByOrderId(orderid); err != nil || !found {
|
|
return
|
|
}
|
|
|
|
thumburl := service.Wxpay.GenThumburl(int64(orderModel.GameId))
|
|
itemname, _ := service.Wxpay.GetGoodsName(int64(orderModel.GameId), int64(orderModel.ItemId))
|
|
|
|
// 发给客服系统的clicklink
|
|
clickurl := fmt.Sprintf("https://%s/wx/clicknotify?orderid=%s", cfg.GetWxPayNotifyHost(), orderid)
|
|
req := struct {
|
|
ToUser string `json:"touser"`
|
|
MsgType string `json:"msgtype"`
|
|
Link interface{} `json:"link"`
|
|
}{
|
|
ToUser: wxmsg.FromUserName,
|
|
MsgType: "link",
|
|
Link: struct {
|
|
Title string `json:"title"`
|
|
Description string `json:"description"`
|
|
Url string `json:"url"`
|
|
Thumb_url string `json:"thumb_url"`
|
|
}{
|
|
Title: fmt.Sprintf(cfg.GetWxPayLinkTitle(), itemname),
|
|
Description: cfg.GetWxPayLinkDescription(),
|
|
Url: clickurl,
|
|
Thumb_url: thumburl,
|
|
},
|
|
}
|
|
|
|
postbytes, err := json.Marshal(req)
|
|
|
|
dstUrl := service.Wxpay.GenSendWxMsgUrl(int64(orderModel.GameId))
|
|
f5.GetHttpCliMgr().SendGoStylePost(
|
|
dstUrl,
|
|
map[string]string{},
|
|
"Content-Type: application/json",
|
|
string(postbytes),
|
|
func(hcr f5.HttpCliResponse) {
|
|
if hcr.GetErr() != nil {
|
|
f5.GetSysLog().Error("Post wx custom msg err:%v dstUrl:%v", hcr.GetErr().Error(), dstUrl)
|
|
return
|
|
}
|
|
|
|
rspJson := struct {
|
|
Errcode int `json:"errcode"` // 0为成功
|
|
Errmsg string `json:"errmsg"` //
|
|
}{}
|
|
|
|
f5.GetSysLog().Debug("send wx custom msg rsp:%s", hcr.GetRawData())
|
|
err = q5.DecodeJson(hcr.GetRawData(), &rspJson)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if rspJson.Errcode != 0 {
|
|
f5.GetSysLog().Error("send wx custom msg error:%v", rspJson.Errmsg)
|
|
}
|
|
})
|
|
} else {
|
|
c.JSON(200, rspObj)
|
|
}
|
|
}
|
|
|
|
func (this *MainServiceApi) WxClickNotify(c *gin.Context) {
|
|
// balabala 校验代码
|
|
orderid := c.DefaultQuery("orderid", "")
|
|
if len(orderid) == 0 {
|
|
c.String(200, "")
|
|
return
|
|
}
|
|
|
|
orderModel := new(model.InAppOrder)
|
|
if err, found := orderModel.FindByOrderId(orderid); err != nil || !found {
|
|
c.String(200, "")
|
|
return
|
|
}
|
|
|
|
strs := strings.Split(orderModel.AccountId, "_")
|
|
if len(strs) < 3 {
|
|
c.String(200, "")
|
|
return
|
|
}
|
|
|
|
rediskey := "ls:accountid:" + orderModel.AccountId
|
|
str, err := service.Redis.Get(constant.LOGIN_REDIS, rediskey)
|
|
if err != nil {
|
|
c.String(200, "")
|
|
return
|
|
}
|
|
|
|
data := map[string]interface{}{}
|
|
if json.Unmarshal([]byte(str), &data) != nil {
|
|
c.String(200, "")
|
|
return
|
|
}
|
|
|
|
rspstr := service.Wxpay.GetPrepayInfoStr(q5.SafeToString(data["openid"]), int64(orderModel.GameId), orderModel.IP, orderid, int64(orderModel.ItemId))
|
|
|
|
c.Header("Content-Type", "text/html")
|
|
c.String(200, rspstr)
|
|
}
|
|
|
|
func (this *MainServiceApi) WxPayNotify(c *gin.Context) {
|
|
f5.GetSysLog().Debug("wx pay notify:%s", c.Request.URL.RawQuery)
|
|
|
|
failrspobj := struct {
|
|
Code string `json:"code"`
|
|
|
|
Msg string `json:"message"`
|
|
}{
|
|
Code: "FAIL",
|
|
Msg: "失败",
|
|
}
|
|
|
|
payserial := c.GetHeader("Wechatpay-Serial") //验签的微信支付平台证书序列号/微信支付公钥ID
|
|
if mt.Table.Config.GetWxMerchantPublicKeyId() != payserial {
|
|
f5.GetSysLog().Alert("!!!!!!!!!!cerificate Serial error")
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
paysign := c.GetHeader("Wechatpay-Signature") //验签的签名值
|
|
paytimestamp := c.GetHeader("Wechatpay-Timestamp") //验签的时间戳
|
|
paynonce := c.GetHeader("Wechatpay-Nonce") //验签的随机字符串
|
|
nowtime := f5.GetApp().GetRealSeconds()
|
|
paytime := q5.SafeToInt64(paytimestamp)
|
|
if paytime < nowtime-60 || paytime > nowtime+60 {
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
rawdata, err := c.GetRawData()
|
|
if err != nil {
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
f5.GetSysLog().Debug("wx pay post data:%s", rawdata)
|
|
rawstr := fmt.Sprintf("%s\n%s\n%s\n", paytimestamp, paynonce, rawdata)
|
|
if service.Wxpay.VerifyPaySign(rawstr, paysign) != nil {
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
postbodyObj := struct {
|
|
ID string `json:"id"`
|
|
CreateTime string `json:"create_time"`
|
|
ResourceType string `json:"resource_type"`
|
|
EventType string `json:"event_type"`
|
|
Summary string `json:"summary"`
|
|
Resource struct {
|
|
OT string `json:"original_type"`
|
|
Algorithm string `json:"algorithm"`
|
|
CT string `json:"ciphertext"`
|
|
AD string `json:"associated_data"`
|
|
Nonce string `json:"nonce"`
|
|
} `json:"resource"`
|
|
}{}
|
|
|
|
if json.Unmarshal(rawdata, &postbodyObj) != nil {
|
|
f5.GetSysLog().Debug("unmarshal wx pay post data errpr")
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
res := postbodyObj.Resource
|
|
decryptedData, err := service.Wxpay.DecryptPaydata(res.AD, res.Nonce, res.CT)
|
|
if err != nil {
|
|
f5.GetSysLog().Debug("decrypte pay data error:%s, %s, %s", res.AD, res.Nonce, res.CT)
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
f5.GetSysLog().Debug("pay decripted data:%s", decryptedData)
|
|
/*
|
|
{
|
|
"transaction_id":"1217752501201407033233368018",
|
|
"amount":{
|
|
"payer_total":100,
|
|
"total":100,
|
|
"currency":"CNY",
|
|
"payer_currency":"CNY"
|
|
},
|
|
"mchid":"1230000109",
|
|
"trade_state":"SUCCESS",
|
|
"bank_type":"CMC",
|
|
"promotion_detail":[
|
|
{
|
|
"amount":100,
|
|
"wechatpay_contribute":0,
|
|
"coupon_id":"109519",
|
|
"scope":"GLOBAL",
|
|
"merchant_contribute":0,
|
|
"name":"单品惠-6",
|
|
"other_contribute":0,
|
|
"currency":"CNY",
|
|
"stock_id":"931386",
|
|
"goods_detail":[
|
|
{
|
|
"goods_remark":"商品备注信息",
|
|
"quantity":1,
|
|
"discount_amount":1,
|
|
"goods_id":"M1006",
|
|
"unit_price":100
|
|
},
|
|
{
|
|
"goods_remark":"商品备注信息",
|
|
"quantity":1,
|
|
"discount_amount":1,
|
|
"goods_id":"M1006",
|
|
"unit_price":100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"amount":100,
|
|
"wechatpay_contribute":0,
|
|
"coupon_id":"109519",
|
|
"scope":"GLOBAL",
|
|
"merchant_contribute":0,
|
|
"name":"单品惠-6",
|
|
"other_contribute":0,
|
|
"currency":"CNY",
|
|
"stock_id":"931386",
|
|
"goods_detail":[
|
|
{
|
|
"goods_remark":"商品备注信息",
|
|
"quantity":1,
|
|
"discount_amount":1,
|
|
"goods_id":"M1006",
|
|
"unit_price":100
|
|
},
|
|
{
|
|
"goods_remark":"商品备注信息",
|
|
"quantity":1,
|
|
"discount_amount":1,
|
|
"goods_id":"M1006",
|
|
"unit_price":100
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"success_time":"2018-06-08T10:34:56+08:00",
|
|
"payer":{
|
|
"openid":"oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"
|
|
},
|
|
"out_trade_no":"1217752501201407033233368018",
|
|
"appid":"wxd678efh567hg6787",
|
|
"trade_state_desc":"支付成功",
|
|
"trade_type":"APP",
|
|
"attach":"自定义数据",
|
|
"scene_info":{
|
|
"device_id":"013467007045764"
|
|
}
|
|
}
|
|
|
|
*/
|
|
resObj := struct {
|
|
TransId string `json:"transaction_id"`
|
|
Amount struct {
|
|
PayerTotal int64 `json:"payer_total"`
|
|
Total int64 `json:"total"`
|
|
} `json:"amount"`
|
|
MchId string `json:"mchid"`
|
|
TradeState string `json:"trade_state"`
|
|
Payer struct {
|
|
Openid string `json:"openid"`
|
|
} `json:"payer"`
|
|
OrderId string `json:"out_trade_no"`
|
|
AppId string `json:"appid"`
|
|
SceneInfo struct {
|
|
DeviceId string `json:"device_id"`
|
|
} `json:"scene_info"`
|
|
}{}
|
|
err = json.Unmarshal([]byte(decryptedData), &resObj)
|
|
if err != nil {
|
|
f5.GetSysLog().Debug("unmarshal resObj err:%s", err.Error())
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
if resObj.TradeState != "SUCCESS" {
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
if resObj.OrderId == "" ||
|
|
resObj.AppId == "" ||
|
|
resObj.MchId != mt.Table.Config.GetWxMerchantId() {
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
gameid := q5.SafeToInt64(c.Param("gameid"))
|
|
if gameid == 0 {
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
cfg := mt.Table.Wxconfig.GetById(gameid)
|
|
if cfg == nil || cfg.GetAppid() != resObj.AppId {
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
notifyurl := cfg.GetNotifyurl()
|
|
|
|
orderModel := new(model.InAppOrder)
|
|
if err, found := orderModel.FindByOrderId(resObj.OrderId); err != nil || !found {
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
if orderModel.Status > 1 {
|
|
c.String(200, "")
|
|
return
|
|
}
|
|
|
|
rediskey := "ls:accountid:" + orderModel.AccountId
|
|
sessionstr, err := service.Redis.Get(constant.LOGIN_REDIS, rediskey)
|
|
if err != nil {
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
data := map[string]interface{}{}
|
|
if json.Unmarshal([]byte(sessionstr), &data) != nil {
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
openid := q5.SafeToString(data["openid"])
|
|
if openid != resObj.Payer.Openid {
|
|
c.JSON(501, failrspobj)
|
|
return
|
|
}
|
|
|
|
f5.GetSysLog().Debug("notify url:%d, %s", gameid, notifyurl)
|
|
fields := []string{"status", "sp_orderid"}
|
|
orderModel.Status = 1
|
|
orderModel.SpOrderId = resObj.TransId
|
|
if len(notifyurl) > 0 {
|
|
goodsidstr := q5.SafeToString(orderModel.ItemId)
|
|
totalamountstr := q5.SafeToString(resObj.Amount.Total)
|
|
|
|
nowtimestr := q5.SafeToString(f5.GetApp().GetRealSeconds())
|
|
originstr := "account_id=" + orderModel.AccountId
|
|
originstr += "&goodsid=" + goodsidstr
|
|
originstr += "&orderid=" + orderModel.OrderId
|
|
originstr += "&amount=" + totalamountstr
|
|
originstr += ":" + nowtimestr + constant.NOFITY_GAMESERVER_SALT
|
|
params := map[string]string{
|
|
"c": "Recharge",
|
|
"a": "purchaseNotify",
|
|
"account_id": orderModel.AccountId,
|
|
"orderid": orderModel.OrderId,
|
|
"timestamp": nowtimestr,
|
|
"goodsid": goodsidstr,
|
|
"amount": totalamountstr,
|
|
"sign": q5.Md5Str(originstr),
|
|
}
|
|
f5.GetHttpCliMgr().SendGoStyleRequest(
|
|
notifyurl,
|
|
params,
|
|
func(hcr f5.HttpCliResponse) {
|
|
if hcr.GetErr() != nil {
|
|
return
|
|
}
|
|
|
|
gamerspObj := struct {
|
|
ErrCode int64 `json:"errcode"`
|
|
ErrMsg string `json:"errmsg"`
|
|
}{}
|
|
|
|
f5.GetSysLog().Debug("get game rsp:%s", hcr.GetRawData())
|
|
if json.Unmarshal([]byte(hcr.GetRawData()), &gamerspObj) != nil {
|
|
return
|
|
}
|
|
|
|
if gamerspObj.ErrCode == 0 {
|
|
orderModel.Status = 2
|
|
}
|
|
})
|
|
} else {
|
|
count, _ := service.Wxpay.GetGoodsCount(gameid, int64(orderModel.ItemId))
|
|
orderModel.SpAmount = int32(count)
|
|
fields = append(fields, "sp_amount")
|
|
}
|
|
orderModel.UpdateFields(fields)
|
|
|
|
c.String(200, "")
|
|
}
|