Skip to content

Commit

Permalink
V1.1.6 (#7)
Browse files Browse the repository at this point in the history
* v1.1.6
  • Loading branch information
iGoogle-ink authored Aug 2, 2024
1 parent b6e6bf2 commit ddb9689
Show file tree
Hide file tree
Showing 57 changed files with 300 additions and 2,264 deletions.
4 changes: 3 additions & 1 deletion common.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ const (
DebugOff = 0
DebugOn = 1

Version = "1.1.5"
HeaderRequestID = "Request-ID"

Version = "1.1.6"
)

const (
Expand Down
9 changes: 9 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
module github.com/go-pay/wechat-sdk

go 1.21

require (
github.com/go-pay/bm v0.0.4
github.com/go-pay/crypto v0.0.1
github.com/go-pay/util v0.0.2
github.com/go-pay/xhttp v0.0.2
github.com/go-pay/xlog v0.0.3
github.com/go-pay/xtime v0.0.2
)
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
github.com/go-pay/bm v0.0.4 h1:MUECRx1t0MkbQ7Yzk2qseKBOKoUi4N8WZ+alZBrZesg=
github.com/go-pay/bm v0.0.4/go.mod h1:S7ZAxWtyjm7PX54cna4N/RzJ1JAZG8EDukZ2fZaZ+qk=
github.com/go-pay/crypto v0.0.1 h1:B6InT8CLfSLc6nGRVx9VMJRBBazFMjr293+jl0lLXUY=
github.com/go-pay/crypto v0.0.1/go.mod h1:41oEIvHMKbNcYlWUlRWtsnC6+ASgh7u29z0gJXe5bes=
github.com/go-pay/util v0.0.2 h1:goJ4f6kNY5zzdtg1Cj8oWC+Cw7bfg/qq2rJangMAb9U=
github.com/go-pay/util v0.0.2/go.mod h1:qM8VbyF1n7YAPZBSJONSPMPsPedhUTktewUAdf1AjPg=
github.com/go-pay/xhttp v0.0.2 h1:O8rnd/d03WsboFtUthwFMg61ikHRfYHyD1m0JiUx60g=
github.com/go-pay/xhttp v0.0.2/go.mod h1:BnuvXpLKkXTFMOBc5MTb0hxdrstwunbzQPJUZOsNbt4=
github.com/go-pay/xlog v0.0.3 h1:avyMhCL/JgBHreoGx/am/kHxfs1udDOAeVqbmzP/Yes=
github.com/go-pay/xlog v0.0.3/go.mod h1:mH47xbobrdsSHWsmFtSF5agWbMHFP+tK0ZbVCk5OAEw=
github.com/go-pay/xtime v0.0.2 h1:7YR4/iuELsEHpJ6LUO0SVK80hQxDO9MLCfuVYIiTCRM=
github.com/go-pay/xtime v0.0.2/go.mod h1:W1yRbJaSt4CSBcdAtLBQ8xajiN/Pl5hquGczUcUE9xE=
14 changes: 6 additions & 8 deletions mini/access_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import (
"runtime"
"strconv"
"time"

"github.com/go-pay/wechat-sdk/pkg/xlog"
)

// 获取小程序全局唯一后台接口调用凭据(access_token)
Expand All @@ -25,7 +23,7 @@ func (s *SDK) getAccessToken() (err error) {

path := "/cgi-bin/token?grant_type=client_credential&appid=" + s.Appid + "&secret=" + s.Secret
at := &AccessToken{}
if err = s.DoRequestGet(s.ctx, path, at); err != nil {
if _, err = s.DoRequestGet(s.ctx, path, at); err != nil {
return
}
if at.Errcode != Success {
Expand All @@ -45,15 +43,15 @@ func (s *SDK) goAutoRefreshAccessToken() {
if r := recover(); r != nil {
buf := make([]byte, 64<<10)
buf = buf[:runtime.Stack(buf, false)]
xlog.Errorf("mini_goAutoRefreshAccessToken: panic recovered: %s\n%s", r, buf)
s.logger.Errorf("mini_goAutoRefreshAccessToken: panic recovered: %s\n%s", r, buf)
}
}()
for {
// every one hour, request new access token, default 10s
time.Sleep(s.RefreshInternal / 2)
err := s.getAccessToken()
if err != nil {
xlog.Errorf("get access token error, after 10s retry: %+v", err)
s.logger.Errorf("get access token error, after 10s retry: %+v", err)
continue
}
}
Expand All @@ -74,7 +72,7 @@ func (s *SDK) getStableAccessToken() (err error) {

path := "/cgi-bin/stable_token?grant_type=client_credential&appid=" + s.Appid + "&secret=" + s.Secret + "&force_refresh=false"
at := &AccessToken{}
if err = s.DoRequestGet(s.ctx, path, at); err != nil {
if _, err = s.DoRequestGet(s.ctx, path, at); err != nil {
return
}
if at.Errcode != Success {
Expand All @@ -94,15 +92,15 @@ func (s *SDK) goAutoRefreshStableAccessToken() {
if r := recover(); r != nil {
buf := make([]byte, 64<<10)
buf = buf[:runtime.Stack(buf, false)]
xlog.Errorf("mini_goAutoRefreshAccessToken: panic recovered: %s\n%s", r, buf)
s.logger.Errorf("mini_goAutoRefreshAccessToken: panic recovered: %s\n%s", r, buf)
}
}()
for {
// every one hour, request new access token, default 10s
time.Sleep(s.RefreshInternal / 2)
err := s.getStableAccessToken()
if err != nil {
xlog.Errorf("get access token error, after 10s retry: %+v", err)
s.logger.Errorf("get access token error, after 10s retry: %+v", err)
continue
}
}
Expand Down
19 changes: 9 additions & 10 deletions mini/customer_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import (
"context"
"fmt"

"github.com/go-pay/wechat-sdk/pkg/bmap"
"github.com/go-pay/wechat-sdk/pkg/util"
"github.com/go-pay/bm"
)

// CSMessageGetTempMedia 获取客服消息内的临时素材
Expand All @@ -26,9 +25,9 @@ func (s *SDK) CSMessageGetTempMedia(c context.Context, mediaId string) (media []
// msgType:消息类型,枚举值:mini.MsgTypeText、mini.MsgTypeImage、mini.MsgTypeLink、mini.MsgTypeMiniPage
// msgValue:对应 msgType 的value值,BodyMap key-value 格式传入
// 文档:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/kf-mgnt/kf-message/sendCustomMessage.html
func (s *SDK) CSMessageSend(c context.Context, toUser string, msgType MsgType, msgValue bmap.BodyMap) (err error) {
func (s *SDK) CSMessageSend(c context.Context, toUser string, msgType MsgType, msgValue bm.BodyMap) (err error) {
path := "/cgi-bin/message/custom/send?access_token=" + s.accessToken
body := make(bmap.BodyMap)
body := make(bm.BodyMap)
body.Set("touser", toUser)
switch msgType {
case MsgTypeText:
Expand All @@ -45,7 +44,7 @@ func (s *SDK) CSMessageSend(c context.Context, toUser string, msgType MsgType, m
Set("text", msgValue)
}
ec := &ErrorCode{}
if err = s.doRequestPost(c, path, body, ec); err != nil {
if _, err = s.doRequestPost(c, path, body, ec); err != nil {
return err
}
if ec.Errcode != Success {
Expand All @@ -61,7 +60,7 @@ func (s *SDK) CSMessageSend(c context.Context, toUser string, msgType MsgType, m
// 文档:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/kf-mgnt/kf-message/setTyping.html
func (s *SDK) CSMessageSetTyping(c context.Context, toUser string, typingStatus TypingStatus) (err error) {
path := "/cgi-bin/message/custom/typing?access_token=" + s.accessToken
body := make(bmap.BodyMap)
body := make(bm.BodyMap)
body.Set("touser", toUser)
switch typingStatus {
case TypingTyping:
Expand All @@ -70,7 +69,7 @@ func (s *SDK) CSMessageSetTyping(c context.Context, toUser string, typingStatus
body.Set("command", "CancelTyping")
}
ec := &ErrorCode{}
if err = s.doRequestPost(c, path, body, ec); err != nil {
if _, err = s.doRequestPost(c, path, body, ec); err != nil {
return err
}
if ec.Errcode != Success {
Expand All @@ -83,13 +82,13 @@ func (s *SDK) CSMessageSetTyping(c context.Context, toUser string, typingStatus
// 注意:errcode = 0 为成功
// 注意:目前仅支持图片,用于发送客服消息或被动回复用户消息。
// 文档:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/kf-mgnt/kf-message/uploadTempMedia.html
func (s *SDK) CSMessageUploadTempMedia(c context.Context, img *util.File) (media *UploadTempMedia, err error) {
func (s *SDK) CSMessageUploadTempMedia(c context.Context, img *bm.File) (media *UploadTempMedia, err error) {
path := "/cgi-bin/media/upload?access_token=" + s.accessToken
body := make(bmap.BodyMap)
body := make(bm.BodyMap)
body.Set("type", "image").
SetFormFile("media", img)
media = &UploadTempMedia{}
if err = s.doRequestPostFile(c, path, body, media); err != nil {
if _, err = s.doRequestPostFile(c, path, body, media); err != nil {
return nil, err
}
if media.Errcode != Success {
Expand Down
2 changes: 1 addition & 1 deletion mini/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
func (s *SDK) Code2Session(c context.Context, wxCode string) (session *Code2Session, err error) {
path := "/sns/jscode2session?appid=" + s.Appid + "&secret=" + s.Secret + "&js_code=" + wxCode + "&grant_type=authorization_code"
session = &Code2Session{}
if err = s.doRequestGet(c, path, session); err != nil {
if _, err = s.doRequestGet(c, path, session); err != nil {
return nil, err
}
if session.Errcode != Success {
Expand Down
58 changes: 39 additions & 19 deletions mini/mini.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package mini

import (
"context"
"encoding/json"
"fmt"
"net/http"
"time"

"github.com/go-pay/util"
"github.com/go-pay/util/js"
"github.com/go-pay/wechat-sdk"
"github.com/go-pay/wechat-sdk/pkg/util"
"github.com/go-pay/wechat-sdk/pkg/xhttp"
"github.com/go-pay/wechat-sdk/pkg/xlog"
"github.com/go-pay/xhttp"
"github.com/go-pay/xlog"
)

type SDK struct {
Expand All @@ -20,6 +21,8 @@ type SDK struct {
Host string
accessToken string
RefreshInternal time.Duration
hc *xhttp.Client
logger xlog.XLogger

callback func(appid, accessToken string, expireIn int, err error)
}
Expand All @@ -29,12 +32,16 @@ type SDK struct {
// Secret:appSecret
// autoManageToken:是否自动获取并自动维护刷新 AccessToken,默认使用稳定版接口且force_refresh=false
func New(appid, secret string, autoManageToken bool) (m *SDK, err error) {
logger := xlog.NewLogger()
logger.SetLevel(xlog.DebugLevel)
m = &SDK{
ctx: context.Background(),
DebugSwitch: wechat.DebugOff,
Appid: appid,
Secret: secret,
Host: HostDefault,
hc: xhttp.NewClient(),
logger: logger,
}
if autoManageToken {
if err = m.getStableAccessToken(); err != nil {
Expand All @@ -45,35 +52,48 @@ func New(appid, secret string, autoManageToken bool) (m *SDK, err error) {
return
}

func (s *SDK) DoRequestGet(c context.Context, path string, ptr any) (err error) {
// SetHttpClient 设置自定义的xhttp.Client
func (s *SDK) SetHttpClient(client *xhttp.Client) {
if client != nil {
s.hc = client
}
}

func (s *SDK) SetLogger(logger xlog.XLogger) {
if logger != nil {
s.logger = logger
}
}

func (s *SDK) DoRequestGet(c context.Context, path string, ptr any) (res *http.Response, err error) {
uri := s.Host + path
httpClient := xhttp.NewClient()
if s.DebugSwitch == wechat.DebugOn {
xlog.Debugf("Wechat_SDK_URI: %s", uri)
s.logger.Debugf("Wechat_SDK_URI: %s", uri)
}
httpClient.Header.Add(xhttp.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
res, bs, err := httpClient.Get(uri).EndBytes(c)
req := s.hc.Req()
req.Header.Add(wechat.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
res, bs, err := req.Get(uri).EndBytes(c)
if err != nil {
return fmt.Errorf("http.request(GET, %s), status_code:%d, err:%w", uri, res.StatusCode, err)
return nil, fmt.Errorf("http.request(GET, %s), err:%w", uri, err)
}
if s.DebugSwitch == wechat.DebugOn {
xlog.Debugf("Wechat_SDK_Response: [%d] -> %s", res.StatusCode, string(bs))
s.logger.Debugf("Wechat_SDK_Response: [%d] -> %s", res.StatusCode, string(bs))
}
if err = json.Unmarshal(bs, ptr); err != nil {
return fmt.Errorf("json.Unmarshal(%s, %+v):%w", string(bs), ptr, err)
if err = js.UnmarshalBytes(bs, ptr); err != nil {
return res, fmt.Errorf("js.UnmarshalBytes(%s, %+v):%w", string(bs), ptr, err)
}
return
}

func doRequestGet(c context.Context, uri string, ptr any) (err error) {
httpClient := xhttp.NewClient()
httpClient.Header.Add(xhttp.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
res, bs, err := httpClient.Get(uri).EndBytes(c)
req := xhttp.NewClient().Req()
req.Header.Add(wechat.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
_, bs, err := req.Get(uri).EndBytes(c)
if err != nil {
return fmt.Errorf("http.request(GET, %s), status_code:%d, err:%w", uri, res.StatusCode, err)
return fmt.Errorf("http.request(GET, %s), err:%w", uri, err)
}
if err = json.Unmarshal(bs, ptr); err != nil {
return fmt.Errorf("json.Unmarshal(%s, %+v):%w", string(bs), ptr, err)
if err = js.UnmarshalBytes(bs, ptr); err != nil {
return fmt.Errorf("js.UnmarshalBytes(%s, %+v):%w", string(bs), ptr, err)
}
return
}
11 changes: 6 additions & 5 deletions mini/mini_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"os"
"testing"

"github.com/go-pay/bm"
"github.com/go-pay/wechat-sdk"
"github.com/go-pay/wechat-sdk/pkg/bmap"
"github.com/go-pay/wechat-sdk/pkg/xlog"
"github.com/go-pay/xlog"
)

var (
Expand All @@ -20,6 +20,7 @@ var (
)

func TestMain(m *testing.M) {
xlog.SetLevel(xlog.DebugLevel)
// 初始化微信小程序 SDK
// Appid:Appid
// Secret:appSecret
Expand Down Expand Up @@ -62,10 +63,10 @@ func TestCode2Session(t *testing.T) {
}

func TestUniformMessageSend(t *testing.T) {
body := make(bmap.BodyMap)
bb := make(bmap.BodyMap)
body := make(bm.BodyMap)
bb := make(bm.BodyMap)
bb.Set("appid", "APPID").
Set("template_id", "TEMPLATE_ID").SetBodyMap("miniprogram", func(b bmap.BodyMap) {
Set("template_id", "TEMPLATE_ID").SetBodyMap("miniprogram", func(b bm.BodyMap) {
b.Set("appid", "xiaochengxuappid12345").Set("pagepath", "index?foo=bar")
})

Expand Down
2 changes: 1 addition & 1 deletion mini/model.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package mini

import "github.com/go-pay/wechat-sdk/pkg/xtime"
import "github.com/go-pay/xtime"

const (
Success = 0
Expand Down
25 changes: 8 additions & 17 deletions mini/open_data.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package mini

import (
"crypto/aes"
"crypto/cipher"
"crypto/sha1"
"encoding/base64"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"reflect"

xaes "github.com/go-pay/wechat-sdk/pkg/aes"
"github.com/go-pay/wechat-sdk/pkg/util"
"github.com/go-pay/crypto/aes"
"github.com/go-pay/util"
"github.com/go-pay/util/js"
)

// VerifyDecryptOpenData 数据签名校验
Expand All @@ -39,8 +37,6 @@ func (s *SDK) DecryptOpenData(encryptedData, iv, sessionKey string, ptr any) (er
}
var (
cipherText, aesKey, ivKey, plainText []byte
block cipher.Block
blockMode cipher.BlockMode
)
beanValue := reflect.ValueOf(ptr)
if beanValue.Kind() != reflect.Ptr {
Expand All @@ -55,17 +51,12 @@ func (s *SDK) DecryptOpenData(encryptedData, iv, sessionKey string, ptr any) (er
if len(cipherText)%len(aesKey) != 0 {
return errors.New("encryptedData error")
}
if block, err = aes.NewCipher(aesKey); err != nil {
return fmt.Errorf("aes.NewCipher(),error(%w)", err)
plainText, err = aes.CBCDecrypt(cipherText, aesKey, ivKey)
if err != nil {
return fmt.Errorf("aes.CBCDecrypt(),err(%w)", err)
}
blockMode = cipher.NewCBCDecrypter(block, ivKey)
plainText = make([]byte, len(cipherText))
blockMode.CryptBlocks(plainText, cipherText)
if len(plainText) > 0 {
plainText = xaes.PKCS7UnPadding(plainText)
}
if err = json.Unmarshal(plainText, ptr); err != nil {
return fmt.Errorf("json.Unmarshal(%s, %+v),error(%w)", string(plainText), ptr, err)
if err = js.UnmarshalBytes(plainText, ptr); err != nil {
return fmt.Errorf("js.UnmarshalBytes(%s, %+v),error(%w)", string(plainText), ptr, err)
}
return
}
Loading

0 comments on commit ddb9689

Please sign in to comment.