accessToken
This commit is contained in:
parent
1691d745c7
commit
90bb74a5f1
@ -3,6 +3,7 @@
|
||||
"gameid": "1004",
|
||||
"appid": "wx1e89277247304160",
|
||||
"appkey": "CBP5uFcZP0S2PlcgkBTHxfZEXJft9wMK",
|
||||
"appsecret": "5834607a498c3225b1d0a608d827c0d6",
|
||||
"zoneid": "1",
|
||||
"offerid": "1450310463"
|
||||
},
|
||||
@ -10,7 +11,8 @@
|
||||
"gameid": "2004",
|
||||
"appid": "wx327f44630205dcd2",
|
||||
"appkey": "CrIjLw1wiExEnNBVqBQqWGMy0yToREC7",
|
||||
"appsecret": "148509437b331acd15580b279e8511af",
|
||||
"zoneid": "1",
|
||||
"offerid": "1450318181"
|
||||
}
|
||||
]
|
||||
]
|
@ -12,7 +12,7 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type InGameApi struct {
|
||||
type InGameApi struct {
|
||||
}
|
||||
|
||||
func (this *InGameApi) PreOrder(c *gin.Context) {
|
||||
@ -172,7 +172,7 @@ func (this *InGameApi) PayDone(c *gin.Context) {
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
c.JSON(200, rspObj)
|
||||
}
|
||||
|
||||
@ -187,15 +187,6 @@ func (this *InGameApi) OrderInfo(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
orderModel := new(model.InAppOrder)
|
||||
if err, found := orderModel.Find(reqJson.AccountId, reqJson.OrderId); err != nil {
|
||||
f5.RspErr(c, 500, "server internal error")
|
||||
return
|
||||
} else if !found {
|
||||
f5.RspErr(c, 1, "not found")
|
||||
return
|
||||
}
|
||||
|
||||
strs := strings.Split(reqJson.AccountId, "_")
|
||||
if len(strs) < 3 {
|
||||
f5.RspErr(c, 401, "params error1")
|
||||
@ -215,59 +206,70 @@ func (this *InGameApi) OrderInfo(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
status := orderModel.Status
|
||||
sessionkeytime := q5.SafeToInt64(data["update_time"])
|
||||
if service.Wxpay.CheckExpireCache(reqJson.AccountId, sessionkeytime) {
|
||||
f5.RspErr(c, 402, "session expired")
|
||||
return
|
||||
}
|
||||
|
||||
orderModel := new(model.InAppOrder)
|
||||
if err, found := orderModel.Find(reqJson.AccountId, reqJson.OrderId); err != nil {
|
||||
f5.RspErr(c, 500, "server internal error")
|
||||
return
|
||||
} else if !found {
|
||||
f5.RspErr(c, 1, "not found")
|
||||
return
|
||||
}
|
||||
|
||||
rspObj := struct {
|
||||
ErrorCode int32 `json:"errcode"`
|
||||
ErrMsg string `json:"errmsg"`
|
||||
OrderId string `json:"order_id"`
|
||||
GoodsId int32 `json:"goods_id"`
|
||||
Status int32 `json:"status"`
|
||||
}{}
|
||||
for status == 0 {
|
||||
}{
|
||||
OrderId: orderModel.OrderId,
|
||||
GoodsId: orderModel.ItemId,
|
||||
Status: orderModel.Status,
|
||||
}
|
||||
|
||||
c.JSON(200, rspObj)
|
||||
|
||||
if orderModel.Status == 0 {
|
||||
gameid := q5.SafeToInt64(strs[1])
|
||||
openid := strs[2]
|
||||
sessionkey := q5.SafeToString(data["session_key"])
|
||||
userip := this.getIP(c)
|
||||
balance, errcode, err := service.Wxpay.QueryBalance(openid, gameid, userip, sessionkey)
|
||||
if err != nil {
|
||||
f5.RspErr(c, 500, "system busy")
|
||||
return
|
||||
}
|
||||
|
||||
if errcode == constant.WX_ERRCODE_OK {
|
||||
count, err := service.Wxpay.GetGoodsCount(gameid, int64(orderModel.ItemId))
|
||||
if err != nil {
|
||||
f5.RspErr(c, 401, "goods error")
|
||||
return
|
||||
}
|
||||
|
||||
if balance < count {
|
||||
break
|
||||
}
|
||||
|
||||
errcode = service.Wxpay.QueryPay(openid, gameid, userip, sessionkey, int32(count), orderModel.OrderId)
|
||||
if errcode == constant.WX_ERRCODE_OK {
|
||||
status = 1
|
||||
orderModel.Status = 2
|
||||
orderModel.UpdateFields([]string{"status"})
|
||||
if balance >= count {
|
||||
errcode = service.Wxpay.QueryPay(openid, gameid, userip, sessionkey, int32(count), orderModel.OrderId)
|
||||
if errcode == constant.WX_ERRCODE_OK {
|
||||
orderModel.Status = 1
|
||||
orderModel.UpdateFields([]string{"status"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if errcode == constant.WX_ERRCODE_SESSIONERR || errcode == constant.WX_ERRCODE_SIGERR {
|
||||
rspObj.ErrorCode = 402
|
||||
rspObj.ErrMsg = "session overtime"
|
||||
service.Wxpay.AddExpireInfo(reqJson.AccountId, sessionkeytime)
|
||||
}
|
||||
|
||||
break
|
||||
} else if orderModel.Status == 1 {
|
||||
orderModel.Status = 2
|
||||
orderModel.UpdateFields([]string{"status"})
|
||||
}
|
||||
|
||||
rspObj.OrderId = orderModel.OrderId
|
||||
rspObj.GoodsId = orderModel.ItemId
|
||||
rspObj.Status = status
|
||||
c.JSON(200, rspObj)
|
||||
}
|
||||
|
||||
func (this *InGameApi) getIP(c *gin.Context) (ip string) {
|
||||
func (iga *InGameApi) getIP(c *gin.Context) (ip string) {
|
||||
ip = c.Request.Header.Get("X-Real-Ip")
|
||||
if ip == "" {
|
||||
ip = strings.Split(c.Request.Header.Get("X-Forwarded-For"), ",")[0]
|
||||
|
@ -116,6 +116,7 @@ type Wxconfig struct {
|
||||
gameid int64
|
||||
appid string
|
||||
appkey string
|
||||
appsecret string
|
||||
zoneid string
|
||||
offerid string
|
||||
|
||||
@ -543,12 +544,20 @@ func (this *Wxconfig) HasAppkey() bool {
|
||||
return (this._flags1_ & (uint64(1) << 3)) > 0
|
||||
}
|
||||
|
||||
func (this *Wxconfig) GetAppsecret() string {
|
||||
return this.appsecret
|
||||
}
|
||||
|
||||
func (this *Wxconfig) HasAppsecret() bool {
|
||||
return (this._flags1_ & (uint64(1) << 4)) > 0
|
||||
}
|
||||
|
||||
func (this *Wxconfig) GetZoneid() string {
|
||||
return this.zoneid
|
||||
}
|
||||
|
||||
func (this *Wxconfig) HasZoneid() bool {
|
||||
return (this._flags1_ & (uint64(1) << 4)) > 0
|
||||
return (this._flags1_ & (uint64(1) << 5)) > 0
|
||||
}
|
||||
|
||||
func (this *Wxconfig) GetOfferid() string {
|
||||
@ -556,7 +565,7 @@ func (this *Wxconfig) GetOfferid() string {
|
||||
}
|
||||
|
||||
func (this *Wxconfig) HasOfferid() bool {
|
||||
return (this._flags1_ & (uint64(1) << 5)) > 0
|
||||
return (this._flags1_ & (uint64(1) << 6)) > 0
|
||||
}
|
||||
|
||||
func (this *LoginRedis) GetHost() string {
|
||||
@ -690,8 +699,9 @@ func (this *Wxconfig) LoadFromKv(kv map[string]interface{}) {
|
||||
f5.ReadMetaTableField(&this.gameid, "gameid", &this._flags1_, 1, kv)
|
||||
f5.ReadMetaTableField(&this.appid, "appid", &this._flags1_, 2, kv)
|
||||
f5.ReadMetaTableField(&this.appkey, "appkey", &this._flags1_, 3, kv)
|
||||
f5.ReadMetaTableField(&this.zoneid, "zoneid", &this._flags1_, 4, kv)
|
||||
f5.ReadMetaTableField(&this.offerid, "offerid", &this._flags1_, 5, kv)
|
||||
f5.ReadMetaTableField(&this.appsecret, "appsecret", &this._flags1_, 4, kv)
|
||||
f5.ReadMetaTableField(&this.zoneid, "zoneid", &this._flags1_, 5, kv)
|
||||
f5.ReadMetaTableField(&this.offerid, "offerid", &this._flags1_, 6, kv)
|
||||
}
|
||||
|
||||
func (this *LoginRedis) LoadFromKv(kv map[string]interface{}) {
|
||||
|
@ -95,8 +95,9 @@ message Wxconfig
|
||||
optional int64 gameid = 1;
|
||||
optional string appid = 2;
|
||||
optional string appkey = 3;
|
||||
optional string zoneid = 4;
|
||||
optional string offerid = 5;
|
||||
optional string appsecret = 4;
|
||||
optional string zoneid = 5;
|
||||
optional string offerid = 6;
|
||||
}
|
||||
|
||||
message LoginRedis
|
||||
|
@ -11,10 +11,23 @@ import (
|
||||
"main/mt"
|
||||
"q5"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type tokenItem struct {
|
||||
token string
|
||||
expire int64
|
||||
}
|
||||
|
||||
type expireSession struct {
|
||||
SessionTime int64
|
||||
Time int64
|
||||
}
|
||||
type wxpay struct {
|
||||
gamesGoods q5.ConcurrentMap[int64, map[int64]int64]
|
||||
gamesGoods q5.ConcurrentMap[int64, map[int64]int64] //[gameid, [goodsid]count]
|
||||
accessTokens q5.ConcurrentMap[int64, tokenItem] //[gameid, tokenitem]
|
||||
|
||||
expireInfo q5.ConcurrentMap[string, *expireSession] //[accountid, expireSession]
|
||||
}
|
||||
|
||||
type WxQuery struct {
|
||||
@ -46,6 +59,9 @@ type WxPayRsp struct {
|
||||
|
||||
func (wp *wxpay) init() {
|
||||
wp.gamesGoods = q5.ConcurrentMap[int64, map[int64]int64]{}
|
||||
wp.accessTokens = q5.ConcurrentMap[int64, tokenItem]{}
|
||||
wp.expireInfo = q5.ConcurrentMap[string, *expireSession]{}
|
||||
|
||||
mt.Table.Wxconfig.Traverse(func(w *mt.Wxconfig) bool {
|
||||
filename := "../res/gamegoods/" + q5.SafeToString(w.GetGameid()) + ".json"
|
||||
str, err := f5.ReadJsonFile(filename)
|
||||
@ -61,14 +77,84 @@ func (wp *wxpay) init() {
|
||||
gamegoods[q5.SafeToInt64(data["id"])] = q5.SafeToInt64(data["count"])
|
||||
}
|
||||
wp.gamesGoods.Store(w.GetGameid(), gamegoods)
|
||||
wp.accessTokens.Store(w.GetGameid(), tokenItem{})
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
wp.gamesGoods.Range(func(gameid int64, value map[int64]int64) bool {
|
||||
wp.freshAccessToken(gameid)
|
||||
return true
|
||||
})
|
||||
|
||||
go wp.checkExpireInfo()
|
||||
}
|
||||
|
||||
func (wp *wxpay) unInit() {
|
||||
}
|
||||
|
||||
func (wp *wxpay) freshAccessToken(gameid int64) (token string) {
|
||||
cfg := mt.Table.Wxconfig.GetById(gameid)
|
||||
params := map[string]string{
|
||||
"grant_type": "client_credential",
|
||||
"appid": cfg.GetAppid(),
|
||||
"secret": cfg.GetAppsecret(),
|
||||
}
|
||||
urls := mt.Table.Config.GetWxUrl()
|
||||
queryuri := "cgi-bin/token"
|
||||
for _, wxhost := range urls {
|
||||
url := "https://" + wxhost + queryuri
|
||||
sendok := false
|
||||
f5.GetHttpCliMgr().SendGoStyleRequest(
|
||||
url,
|
||||
params,
|
||||
func(hcr f5.HttpCliResponse) {
|
||||
if hcr.GetErr() != nil {
|
||||
return
|
||||
}
|
||||
|
||||
rspObj := struct {
|
||||
Token string `json:"access_token"`
|
||||
Expire int64 `json:"expire_in"`
|
||||
ErrCode int64 `json:"errcode"`
|
||||
ErrMsg string `json:"errmsg"`
|
||||
}{}
|
||||
|
||||
sendok = true
|
||||
f5.GetSysLog().Debug("wx get access token rsp:%s", hcr.GetRawData())
|
||||
if json.Unmarshal([]byte(hcr.GetRawData()), &rspObj) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if rspObj.ErrCode == 0 {
|
||||
tokenitem, _ := wp.accessTokens.Load(gameid)
|
||||
tokenitem.token = rspObj.Token
|
||||
tokenitem.expire = rspObj.Expire + f5.GetApp().GetRealSeconds()
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
if sendok {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return token
|
||||
}
|
||||
|
||||
func (wp *wxpay) getAccessToken(gameid int64) (token string) {
|
||||
cfg, exist := wp.accessTokens.Load(gameid)
|
||||
nowTime := f5.GetApp().GetRealSeconds()
|
||||
if exist {
|
||||
if cfg.expire > nowTime+60 {
|
||||
return cfg.token
|
||||
}
|
||||
|
||||
return wp.freshAccessToken(gameid)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (wp *wxpay) GetGoodsCount(gameid int64, goodsid int64) (count int64, err error) {
|
||||
goods, ok := wp.gamesGoods.Load(gameid)
|
||||
if !ok {
|
||||
@ -108,7 +194,7 @@ func (wp *wxpay) QueryBalance(openid string, gameid int64, userip string, sessio
|
||||
|
||||
queryuri := "/wxa/game/getbalance"
|
||||
query := WxQuery{
|
||||
AccessToken: "",
|
||||
AccessToken: wp.getAccessToken(gameid),
|
||||
Signature: wp.genSHA256Signature(poststr, sessionkey),
|
||||
SigMethod: "hmac_sha256",
|
||||
PaySig: wp.genSHA256Signature(queryuri+"&"+poststr, cfg.GetAppkey()),
|
||||
@ -121,7 +207,7 @@ func (wp *wxpay) QueryBalance(openid string, gameid int64, userip string, sessio
|
||||
sendRequest := false
|
||||
urls := mt.Table.Config.GetWxUrl()
|
||||
for _, wxhost := range urls {
|
||||
url := "https://" + wxhost + "/" + queryuri
|
||||
url := "https://" + wxhost + queryuri
|
||||
f5.GetHttpCliMgr().SendGoStylePost(
|
||||
url,
|
||||
params,
|
||||
@ -146,11 +232,7 @@ func (wp *wxpay) QueryBalance(openid string, gameid int64, userip string, sessio
|
||||
balance = rspJson.Balance
|
||||
case constant.WX_ERRCODE_BUSY:
|
||||
sendRequest = false
|
||||
case constant.WX_ERRCODE_SIGERR:
|
||||
fallthrough
|
||||
case constant.WX_ERRCODE_PAYSIGERR:
|
||||
fallthrough
|
||||
case constant.WX_ERRCODE_PARAMERR:
|
||||
default:
|
||||
f5.GetSysLog().Info("err msg:%s", rspJson.ErrMsg)
|
||||
}
|
||||
|
||||
@ -192,7 +274,7 @@ func (wp *wxpay) QueryPay(openid string, gameid int64, userip string, sessionkey
|
||||
|
||||
queryuri := "/wxa/game/pay"
|
||||
query := WxQuery{
|
||||
AccessToken: "",
|
||||
AccessToken: wp.getAccessToken(gameid),
|
||||
Signature: wp.genSHA256Signature(poststr, sessionkey),
|
||||
SigMethod: "hmac_sha256",
|
||||
PaySig: wp.genSHA256Signature(queryuri+"&"+poststr, cfg.GetAppkey()),
|
||||
@ -229,17 +311,7 @@ func (wp *wxpay) QueryPay(openid string, gameid int64, userip string, sessionkey
|
||||
case constant.WX_ERRCODE_OK:
|
||||
case constant.WX_ERRCODE_BUSY:
|
||||
sendRequest = false
|
||||
case constant.WX_ERRCODE_SIGERR:
|
||||
fallthrough
|
||||
case constant.WX_ERRCODE_PAYSIGERR:
|
||||
fallthrough
|
||||
case constant.WX_ERRCODE_SAMEBILLNO:
|
||||
fallthrough
|
||||
case constant.WX_ERRCODE_NOENOUGH:
|
||||
fallthrough
|
||||
case constant.WX_ERRCODE_SESSIONERR:
|
||||
fallthrough
|
||||
case constant.WX_ERRCODE_PARAMERR:
|
||||
default:
|
||||
f5.GetSysLog().Info("err msg:%s", rspJson.ErrMsg)
|
||||
}
|
||||
|
||||
@ -252,8 +324,49 @@ func (wp *wxpay) QueryPay(openid string, gameid int64, userip string, sessionkey
|
||||
return wxerrcode
|
||||
}
|
||||
|
||||
func (wp *wxpay) AddExpireInfo(accountid string, sessiontime int64) {
|
||||
info := expireSession{
|
||||
SessionTime: sessiontime,
|
||||
Time: f5.GetApp().GetRealSeconds(),
|
||||
}
|
||||
|
||||
wp.expireInfo.Store(accountid, &info)
|
||||
}
|
||||
|
||||
func (wp *wxpay) CheckExpireCache(accountid string, expire int64) bool {
|
||||
info, exist := wp.expireInfo.Load(accountid)
|
||||
if !exist {
|
||||
return false
|
||||
}
|
||||
|
||||
if (*info).SessionTime < expire {
|
||||
wp.expireInfo.Delete(accountid)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (wp *wxpay) genSHA256Signature(str string, key string) string {
|
||||
mac := hmac.New(sha256.New, []byte(key))
|
||||
_, _ = mac.Write([]byte(str))
|
||||
return strings.ToLower(hex.EncodeToString(mac.Sum(nil)))
|
||||
}
|
||||
|
||||
func (wp *wxpay) checkExpireInfo() {
|
||||
for {
|
||||
time.Sleep(time.Minute * 30)
|
||||
nowTime := f5.GetApp().GetRealSeconds()
|
||||
deletelist := map[string]int64{}
|
||||
wp.expireInfo.Range(func(accountid string, value *expireSession) bool {
|
||||
if value.Time+3600 < nowTime {
|
||||
deletelist[accountid] = value.Time
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
for accountid := range deletelist {
|
||||
wp.expireInfo.Delete(accountid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user