aozhiwei 32d3fdbfc8 1
2020-03-18 20:02:03 +08:00

187 lines
4.9 KiB
Go
Executable File

package platApi
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"game/base/util"
"io/ioutil"
"net/http"
"net/url"
"time"
"game/base/log"
)
type QQTokenRes struct {
AccessToken string `json:"access_token"`
ExpiresIn uint32 `json:"expires_in"`
ErrCode uint32 `json:"errcode"`
ErrMsg string `json:"errmsg"`
}
func QQAccessToken(appID string, secret string) (key string, expire uint32, err error) {
url1 := "https://api.q.qq.com/api/getToken?grant_type=client_credential&appid=" + appID + "&secret=" + secret
resp, err := http.Get(url1)
if err != nil {
return
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}
resp.Body.Close()
ret := &QQTokenRes{}
err = json.Unmarshal(body, &ret)
if err != nil || ret.ErrCode != 0 {
return
}
key = ret.AccessToken
expire = ret.ExpiresIn
return
}
type QQPrePayRes struct {
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
PrepayId string `json:"prepayId"`
}
type QQPrePayReq struct {
OpenId string `json:"openid"`
AppId string `json:"appid"`
Ts int `json:"ts"`
ZoneId string `json:"zone_id"`
Pf string `json:"pf"`
Amt int `json:"amt"`
GoodId string `json:"goodid"`
GoodNum string `json:"good_num"`
AppRemark string `json:"app_remark"`
BillNo string `json:"bill_no"`
Sig string `json:"sig"`
}
func QQPrePay(openid string, appid string, zone string, amt string, goodId string, goodNum uint32, token string, sessionKey string) (*QQPrePayRes, error) {
u := "https://api.q.qq.com/api/json/openApiPay/GamePrePay?access_token=" + token
value := url.Values{}
value.Add("openid", openid)
value.Add("appid", appid)
value.Add("ts", util.Int64ToString(time.Now().Unix()))
value.Add("zone_id", zone)
value.Add("pf", "qq_m_qq-2001-android-2011")
value.Add("amt", amt)
value.Add("goodid", "31b654ce0caeda34ad583d069551481c")
//value.Add("goodid", goodId)
value.Add("good_nun", util.Uint32ToString(goodNum))
value.Add("app_remark", zone + "-" + goodId + "-" + openid)
billNo, _ := util.NextId()
value.Add("bill_no", util.Int64ToString(billNo))
param := "POST&" + url.PathEscape("/api/json/openApiPay/GamePrePay") + "&" + value.Encode() + "&session_key=" + sessionKey
h := hmac.New(sha256.New, []byte(sessionKey))
h.Write([]byte(param))
sign := hex.EncodeToString(h.Sum(nil))
value.Set("sig", sign)
req := &QQPrePayReq{};
raw_data, _ := json.Marshal(util.UrlValuesToMap(value))
err := json.Unmarshal(raw_data, &req)
data, _ := json.Marshal(req)
resp, err := http.Post(u, "application/json;charset=UTF-8", bytes.NewReader(data))
if err != nil {
log.Error("Post error ", err)
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Error("Read Body Error ", err)
return nil, err
}
res := &QQPrePayRes{}
if e := json.Unmarshal(body, res); e != nil {
log.Error("Recv Result Error ", e)
return nil, e
}
if res.Errcode != 0 {
log.Error(res.Errmsg)
}
return res, nil
}
type QQSessionRet struct {
Openid string `json:"openid"`
SessionKey string `json:"session_key"`
UinionId string `json:"uinionid"`
Errcode int `json:"errcode"`
ErrMsg string `json:"errMsg"`
}
func QQCode2Session(code string, appID string, secret string) *QQSessionRet {
client := http.Client{}
param := url.Values{}
param.Set("appid", appID)
param.Set("secret", secret)
param.Set("js_code", code)
param.Set("grant_type", "authorization_code")
urlStr := "https://api.q.qq.com/sns/jscode2session?" + param.Encode()
res, err := client.Get(urlStr)
if err != nil {
log.Error("Get Access Token Error ", urlStr, err)
return nil
}
body, bodyErr := ioutil.ReadAll(res.Body)
if bodyErr != nil {
log.Error("Get Access Token Error ", bodyErr)
return nil
}
res.Body.Close()
ret := &QQSessionRet{}
e := json.Unmarshal(body, ret)
if e != nil {
log.Error("Get Access Token Error ", e)
return nil
}
if ret.Errcode != 0 {
log.Error("Get Access Token Error ", ret.Errcode, ret.ErrMsg)
return nil
}
return ret
}
type QQPayCallBack struct {
Openid string `json:"openid"`
BillNo string `json:"bill_no"`
Amt int `json:"amt"`
Ts int64 `json:"ts"`
AppRemark string `json:"app_remark"`
Sig string `json:"sig"`
}
func QQCallBackVerify(req *QQPayCallBack, urlPath string, secret string) bool {
var str string
if req.AppRemark == "" {
str = fmt.Sprintf("POST&%s&amt=%d&bill_no=%s&openid=%s&ts=%d&AppSecret=%s",
url.QueryEscape(urlPath), req.Amt, req.BillNo, req.Openid, req.Ts, secret)
} else {
str = fmt.Sprintf("POST&%s&amt=%d&app_remark=%s&bill_no=%s&openid=%s&ts=%d&AppSecret=%s",
url.QueryEscape(urlPath), req.Amt, req.AppRemark, req.BillNo, req.Openid, req.Ts, secret)
}
h := hmac.New(sha256.New, []byte(secret))
h.Write([]byte(str))
sign := hex.EncodeToString(h.Sum(nil))
if sign != req.Sig {
return false
}
return true
}
type QQPayCallBackRet struct {
Code int `json:"code"`
Msg string `json:"msg"`
}