195 lines
4.2 KiB
Go
195 lines
4.2 KiB
Go
package wechat
|
|
|
|
import (
|
|
json "github.com/json-iterator/go"
|
|
"github.com/oylshe1314/framework/util"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
func Code2Session(code string) (*MsgCode2SessionAck, error) {
|
|
var reqUrl, err = url.Parse(apiUri)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
reqUrl = reqUrl.JoinPath(apiCode2Session)
|
|
|
|
var query = url.Values{}
|
|
query.Add("appid", appId)
|
|
query.Add("secret", appSecret)
|
|
query.Add("js_code", code)
|
|
query.Add("grant_type", "authorization_code")
|
|
|
|
reqUrl.RawQuery = query.Encode()
|
|
|
|
var ack = new(MsgCode2SessionAck)
|
|
err = util.HttpJsonGet(reqUrl.String(), ack)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ack, nil
|
|
}
|
|
|
|
func GetAccessToken() (*MsgGetAccessTokenAck, error) {
|
|
var reqUrl, err = url.Parse(apiUri)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
reqUrl = reqUrl.JoinPath(apiGetStableAccessToken)
|
|
|
|
var req = &MsgGetAccessTokenReq{
|
|
GrantType: "client_credential",
|
|
Appid: appId,
|
|
Secret: appSecret,
|
|
ForceRefresh: false,
|
|
}
|
|
var ack = new(MsgGetAccessTokenAck)
|
|
err = util.HttpJsonPost(reqUrl.String(), req, ack)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ack, nil
|
|
}
|
|
|
|
// 一个body算两遍签名?, 有病?
|
|
func signature(sessionKey string, body []byte) string {
|
|
var sb strings.Builder
|
|
sb.Write(body)
|
|
|
|
return util.HMACSHA256(sessionKey, sb.String())
|
|
}
|
|
|
|
func paySig(url string, body []byte) string {
|
|
var sb strings.Builder
|
|
sb.WriteString(url)
|
|
sb.WriteByte('&')
|
|
sb.Write(body)
|
|
|
|
return util.HMACSHA256(appKey, sb.String())
|
|
}
|
|
|
|
func virtualPaymentRequest(accessTtoken string, sessionKey string, req any) (string, []byte, error) {
|
|
var reqUrl, err = url.Parse(apiUri)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
reqUrl = reqUrl.JoinPath(apiGetBalance)
|
|
|
|
reqBody, err := json.Marshal(req)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
var query = url.Values{}
|
|
query.Add("access_token", accessTtoken)
|
|
query.Add("signature", signature(sessionKey, reqBody))
|
|
query.Add("sig_method", "hmac_sha256")
|
|
query.Add("pay_sig", paySig(apiGetBalance, reqBody))
|
|
|
|
reqUrl.RawQuery = query.Encode()
|
|
|
|
return reqUrl.String(), reqBody, nil
|
|
}
|
|
|
|
func GetBalance(accessTtoken, sessionKey, openId, zoneId string) (*MsgGetBalanceAck, error) {
|
|
reqUrl, reqBody, err := virtualPaymentRequest(accessTtoken, sessionKey, &MsgGetBalanceReq{
|
|
MsgVirtualPayReq: MsgVirtualPayReq{
|
|
OpenId: openId,
|
|
OfferId: offerId,
|
|
Ts: util.Unix(),
|
|
ZoneId: zoneId,
|
|
Env: apiEnv,
|
|
},
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var ack = new(MsgGetBalanceAck)
|
|
err = util.HttpJsonPost(reqUrl, reqBody, ack)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ack, nil
|
|
}
|
|
|
|
func Pay(accessTtoken, sessionKey, openId, zoneId string, amount uint32, orderId string) (*MsgPayAck, error) {
|
|
reqUrl, reqBody, err := virtualPaymentRequest(accessTtoken, sessionKey, &MsgPayReq{
|
|
MsgVirtualPayReq: MsgVirtualPayReq{
|
|
OpenId: openId,
|
|
OfferId: offerId,
|
|
Ts: util.Unix(),
|
|
ZoneId: zoneId,
|
|
Env: apiEnv,
|
|
},
|
|
Amount: amount,
|
|
BillNo: orderId,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var ack = new(MsgPayAck)
|
|
err = util.HttpJsonPost(reqUrl, reqBody, ack)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ack, nil
|
|
}
|
|
|
|
func Cancelay(accessTtoken, sessionKey, openId, zoneId string, amount uint32, orderId string) (*MsgCancelPayAck, error) {
|
|
reqUrl, reqBody, err := virtualPaymentRequest(accessTtoken, sessionKey, &MsgCancelPayReq{
|
|
MsgVirtualPayReq: MsgVirtualPayReq{
|
|
OpenId: openId,
|
|
OfferId: offerId,
|
|
Ts: util.Unix(),
|
|
ZoneId: zoneId,
|
|
Env: apiEnv,
|
|
},
|
|
Amount: amount,
|
|
PayBillNo: orderId,
|
|
BillNo: orderId,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var ack = new(MsgCancelPayAck)
|
|
err = util.HttpJsonPost(reqUrl, reqBody, ack)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ack, nil
|
|
}
|
|
|
|
func SyncAccessToken(accessToken string) (*MsgSyncAccessTokenAck, error) {
|
|
var sb strings.Builder
|
|
|
|
sb.WriteString("accessToken=")
|
|
sb.WriteString(accessToken)
|
|
sb.WriteString("&appletId=")
|
|
sb.WriteString(appId)
|
|
sb.WriteString("&key=")
|
|
sb.WriteString(syncSignKey)
|
|
|
|
var sign = util.MD5(sb.String())
|
|
|
|
sb.WriteString("&sign=")
|
|
sb.WriteString(sign)
|
|
|
|
var ack = new(MsgSyncAccessTokenAck)
|
|
var err = util.HttpJsonGet(syncUri+syncAccessToken+"?"+sb.String(), ack)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ack, nil
|
|
}
|