diff --git a/doc/mini.md b/doc/mini.md
index 1b2e1c8..dcfd919 100644
--- a/doc/mini.md
+++ b/doc/mini.md
@@ -21,7 +21,7 @@ import (
// 初始化微信小程序 SDK
// Appid:Appid
// Secret:appSecret
-// autoManageToken:是否自动获取并自动维护刷新 AccessToken
+// autoManageToken:是否自动获取并自动维护刷新 AccessToken,默认使用稳定版接口且force_refresh=false
miniSDK, err := mini.New(Appid, Secret, true)
if err != nil {
xlog.Error(err)
@@ -126,8 +126,13 @@ if err != nil {
* 开放数据解密:`sdk.DecryptOpenData()`
* 客服消息
* 获取客服消息内的临时素材:`sdk.CSMessageGetTempMedia()`
- * 发送客服消息给用户:`sdk.CSMessageSend()`
+ * 发送客服消息:`sdk.CSMessageSend()`
* 下发客服当前输入状态给用户:`sdk.CSMessageSetTyping()`
- * 把媒体文件上传到微信服务器(目前仅支持图片):`sdk.CSMessageUploadTempMedia()`
+ * 新增图片素材:`sdk.CSMessageUploadTempMedia()`
* 统一服务消息
* 发送统一服务消息:`sdk.UniformMessageSend()` 未完成
+
+### 微信小程序 公共API
+
+* `mini.GetAccessToken()` => 获取接口调用凭据
+* `mini.GetStableAccessToken()` => 获取稳定版接口调用凭据
\ No newline at end of file
diff --git a/mini/access_token.go b/mini/access_token.go
index 6c135f2..52ddf30 100644
--- a/mini/access_token.go
+++ b/mini/access_token.go
@@ -1,15 +1,17 @@
package mini
import (
+ "context"
"fmt"
"runtime"
+ "strconv"
"time"
"github.com/go-pay/wechat-sdk/pkg/xlog"
)
// 获取小程序全局唯一后台接口调用凭据(access_token)
-// 微信小程序文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html
+// 微信小程序文档:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html
func (s *SDK) getAccessToken() (err error) {
defer func() {
if err != nil {
@@ -57,6 +59,55 @@ func (s *SDK) goAutoRefreshAccessToken() {
}
}
+// 获取稳定版接口调用凭据
+// 微信小程序文档:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getStableAccessToken.html
+func (s *SDK) getStableAccessToken() (err error) {
+ defer func() {
+ if err != nil {
+ // reset default refresh internal
+ s.RefreshInternal = time.Second * 20
+ if s.callback != nil {
+ go s.callback("", "", 0, err)
+ }
+ }
+ }()
+
+ 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 {
+ return
+ }
+ if at.Errcode != Success {
+ err = fmt.Errorf("errcode(%d), errmsg(%s)", at.Errcode, at.Errmsg)
+ return
+ }
+ s.accessToken = at.AccessToken
+ s.RefreshInternal = time.Second * time.Duration(at.ExpiresIn)
+ if s.callback != nil {
+ go s.callback(s.Appid, at.AccessToken, at.ExpiresIn, nil)
+ }
+ return nil
+}
+
+func (s *SDK) goAutoRefreshStableAccessToken() {
+ defer func() {
+ 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)
+ }
+ }()
+ 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)
+ continue
+ }
+ }
+}
+
// SetMiniAccessTokenCallback set mini access token callback listener
func (s *SDK) SetMiniAccessTokenCallback(fn func(appid, accessToken string, expireIn int, err error)) {
s.callback = fn
@@ -71,3 +122,33 @@ func (s *SDK) GetMiniAccessToken() (at string) {
func (s *SDK) SetMiniAccessToken(accessToken string) {
s.accessToken = accessToken
}
+
+// =====================================================================================================================
+
+// 获取接口调用凭据
+// 微信小程序文档:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html
+func GetAccessToken(c context.Context, appid, secret string) (at *AccessToken, err error) {
+ uri := HostDefault + "/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret
+ at = &AccessToken{}
+ if err = doRequestGet(c, uri, at); err != nil {
+ return nil, err
+ }
+ if at.Errcode != Success {
+ return nil, fmt.Errorf("errcode(%d), errmsg(%s)", at.Errcode, at.Errmsg)
+ }
+ return at, nil
+}
+
+// 获取稳定版接口调用凭据
+// 微信小程序文档:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getStableAccessToken.html
+func GetStableAccessToken(c context.Context, appid, secret string, forceRefresh bool) (at *AccessToken, err error) {
+ uri := HostDefault + "/cgi-bin/stable_token?grant_type=client_credential&appid=" + appid + "&secret=" + secret + "&force_refresh=" + strconv.FormatBool(forceRefresh)
+ at = &AccessToken{}
+ if err = doRequestGet(c, uri, at); err != nil {
+ return nil, err
+ }
+ if at.Errcode != Success {
+ return nil, fmt.Errorf("errcode(%d), errmsg(%s)", at.Errcode, at.Errmsg)
+ }
+ return at, nil
+}
diff --git a/mini/customer_service.go b/mini/customer_service.go
index fc6bee7..a130ef7 100644
--- a/mini/customer_service.go
+++ b/mini/customer_service.go
@@ -10,7 +10,7 @@ import (
// CSMessageGetTempMedia 获取客服消息内的临时素材
// mediaId:媒体文件 ID
-// 文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-message/customerServiceMessage.getTempMedia.html
+// 文档:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/kf-mgnt/kf-message/getTempMedia.html
func (s *SDK) CSMessageGetTempMedia(c context.Context, mediaId string) (media []byte, err error) {
path := "/cgi-bin/media/get?access_token=" + s.accessToken + "&media_id=" + mediaId
media, err = s.doRequestGetByte(c, path)
@@ -20,12 +20,12 @@ func (s *SDK) CSMessageGetTempMedia(c context.Context, mediaId string) (media []
return
}
-// CSMessageSend 发送客服消息给用户
+// CSMessageSend 发送客服消息
// 注意:errcode = 0 为成功
// toUser:小程序用户的 OpenID
// msgType:消息类型,枚举值:mini.MsgTypeText、mini.MsgTypeImage、mini.MsgTypeLink、mini.MsgTypeMiniPage
// msgValue:对应 msgType 的value值,BodyMap key-value 格式传入
-// 文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-message/customerServiceMessage.send.html
+// 文档: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) {
path := "/cgi-bin/message/custom/send?access_token=" + s.accessToken
body := make(bmap.BodyMap)
@@ -58,7 +58,7 @@ func (s *SDK) CSMessageSend(c context.Context, toUser string, msgType MsgType, m
// 注意:errcode = 0 为成功
// toUser:小程序用户的 OpenID
// typingStatus:枚举值:mini.TypingTyping、mini.TypingCancel
-// 文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-message/customerServiceMessage.setTyping.html
+// 文档: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)
@@ -79,10 +79,10 @@ func (s *SDK) CSMessageSetTyping(c context.Context, toUser string, typingStatus
return nil
}
-// CSMessageUploadTempMedia 把媒体文件上传到微信服务器
+// CSMessageUploadTempMedia 新增图片素材
// 注意:errcode = 0 为成功
// 注意:目前仅支持图片,用于发送客服消息或被动回复用户消息。
-// 文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-message/customerServiceMessage.uploadTempMedia.html
+// 文档: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) {
path := "/cgi-bin/media/upload?access_token=" + s.accessToken
body := make(bmap.BodyMap)
diff --git a/mini/login.go b/mini/login.go
index f98ee14..d133e48 100644
--- a/mini/login.go
+++ b/mini/login.go
@@ -8,7 +8,7 @@ import (
// Code2Session 登录凭证校验
// 注意:errcode = 0 为成功
// wxCode:小程序调用 wx.login 获取的code
-// 文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
+// 文档:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html
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{}
diff --git a/mini/mini.go b/mini/mini.go
index 463c50e..957df31 100644
--- a/mini/mini.go
+++ b/mini/mini.go
@@ -27,7 +27,7 @@ type SDK struct {
// New 初始化微信小程序 SDK
// Appid:Appid
// Secret:appSecret
-// autoManageToken:是否自动获取并自动维护刷新 AccessToken
+// autoManageToken:是否自动获取并自动维护刷新 AccessToken,默认使用稳定版接口且force_refresh=false
func New(appid, secret string, autoManageToken bool) (m *SDK, err error) {
m = &SDK{
ctx: context.Background(),
@@ -37,15 +37,15 @@ func New(appid, secret string, autoManageToken bool) (m *SDK, err error) {
Host: HostDefault,
}
if autoManageToken {
- if err = m.getAccessToken(); err != nil {
+ if err = m.getStableAccessToken(); err != nil {
return nil, err
}
- go m.goAutoRefreshAccessToken()
+ go m.goAutoRefreshStableAccessToken()
}
return
}
-func (s *SDK) DoRequestGet(c context.Context, path string, ptr interface{}) (err error) {
+func (s *SDK) DoRequestGet(c context.Context, path string, ptr any) (err error) {
uri := s.Host + path
httpClient := xhttp.NewClient()
if s.DebugSwitch == wechat.DebugOn {
@@ -54,7 +54,7 @@ func (s *SDK) DoRequestGet(c context.Context, path string, ptr interface{}) (err
httpClient.Header.Add(xhttp.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
res, bs, err := httpClient.Get(uri).EndBytes(c)
if err != nil {
- return fmt.Errorf("http.request(GET, %s):%w", uri, err)
+ return fmt.Errorf("http.request(GET, %s), status_code:%d, err:%w", uri, res.StatusCode, err)
}
if s.DebugSwitch == wechat.DebugOn {
xlog.Debugf("Wechat_SDK_Response: [%d] -> %s", res.StatusCode, string(bs))
@@ -64,3 +64,16 @@ func (s *SDK) DoRequestGet(c context.Context, path string, ptr interface{}) (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)
+ if err != nil {
+ return fmt.Errorf("http.request(GET, %s), status_code:%d, err:%w", uri, res.StatusCode, err)
+ }
+ if err = json.Unmarshal(bs, ptr); err != nil {
+ return fmt.Errorf("json.Unmarshal(%s, %+v):%w", string(bs), ptr, err)
+ }
+ return
+}
diff --git a/mini/mini_test.go b/mini/mini_test.go
index 4ed0bc5..3a09284 100644
--- a/mini/mini_test.go
+++ b/mini/mini_test.go
@@ -23,7 +23,7 @@ func TestMain(m *testing.M) {
// 初始化微信小程序 SDK
// Appid:Appid
// Secret:appSecret
- // autoManageToken:是否自动获取并自动维护刷新 AccessToken
+ // autoManageToken:是否自动获取并自动维护刷新 AccessToken,默认使用稳定版接口且force_refresh=false
miniSDK, err = New(Appid, Secret, true)
if err != nil {
xlog.Error(err)
diff --git a/mini/open_data.go b/mini/open_data.go
index 328eecd..e26f8d3 100644
--- a/mini/open_data.go
+++ b/mini/open_data.go
@@ -33,7 +33,7 @@ func (s *SDK) VerifyDecryptOpenData(rowData, signature, sessionKey string) (ok b
// sessionKey:会话密钥,通过 sdk.Code2Session() 方法获取到
// ptr:需要解析到的结构体指针,例:mini.UserPhone、mini.UserInfo
// 文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
-func (s *SDK) DecryptOpenData(encryptedData, iv, sessionKey string, ptr interface{}) (err error) {
+func (s *SDK) DecryptOpenData(encryptedData, iv, sessionKey string, ptr any) (err error) {
if encryptedData == util.NULL || iv == util.NULL || sessionKey == util.NULL {
return errors.New("input params can not null")
}
diff --git a/mini/request.go b/mini/request.go
index 9f0f7f1..9198e5d 100644
--- a/mini/request.go
+++ b/mini/request.go
@@ -13,7 +13,7 @@ import (
"github.com/go-pay/wechat-sdk/pkg/xlog"
)
-func (s *SDK) doRequestGet(c context.Context, path string, ptr interface{}) (err error) {
+func (s *SDK) doRequestGet(c context.Context, path string, ptr any) (err error) {
uri := s.Host + path
httpClient := xhttp.NewClient()
if s.DebugSwitch == wechat.DebugOn {
@@ -22,7 +22,7 @@ func (s *SDK) doRequestGet(c context.Context, path string, ptr interface{}) (err
httpClient.Header.Add(xhttp.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
res, bs, err := httpClient.Get(uri).EndBytes(c)
if err != nil {
- return fmt.Errorf("http.request(GET, %s):%w", uri, err)
+ return fmt.Errorf("http.request(GET, %s), status_code:%d, err:%w", uri, res.StatusCode, err)
}
if s.DebugSwitch == wechat.DebugOn {
xlog.Debugf("Wechat_Mini_SDK_Response: [%d] -> %s", res.StatusCode, string(bs))
@@ -42,7 +42,7 @@ func (s *SDK) doRequestGetByte(c context.Context, path string) (bs []byte, err e
httpClient.Header.Add(xhttp.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
res, bs, err := httpClient.Get(uri).EndBytes(c)
if err != nil {
- return nil, fmt.Errorf("http.request(GET, %s):%w", uri, err)
+ return nil, fmt.Errorf("http.request(GET, %s), status_code:%d, err:%w", uri, res.StatusCode, err)
}
if s.DebugSwitch == wechat.DebugOn {
xlog.Debugf("Wechat_Mini_SDK_Response: [%d] -> %s", res.StatusCode, string(bs))
@@ -55,7 +55,7 @@ func (s *SDK) doRequestGetByte(c context.Context, path string) (bs []byte, err e
return
}
-func (s *SDK) doRequestPost(c context.Context, path string, body bmap.BodyMap, ptr interface{}) (err error) {
+func (s *SDK) doRequestPost(c context.Context, path string, body bmap.BodyMap, ptr any) (err error) {
uri := s.Host + path
httpClient := xhttp.NewClient()
if s.DebugSwitch == wechat.DebugOn {
@@ -65,7 +65,7 @@ func (s *SDK) doRequestPost(c context.Context, path string, body bmap.BodyMap, p
httpClient.Header.Add(xhttp.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
res, bs, err := httpClient.Post(uri).SendBodyMap(body).EndBytes(c)
if err != nil {
- return fmt.Errorf("http.request(POST, %s):%w", uri, err)
+ return fmt.Errorf("http.request(POST, %s), status_code:%d, err:%w", uri, res.StatusCode, err)
}
if s.DebugSwitch == wechat.DebugOn {
xlog.Debugf("Wechat_Mini_SDK_Response: [%d] -> %s", res.StatusCode, string(bs))
@@ -76,7 +76,7 @@ func (s *SDK) doRequestPost(c context.Context, path string, body bmap.BodyMap, p
return
}
-func (s *SDK) doRequestPostFile(ctx context.Context, path string, body bmap.BodyMap, ptr interface{}) (err error) {
+func (s *SDK) doRequestPostFile(ctx context.Context, path string, body bmap.BodyMap, ptr any) (err error) {
uri := s.Host + path
httpClient := xhttp.NewClient()
if s.DebugSwitch == wechat.DebugOn {
@@ -85,7 +85,7 @@ func (s *SDK) doRequestPostFile(ctx context.Context, path string, body bmap.Body
httpClient.Header.Add(xhttp.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
res, bs, err := httpClient.Type(xhttp.TypeMultipartFormData).Post(uri).SendMultipartBodyMap(body).EndBytes(ctx)
if err != nil {
- return fmt.Errorf("http.request(POST, %s):%w", uri, err)
+ return fmt.Errorf("http.request(POST, %s), status_code:%d, err:%w", uri, res.StatusCode, err)
}
if s.DebugSwitch == wechat.DebugOn {
xlog.Debugf("Wechat_Mini_SDK_Response: [%d] -> %s", res.StatusCode, string(bs))
diff --git a/open/open.go b/open/open.go
index 302680f..ade52ae 100644
--- a/open/open.go
+++ b/open/open.go
@@ -48,7 +48,7 @@ func New(appid, secret string, autoManageToken bool) (o *SDK) {
return
}
-func (s *SDK) DoRequestGet(c context.Context, path string, ptr interface{}) (err error) {
+func (s *SDK) DoRequestGet(c context.Context, path string, ptr any) (err error) {
uri := s.Host + path
httpClient := xhttp.NewClient()
if s.DebugSwitch == wechat.DebugOn {
@@ -57,7 +57,7 @@ func (s *SDK) DoRequestGet(c context.Context, path string, ptr interface{}) (err
httpClient.Header.Add(xhttp.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
res, bs, err := httpClient.Get(uri).EndBytes(c)
if err != nil {
- return fmt.Errorf("http.request(GET, %s):%w", uri, err)
+ return fmt.Errorf("http.request(GET, %s), status_code:%d, err:%w", uri, res.StatusCode, err)
}
if s.DebugSwitch == wechat.DebugOn {
xlog.Debugf("Wechat_Open_SDK_Response: [%d] -> %s", res.StatusCode, string(bs))
diff --git a/pkg/bmap/body_map.go b/pkg/bmap/body_map.go
index 340b5a5..1ed49f7 100644
--- a/pkg/bmap/body_map.go
+++ b/pkg/bmap/body_map.go
@@ -12,11 +12,11 @@ import (
"github.com/go-pay/wechat-sdk/pkg/util"
)
-type BodyMap map[string]interface{}
+type BodyMap map[string]any
type xmlMapMarshal struct {
XMLName xml.Name
- Value interface{} `xml:",cdata"`
+ Value any `xml:",cdata"`
}
type xmlMapUnmarshal struct {
@@ -25,7 +25,7 @@ type xmlMapUnmarshal struct {
}
// 设置参数
-func (bm BodyMap) Set(key string, value interface{}) BodyMap {
+func (bm BodyMap) Set(key string, value any) BodyMap {
bm[key] = value
return bm
}
@@ -65,7 +65,7 @@ func (bm BodyMap) GetString(key string) string {
}
// 获取原始参数
-func (bm BodyMap) GetInterface(key string) interface{} {
+func (bm BodyMap) GetInterface(key string) any {
if bm == nil {
return nil
}
@@ -94,7 +94,7 @@ func (bm BodyMap) JsonBody() (jb string) {
}
// Unmarshal to struct or slice point
-func (bm BodyMap) Unmarshal(ptr interface{}) (err error) {
+func (bm BodyMap) Unmarshal(ptr any) (err error) {
bs, err := json.Marshal(bm)
if err != nil {
return err
@@ -226,7 +226,7 @@ func (bm BodyMap) CheckEmptyError(keys ...string) error {
return nil
}
-func convertToString(v interface{}) (str string) {
+func convertToString(v any) (str string) {
if v == nil {
return ""
}
diff --git a/pkg/util/string.go b/pkg/util/string.go
index b33dee3..3fb764d 100644
--- a/pkg/util/string.go
+++ b/pkg/util/string.go
@@ -2,7 +2,7 @@ package util
import "encoding/json"
-func ConvertToString(v interface{}) (str string) {
+func ConvertToString(v any) (str string) {
if v == nil {
return NULL
}
diff --git a/pkg/xhttp/client.go b/pkg/xhttp/client.go
index ad584f4..60d4113 100644
--- a/pkg/xhttp/client.go
+++ b/pkg/xhttp/client.go
@@ -32,7 +32,7 @@ type Client struct {
FormString string
ContentType string
unmarshalType string
- multipartBodyMap map[string]interface{}
+ multipartBodyMap map[string]any
jsonByte []byte
err error
}
@@ -113,7 +113,7 @@ func (c *Client) Patch(url string) (client *Client) {
return c
}
-func (c *Client) SendStruct(v interface{}) (client *Client) {
+func (c *Client) SendStruct(v any) (client *Client) {
if v == nil {
return c
}
@@ -126,7 +126,7 @@ func (c *Client) SendStruct(v interface{}) (client *Client) {
case TypeJSON:
c.jsonByte = bs
case TypeXML, TypeUrlencoded, TypeForm, TypeFormData:
- body := make(map[string]interface{})
+ body := make(map[string]any)
if err = json.Unmarshal(bs, &body); err != nil {
c.err = fmt.Errorf("json.Unmarshal(%s, %+v):%w", string(bs), body, err)
return c
@@ -136,7 +136,7 @@ func (c *Client) SendStruct(v interface{}) (client *Client) {
return c
}
-func (c *Client) SendBodyMap(bm map[string]interface{}) (client *Client) {
+func (c *Client) SendBodyMap(bm map[string]any) (client *Client) {
if bm == nil {
return c
}
@@ -154,7 +154,7 @@ func (c *Client) SendBodyMap(bm map[string]interface{}) (client *Client) {
return c
}
-func (c *Client) SendMultipartBodyMap(bm map[string]interface{}) (client *Client) {
+func (c *Client) SendMultipartBodyMap(bm map[string]any) (client *Client) {
if bm == nil {
return c
}
@@ -185,7 +185,7 @@ func (c *Client) SendString(encodeStr string) (client *Client) {
return c
}
-func (c *Client) EndStruct(ctx context.Context, v interface{}) (res *http.Response, err error) {
+func (c *Client) EndStruct(ctx context.Context, v any) (res *http.Response, err error) {
res, bs, err := c.EndBytes(ctx)
if err != nil {
return nil, err
@@ -317,7 +317,7 @@ func (c *Client) EndBytes(ctx context.Context) (res *http.Response, bs []byte, e
return res, bs, nil
}
-func FormatURLParam(body map[string]interface{}) (urlParam string) {
+func FormatURLParam(body map[string]any) (urlParam string) {
var (
buf strings.Builder
keys []string
@@ -344,7 +344,7 @@ func FormatURLParam(body map[string]interface{}) (urlParam string) {
return buf.String()[:buf.Len()-1]
}
-func convertToString(v interface{}) (str string) {
+func convertToString(v any) (str string) {
if v == nil {
return ""
}
diff --git a/pkg/xhttp/client_test.go b/pkg/xhttp/client_test.go
index 32fc7d0..f12d8a9 100644
--- a/pkg/xhttp/client_test.go
+++ b/pkg/xhttp/client_test.go
@@ -12,9 +12,9 @@ import (
)
type HttpGet struct {
- Code int `json:"code"`
- Message string `json:"message"`
- Data interface{} `json:"data,omitempty"`
+ Code int `json:"code"`
+ Message string `json:"message"`
+ Data any `json:"data,omitempty"`
}
var ctx = context.Background()
diff --git a/pkg/xlog/color.go b/pkg/xlog/color.go
index 8c1c9c1..facdf67 100644
--- a/pkg/xlog/color.go
+++ b/pkg/xlog/color.go
@@ -79,34 +79,34 @@ func Color(color ColorType) *ColorLogger {
return cl
}
-func (l *ColorLogger) Info(args ...interface{}) {
+func (l *ColorLogger) Info(args ...any) {
l.i.LogOut(&l.Color, nil, args...)
}
-func (l *ColorLogger) Infof(format string, args ...interface{}) {
+func (l *ColorLogger) Infof(format string, args ...any) {
l.i.LogOut(&l.Color, &format, args...)
}
-func (l *ColorLogger) Debug(args ...interface{}) {
+func (l *ColorLogger) Debug(args ...any) {
l.d.LogOut(&l.Color, nil, args...)
}
-func (l *ColorLogger) Debugf(format string, args ...interface{}) {
+func (l *ColorLogger) Debugf(format string, args ...any) {
l.d.LogOut(&l.Color, &format, args...)
}
-func (l *ColorLogger) Warn(args ...interface{}) {
+func (l *ColorLogger) Warn(args ...any) {
l.w.LogOut(&l.Color, nil, args...)
}
-func (l *ColorLogger) Warnf(format string, args ...interface{}) {
+func (l *ColorLogger) Warnf(format string, args ...any) {
l.w.LogOut(&l.Color, &format, args...)
}
-func (l *ColorLogger) Error(args ...interface{}) {
+func (l *ColorLogger) Error(args ...any) {
l.e.LogOut(&l.Color, nil, args...)
}
-func (l *ColorLogger) Errorf(format string, args ...interface{}) {
+func (l *ColorLogger) Errorf(format string, args ...any) {
l.e.LogOut(&l.Color, &format, args...)
}
diff --git a/pkg/xlog/debug_logger.go b/pkg/xlog/debug_logger.go
index 27c7c00..8f26fd3 100644
--- a/pkg/xlog/debug_logger.go
+++ b/pkg/xlog/debug_logger.go
@@ -12,7 +12,7 @@ type DebugLogger struct {
once sync.Once
}
-func (d *DebugLogger) LogOut(col *ColorType, format *string, v ...interface{}) {
+func (d *DebugLogger) LogOut(col *ColorType, format *string, v ...any) {
d.once.Do(func() {
d.init()
})
diff --git a/pkg/xlog/error_logger.go b/pkg/xlog/error_logger.go
index 32eba31..bd65a6a 100644
--- a/pkg/xlog/error_logger.go
+++ b/pkg/xlog/error_logger.go
@@ -12,7 +12,7 @@ type ErrorLogger struct {
once sync.Once
}
-func (e *ErrorLogger) LogOut(col *ColorType, format *string, v ...interface{}) {
+func (e *ErrorLogger) LogOut(col *ColorType, format *string, v ...any) {
e.once.Do(func() {
e.init()
})
diff --git a/pkg/xlog/info_logger.go b/pkg/xlog/info_logger.go
index f1552c2..bfe347c 100644
--- a/pkg/xlog/info_logger.go
+++ b/pkg/xlog/info_logger.go
@@ -12,7 +12,7 @@ type InfoLogger struct {
once sync.Once
}
-func (i *InfoLogger) LogOut(col *ColorType, format *string, v ...interface{}) {
+func (i *InfoLogger) LogOut(col *ColorType, format *string, v ...any) {
i.once.Do(func() {
i.init()
})
diff --git a/pkg/xlog/log.go b/pkg/xlog/log.go
index 2486744..223dc8f 100644
--- a/pkg/xlog/log.go
+++ b/pkg/xlog/log.go
@@ -19,38 +19,38 @@ var (
)
type XLogger interface {
- LogOut(col *ColorType, format *string, args ...interface{})
+ LogOut(col *ColorType, format *string, args ...any)
}
-func Info(args ...interface{}) {
+func Info(args ...any) {
infoLog.LogOut(nil, nil, args...)
}
-func Infof(format string, args ...interface{}) {
+func Infof(format string, args ...any) {
infoLog.LogOut(nil, &format, args...)
}
-func Debug(args ...interface{}) {
+func Debug(args ...any) {
debugLog.LogOut(nil, nil, args...)
}
-func Debugf(format string, args ...interface{}) {
+func Debugf(format string, args ...any) {
debugLog.LogOut(nil, &format, args...)
}
-func Warn(args ...interface{}) {
+func Warn(args ...any) {
warnLog.LogOut(nil, nil, args...)
}
-func Warnf(format string, args ...interface{}) {
+func Warnf(format string, args ...any) {
warnLog.LogOut(nil, &format, args...)
}
-func Error(args ...interface{}) {
+func Error(args ...any) {
errLog.LogOut(nil, nil, args...)
}
-func Errorf(format string, args ...interface{}) {
+func Errorf(format string, args ...any) {
errLog.LogOut(nil, &format, args...)
}
diff --git a/pkg/xlog/warn_logger.go b/pkg/xlog/warn_logger.go
index 362b3e2..4b06565 100644
--- a/pkg/xlog/warn_logger.go
+++ b/pkg/xlog/warn_logger.go
@@ -12,7 +12,7 @@ type WarnLogger struct {
once sync.Once
}
-func (w *WarnLogger) LogOut(col *ColorType, format *string, v ...interface{}) {
+func (w *WarnLogger) LogOut(col *ColorType, format *string, v ...any) {
w.once.Do(func() {
w.init()
})
diff --git a/pkg/xtime/xtime.go b/pkg/xtime/xtime.go
index ff5b9f9..f23c5dc 100644
--- a/pkg/xtime/xtime.go
+++ b/pkg/xtime/xtime.go
@@ -11,7 +11,7 @@ import (
type Time int64
// Scan scan time.
-func (t *Time) Scan(src interface{}) (err error) {
+func (t *Time) Scan(src any) (err error) {
switch sc := src.(type) {
case time.Time:
*t = Time(sc.Unix())
diff --git a/public/public.go b/public/public.go
index 831daf4..95ca0ec 100644
--- a/public/public.go
+++ b/public/public.go
@@ -45,7 +45,7 @@ func New(appid, secret string, autoManageToken bool) (p *SDK, err error) {
return
}
-func (s *SDK) DoRequestGet(c context.Context, path string, ptr interface{}) (err error) {
+func (s *SDK) DoRequestGet(c context.Context, path string, ptr any) (err error) {
uri := s.Host + path
httpClient := xhttp.NewClient()
if s.DebugSwitch == wechat.DebugOn {
@@ -54,7 +54,7 @@ func (s *SDK) DoRequestGet(c context.Context, path string, ptr interface{}) (err
httpClient.Header.Add(xhttp.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
res, bs, err := httpClient.Get(uri).EndBytes(c)
if err != nil {
- return fmt.Errorf("http.request(GET, %s):%w", uri, err)
+ return fmt.Errorf("http.request(GET, %s), status_code:%d, err:%w", uri, res.StatusCode, err)
}
if s.DebugSwitch == wechat.DebugOn {
xlog.Debugf("Wechat_SDK_Response: [%d] -> %s", res.StatusCode, string(bs))
diff --git a/public/request.go b/public/request.go
index e02a6ba..4907f3a 100644
--- a/public/request.go
+++ b/public/request.go
@@ -13,7 +13,7 @@ import (
"github.com/go-pay/wechat-sdk/pkg/xlog"
)
-func (s *SDK) doRequestGet(c context.Context, path string, ptr interface{}) (err error) {
+func (s *SDK) doRequestGet(c context.Context, path string, ptr any) (err error) {
uri := s.Host + path
httpClient := xhttp.NewClient()
if s.DebugSwitch == wechat.DebugOn {
@@ -22,7 +22,7 @@ func (s *SDK) doRequestGet(c context.Context, path string, ptr interface{}) (err
httpClient.Header.Add(xhttp.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
res, bs, err := httpClient.Get(uri).EndBytes(c)
if err != nil {
- return fmt.Errorf("http.request(GET, %s):%w", uri, err)
+ return fmt.Errorf("http.request(GET, %s), status_code:%d, err:%w", uri, res.StatusCode, err)
}
if s.DebugSwitch == wechat.DebugOn {
xlog.Debugf("Wechat_Public_SDK_Response: [%d] -> %s", res.StatusCode, string(bs))
@@ -42,7 +42,7 @@ func (s *SDK) doRequestGet(c context.Context, path string, ptr interface{}) (err
// httpClient.Header.Add(xhttp.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
// res, bs, err := httpClient.Get(uri).EndBytes(c)
// if err != nil {
-// return nil, fmt.Errorf("http.request(GET, %s):%w", uri, err)
+// return nil, fmt.Errorf("http.request(GET, %s), status_code:%d, err:%w", uri, res.StatusCode, err)
// }
// if s.DebugSwitch == wechat.DebugOn {
// xlog.Debugf("Wechat_Public_SDK_Response: [%d] -> %s", res.StatusCode, string(bs))
@@ -55,7 +55,7 @@ func (s *SDK) doRequestGet(c context.Context, path string, ptr interface{}) (err
// return
//}
-func (s *SDK) doRequestPost(c context.Context, path string, body bmap.BodyMap, ptr interface{}) (err error) {
+func (s *SDK) doRequestPost(c context.Context, path string, body bmap.BodyMap, ptr any) (err error) {
uri := s.Host + path
httpClient := xhttp.NewClient()
if s.DebugSwitch == wechat.DebugOn {
@@ -65,7 +65,7 @@ func (s *SDK) doRequestPost(c context.Context, path string, body bmap.BodyMap, p
httpClient.Header.Add(xhttp.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
res, bs, err := httpClient.Post(uri).SendBodyMap(body).EndBytes(c)
if err != nil {
- return fmt.Errorf("http.request(POST, %s):%w", uri, err)
+ return fmt.Errorf("http.request(POST, %s), status_code:%d, err:%w", uri, res.StatusCode, err)
}
if s.DebugSwitch == wechat.DebugOn {
xlog.Debugf("Wechat_Public_SDK_Response: [%d] -> %s", res.StatusCode, string(bs))
@@ -76,7 +76,7 @@ func (s *SDK) doRequestPost(c context.Context, path string, body bmap.BodyMap, p
return
}
-//func (s *SDK) doRequestPostFile(ctx context.Context, path string, body bmap.BodyMap, ptr interface{}) (err error) {
+//func (s *SDK) doRequestPostFile(ctx context.Context, path string, body bmap.BodyMap, ptr any) (err error) {
// uri := s.Host + path
// httpClient := xhttp.NewClient()
// if s.DebugSwitch == wechat.DebugOn {
@@ -85,7 +85,7 @@ func (s *SDK) doRequestPost(c context.Context, path string, body bmap.BodyMap, p
// httpClient.Header.Add(xhttp.HeaderRequestID, fmt.Sprintf("%s-%d", util.RandomString(21), time.Now().Unix()))
// res, bs, err := httpClient.Type(xhttp.TypeMultipartFormData).Post(uri).SendMultipartBodyMap(body).EndBytes(ctx)
// if err != nil {
-// return fmt.Errorf("http.request(POST, %s):%w", uri, err)
+// return fmt.Errorf("http.request(POST, %s), status_code:%d, err:%w", uri, res.StatusCode, err)
// }
// if s.DebugSwitch == wechat.DebugOn {
// xlog.Debugf("Wechat_Public_SDK_Response: [%d] -> %s", res.StatusCode, string(bs))
diff --git a/release_note.txt b/release_note.txt
index 45e5168..dc82cab 100644
--- a/release_note.txt
+++ b/release_note.txt
@@ -1,6 +1,8 @@
版本号:Release 1.1.5
修改记录:
(1) 微信公众号:新增 ticket获取,js-sdk使用校验签名接口
+ (2) 微信小程序:自动维护token改为获取稳定版接口调用凭据,并且 forceRefresh=false
+ (3) 微信小程序:新增公共API 获取接口调用凭据、获取稳定版接口调用凭据
版本号:Release 1.1.4
修改记录: