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 }