187 lines
4.9 KiB
Go
Executable File
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"`
|
|
}
|