521 lines
13 KiB
Go
521 lines
13 KiB
Go
package ingame
|
|
|
|
import (
|
|
"encoding/json"
|
|
"f5"
|
|
"main/constant"
|
|
"main/model"
|
|
"main/service"
|
|
"q5"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type InGameApi struct {
|
|
}
|
|
|
|
func (iga *InGameApi) PreOrder(c *gin.Context) {
|
|
reqJson := struct {
|
|
AccountId string `json:"account_id" binding:"required"`
|
|
SessionId string `json:"session_id" binding:"required"`
|
|
GoodsId int32 `json:"goods_id" binding:"required"`
|
|
}{}
|
|
if err := c.ShouldBindJSON(&reqJson); err != nil {
|
|
f5.RspErr(c, 401, "params error")
|
|
return
|
|
}
|
|
|
|
rspObj := struct {
|
|
ErrorCode int32 `json:"errcode"`
|
|
ErrMsg string `json:"errmsg"`
|
|
OrderId string `json:"order_id"`
|
|
}{}
|
|
|
|
data, ret := iga.checkSessionData(c, reqJson.AccountId)
|
|
if !ret && f5.IsOnlineEnv() {
|
|
return
|
|
}
|
|
|
|
nowTime := int32(f5.GetApp().GetRealSeconds())
|
|
order := new(model.InAppOrder)
|
|
order.AccountId = reqJson.AccountId
|
|
order.OrderId = q5.ToString(f5.GetApp().NewLockNodeUuid())
|
|
order.ItemId = reqJson.GoodsId
|
|
order.GameId = q5.SafeToInt32(data["gameid"])
|
|
order.IP = iga.getIP(c)
|
|
|
|
order.CreateTime = nowTime
|
|
order.ModifyTime = nowTime
|
|
|
|
if err := order.Create(); err != nil {
|
|
f5.RspErr(c, 500, "server internal error")
|
|
return
|
|
}
|
|
|
|
rspObj.OrderId = order.OrderId
|
|
|
|
c.JSON(200, rspObj)
|
|
}
|
|
|
|
func (iga *InGameApi) ServerPreOrder(c *gin.Context) {
|
|
accountId := c.Query("account_id")
|
|
goodsid := c.Query("goods_id")
|
|
sessionid := c.Query("session_id")
|
|
sign := c.Query("sign")
|
|
if !strings.EqualFold(q5.Md5Str(accountId+goodsid+constant.GLOBAL_SALT+sessionid), strings.ToLower(sign)) {
|
|
f5.RspErr(c, 401, "sign err")
|
|
return
|
|
}
|
|
|
|
data, ret := iga.checkSessionData(c, accountId)
|
|
if !ret {
|
|
return
|
|
}
|
|
|
|
nowTime := int32(f5.GetApp().GetRealSeconds())
|
|
order := new(model.InAppOrder)
|
|
order.AccountId = accountId
|
|
order.OrderId = q5.ToString(f5.GetApp().NewLockNodeUuid())
|
|
order.ItemId = q5.SafeToInt32(goodsid)
|
|
order.GameId = q5.SafeToInt32(data["gameid"])
|
|
order.IP = c.Query("user_ip")
|
|
|
|
order.CreateTime = nowTime
|
|
order.ModifyTime = nowTime
|
|
|
|
if err := order.Create(); err != nil {
|
|
f5.RspErr(c, 500, "server internal error")
|
|
return
|
|
}
|
|
|
|
rspObj := struct {
|
|
ErrorCode int32 `json:"errcode"`
|
|
ErrMsg string `json:"errmsg"`
|
|
OrderId string `json:"order_id"`
|
|
}{
|
|
0,
|
|
"",
|
|
order.OrderId,
|
|
}
|
|
|
|
c.JSON(200, rspObj)
|
|
}
|
|
|
|
func (iga *InGameApi) PayDone(c *gin.Context) {
|
|
accountId := c.Query("account_id")
|
|
orderid := c.Query("order_id")
|
|
sessionid := c.Query("session_id")
|
|
sign := c.Query("sign")
|
|
if !strings.EqualFold(q5.Md5Str(accountId+orderid+constant.GLOBAL_SALT+sessionid), strings.ToLower(sign)) {
|
|
f5.RspErr(c, 401, "sign err")
|
|
return
|
|
}
|
|
|
|
orderModel := new(model.InAppOrder)
|
|
if err, found := orderModel.Find(accountId, orderid); err != nil {
|
|
f5.RspErr(c, 500, "server internal error")
|
|
return
|
|
} else if !found {
|
|
f5.RspErr(c, 1, "order not found")
|
|
return
|
|
}
|
|
|
|
data, ret := iga.checkSessionData(c, accountId)
|
|
if !ret {
|
|
return
|
|
}
|
|
|
|
sessionkey := q5.SafeToString(data["session_key"])
|
|
|
|
status := orderModel.Status
|
|
rspObj := struct {
|
|
ErrorCode int32 `json:"errcode"`
|
|
ErrMsg string `json:"errmsg"`
|
|
OrderId string `json:"order_id"`
|
|
Diamond int64 `json:"diamond"`
|
|
}{
|
|
OrderId: orderid,
|
|
}
|
|
if status < 2 {
|
|
gameid := q5.SafeToInt64(data["gameid"])
|
|
openid := q5.SafeToString(data["openid"])
|
|
userip := iga.getIP(c)
|
|
balance, errcode, err := int64(0), int32(0), error(nil)
|
|
if status == 0 {
|
|
balance, errcode, err = service.Wxpay.QueryBalance(openid, gameid, userip, sessionkey)
|
|
if err != nil {
|
|
f5.RspErr(c, 500, "system busy")
|
|
return
|
|
}
|
|
} else {
|
|
balance = int64(orderModel.SpAmount)
|
|
}
|
|
|
|
if errcode == constant.WX_ERRCODE_OK && balance > 0 {
|
|
errcode = service.Wxpay.QueryPay(openid, gameid, userip, sessionkey, int32(balance), orderModel.OrderId)
|
|
if errcode == constant.WX_ERRCODE_OK {
|
|
status = 1
|
|
orderModel.Status = 2
|
|
orderModel.UpdateFields([]string{"status"})
|
|
|
|
rspObj.Diamond = balance
|
|
}
|
|
}
|
|
|
|
if errcode == constant.WX_ERRCODE_SESSIONERR || errcode == constant.WX_ERRCODE_SIGERR {
|
|
rspObj.ErrorCode = 402
|
|
rspObj.ErrMsg = "session overtime"
|
|
}
|
|
}
|
|
|
|
c.JSON(200, rspObj)
|
|
}
|
|
|
|
func (iga *InGameApi) ServerPrePurchase(c *gin.Context) {
|
|
req := struct {
|
|
AccountId string `binding:"required" json:"account_id"`
|
|
SessionId string `binding:"required" json:"session_id"`
|
|
UserIp string `binding:"required" json:"user_ip"`
|
|
Sign string `binding:"required" json:"sign"`
|
|
SigData string `binding:"required" json:"sig_data"`
|
|
}{}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
f5.RspErr(c, 401, "post content error")
|
|
return
|
|
}
|
|
|
|
if !strings.EqualFold(q5.Md5Str(req.AccountId+constant.GLOBAL_SALT+req.SessionId), req.Sign) {
|
|
f5.RspErr(c, 401, "sign err")
|
|
return
|
|
}
|
|
|
|
sigdata := map[string]interface{}{}
|
|
if json.Unmarshal([]byte(req.SigData), &sigdata) != nil {
|
|
f5.RspErr(c, 401, "sigdata err")
|
|
return
|
|
}
|
|
|
|
goodsid := q5.SafeToInt32(sigdata["productId"])
|
|
if goodsid == 0 {
|
|
f5.RspErr(c, 401, "sigdata productid err")
|
|
return
|
|
}
|
|
|
|
data, ret := iga.checkSessionData(c, req.AccountId)
|
|
if !ret {
|
|
return
|
|
}
|
|
|
|
sessionkey := q5.SafeToString(data["session_key"])
|
|
|
|
gameid := q5.SafeToInt64(data["gameid"])
|
|
|
|
nowTime := int32(f5.GetApp().GetRealSeconds())
|
|
order := new(model.InAppOrder)
|
|
order.AccountId = req.AccountId
|
|
order.OrderId = "p" + q5.ToString(f5.GetApp().NewLockNodeUuid())
|
|
order.GameId = int32(gameid)
|
|
order.ItemId = goodsid
|
|
order.IP = req.UserIp
|
|
|
|
order.CreateTime = nowTime
|
|
order.ModifyTime = nowTime
|
|
|
|
sigdata["outTradeNo"] = order.OrderId
|
|
sigdatabyte, _ := json.Marshal(sigdata)
|
|
fullsigdata := string(sigdatabyte)
|
|
|
|
paysig, signature := service.Wxpay.GetPurchaseSig(gameid, fullsigdata, sessionkey)
|
|
if len(paysig) == 0 || len(signature) == 0 {
|
|
f5.RspErr(c, 403, "account error")
|
|
return
|
|
}
|
|
|
|
if err := order.Create(); err != nil {
|
|
f5.RspErr(c, 500, "server internal error")
|
|
return
|
|
}
|
|
|
|
rspObj := struct {
|
|
ErrorCode int32 `json:"errcode"`
|
|
ErrMsg string `json:"errmsg"`
|
|
OrderId string `json:"order_id"`
|
|
PaySig string `json:"pay_sig"`
|
|
Signature string `json:"signature"`
|
|
SigData string `json:"sig_data"`
|
|
}{
|
|
0,
|
|
"",
|
|
order.OrderId,
|
|
paysig,
|
|
signature,
|
|
fullsigdata,
|
|
}
|
|
|
|
c.JSON(200, rspObj)
|
|
}
|
|
|
|
func (iga *InGameApi) OrderInfo(c *gin.Context) {
|
|
reqJson := struct {
|
|
AccountId string `json:"account_id" binding:"required"`
|
|
SessionId string `json:"session_id" binding:"required"`
|
|
OrderId string `json:"order_id" binding:"required"`
|
|
}{}
|
|
if err := c.ShouldBindJSON(&reqJson); err != nil {
|
|
f5.RspErr(c, 401, "params error")
|
|
return
|
|
}
|
|
|
|
if !f5.IsOnlineEnv() {
|
|
rspObj := struct {
|
|
ErrorCode int32 `json:"errcode"`
|
|
ErrMsg string `json:"errmsg"`
|
|
OrderId string `json:"order_id"`
|
|
GoodsId int32 `json:"goods_id"`
|
|
Count int32 `json:"count"`
|
|
Others int32 `json:"others"`
|
|
Status int32 `json:"status"`
|
|
}{
|
|
OrderId: reqJson.OrderId,
|
|
Status: 1,
|
|
}
|
|
c.JSON(200, rspObj)
|
|
return
|
|
}
|
|
|
|
data, ret := iga.checkSessionData(c, reqJson.AccountId)
|
|
if !ret {
|
|
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"`
|
|
Count int32 `json:"count"`
|
|
Others int32 `json:"others"`
|
|
Status int32 `json:"status"`
|
|
}{
|
|
OrderId: orderModel.OrderId,
|
|
GoodsId: orderModel.ItemId,
|
|
Count: orderModel.SpAmount,
|
|
Others: orderModel.SpOthers,
|
|
Status: orderModel.Status,
|
|
}
|
|
|
|
c.JSON(200, rspObj)
|
|
|
|
if orderModel.Status == 0 {
|
|
gameid := q5.SafeToInt64(data["gameid"])
|
|
openid := q5.SafeToString(data["openid"])
|
|
userip := iga.getIP(c)
|
|
sessionkey := q5.SafeToString(data["session_key"])
|
|
balance, errcode, err := service.Wxpay.QueryBalance(openid, gameid, userip, sessionkey)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if errcode == constant.WX_ERRCODE_OK {
|
|
count, err := service.Wxpay.GetGoodsCount(gameid, int64(orderModel.ItemId))
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if balance >= count {
|
|
errcode = service.Wxpay.QueryPay(openid, gameid, userip, sessionkey, int32(balance), orderModel.OrderId)
|
|
if errcode == constant.WX_ERRCODE_OK {
|
|
orderModel.Status = 1
|
|
orderModel.SpAmount = int32(count)
|
|
orderModel.SpOthers = int32(balance - count)
|
|
orderModel.UpdateFields([]string{"status", "sp_amount", "sp_others"})
|
|
}
|
|
}
|
|
}
|
|
|
|
if errcode == constant.WX_ERRCODE_SESSIONERR || errcode == constant.WX_ERRCODE_SIGERR {
|
|
sessionkeytime := q5.SafeToInt64(data["update_time"])
|
|
service.Wxpay.AddExpireInfo(reqJson.AccountId, sessionkeytime)
|
|
}
|
|
} else if orderModel.Status == 1 {
|
|
orderModel.Status = 2
|
|
orderModel.UpdateFields([]string{"status"})
|
|
}
|
|
}
|
|
|
|
func (iga *InGameApi) OtherOrder(c *gin.Context) {
|
|
reqJson := struct {
|
|
AccountId string `json:"account_id" binding:"required"`
|
|
SessionId string `json:"session_id" binding:"required"`
|
|
}{}
|
|
if err := c.ShouldBindJSON(&reqJson); err != nil {
|
|
f5.RspErr(c, 401, "params error")
|
|
return
|
|
}
|
|
|
|
data, ret := iga.checkSessionData(c, reqJson.AccountId)
|
|
if !ret {
|
|
return
|
|
}
|
|
|
|
sessionkey := q5.SafeToString(data["session_key"])
|
|
sessionkeytime := q5.SafeToInt64(data["update_time"])
|
|
rspObj := struct {
|
|
ErrorCode int32 `json:"errcode"`
|
|
ErrMsg string `json:"errmsg"`
|
|
Count int64 `json:"count"`
|
|
}{}
|
|
|
|
gameid := q5.SafeToInt64(data["gameid"])
|
|
openid := q5.SafeToString(data["openid"])
|
|
userip := iga.getIP(c)
|
|
balance, errcode, err := service.Wxpay.QueryBalance(openid, gameid, userip, sessionkey)
|
|
if err != nil {
|
|
f5.RspErr(c, 500, "wx server busy")
|
|
return
|
|
}
|
|
|
|
if errcode == constant.WX_ERRCODE_OK && balance > 0 {
|
|
nowTime := int32(f5.GetApp().GetRealSeconds())
|
|
order := new(model.InAppOrder)
|
|
order.AccountId = reqJson.AccountId
|
|
order.OrderId = "o" + q5.ToString(f5.GetApp().NewLockNodeUuid())
|
|
|
|
errcode = service.Wxpay.QueryPay(openid, gameid, userip, sessionkey, int32(balance), order.OrderId)
|
|
if errcode == constant.WX_ERRCODE_OK {
|
|
order.GameId = int32(gameid)
|
|
order.Channel = q5.SafeToInt32(data["channel"])
|
|
order.IP = iga.getIP(c)
|
|
order.Status = 2
|
|
order.SpOthers = int32(balance)
|
|
order.CreateTime = nowTime
|
|
order.ModifyTime = nowTime
|
|
|
|
if err := order.Create(); err != nil {
|
|
f5.GetSysLog().Error("record other order error:%s, %s, %d", reqJson.AccountId, order.OrderId, balance)
|
|
}
|
|
rspObj.Count = balance
|
|
}
|
|
} else if errcode == constant.WX_ERRCODE_SESSIONERR || errcode == constant.WX_ERRCODE_SIGERR {
|
|
service.Wxpay.AddExpireInfo(reqJson.AccountId, sessionkeytime)
|
|
rspObj.ErrorCode = 402
|
|
rspObj.ErrMsg = "invalid session 2"
|
|
}
|
|
|
|
if errcode == constant.WX_ERRCODE_OK {
|
|
rspObj.Count += model.FindOtherCount(reqJson.AccountId)
|
|
}
|
|
|
|
c.JSON(200, rspObj)
|
|
}
|
|
|
|
func (iga *InGameApi) QueryPay(c *gin.Context) {
|
|
reqJson := struct {
|
|
AccountId string `json:"account_id" binding:"required"`
|
|
SessionId string `json:"session_id" binding:"required"`
|
|
OrderId string `json:"order_id" binding:"required"`
|
|
}{}
|
|
if err := c.ShouldBindJSON(&reqJson); err != nil {
|
|
f5.RspErr(c, 401, "params error")
|
|
return
|
|
}
|
|
|
|
_, ret := iga.checkSessionData(c, reqJson.AccountId)
|
|
if !ret {
|
|
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"`
|
|
Count int32 `json:"count"`
|
|
Others int32 `json:"others"`
|
|
Status int32 `json:"status"`
|
|
}{
|
|
OrderId: orderModel.OrderId,
|
|
GoodsId: orderModel.ItemId,
|
|
Count: orderModel.SpAmount,
|
|
Others: orderModel.SpOthers,
|
|
Status: orderModel.Status,
|
|
}
|
|
|
|
c.JSON(200, rspObj)
|
|
|
|
if orderModel.Status == 1 {
|
|
orderModel.Status = 2
|
|
orderModel.UpdateFields([]string{"status"})
|
|
}
|
|
}
|
|
|
|
func (iga *InGameApi) checkSessionData(c *gin.Context, accountId string) (data map[string]interface{}, ret bool) {
|
|
strs := strings.Split(accountId, "_")
|
|
if len(strs) < 3 {
|
|
f5.RspErr(c, 401, "params error1")
|
|
return
|
|
}
|
|
|
|
rediskey := "ls:accountid:" + accountId
|
|
str, err := service.Redis.Get(constant.LOGIN_REDIS, rediskey)
|
|
if err != nil {
|
|
f5.RspErr(c, 402, "invalid session")
|
|
return
|
|
}
|
|
|
|
data = map[string]interface{}{}
|
|
if json.Unmarshal([]byte(str), &data) != nil {
|
|
f5.RspErr(c, 402, "invalid session 1")
|
|
return
|
|
}
|
|
|
|
sessionkey := q5.SafeToString(data["session_key"])
|
|
if len(sessionkey) == 0 {
|
|
f5.GetSysLog().Debug("empty sessionkey:%s", accountId)
|
|
f5.RspErr(c, 402, "invalid session 2")
|
|
return
|
|
}
|
|
|
|
sessionkeytime := q5.SafeToInt64(data["update_time"])
|
|
if service.Wxpay.CheckExpireCache(accountId, sessionkeytime) {
|
|
f5.RspErr(c, 402, "session expired")
|
|
return
|
|
}
|
|
|
|
data["channel"] = strs[0]
|
|
data["gameid"] = strs[1]
|
|
return data, true
|
|
}
|
|
|
|
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]
|
|
}
|
|
if ip == "" {
|
|
ip = c.Request.RemoteAddr
|
|
}
|
|
|
|
return ip
|
|
}
|