2025-06-04 18:17:39 +08:00

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
}