微信红包

This commit is contained in:
ziming 2025-11-05 18:26:29 +08:00
parent 9cb8d100d8
commit 442d51a364
4 changed files with 0 additions and 333 deletions

View File

@ -1,133 +0,0 @@
package authorize
import (
"encoding/json"
"net/http"
"strconv"
"time"
"transfer/internal/pkg/request"
)
func GetTokenByMKS(appId, secret string) (accessToken string, expiresIn int64, err error) {
uri := "http://marketapi.1688sup.com/mks/open/v1/wechat/getToken"
body := struct {
AppId string `json:"app_id"`
Secret string `json:"secret"`
}{
AppId: appId,
Secret: secret,
}
bodyBytes, err := json.Marshal(body)
if err != nil {
return "", 0, err
}
h := http.Header{
"Content-Type": []string{"application/json"},
}
hc := &http.Client{
Timeout: 15 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 100, // 最大空闲连接数
MaxIdleConnsPerHost: 20, // 每个主机的最大空闲连接数
IdleConnTimeout: 30 * time.Second, // 空闲连接超时时间
},
}
isSuccess := func(code int) bool {
return code == http.StatusOK || code == http.StatusCreated
}
srv := request.NewService(request.WithHttpClient(hc), request.WithStatusCodeFunc(isSuccess))
_, respBody, err := srv.POST(uri, h, bodyBytes)
if err != nil {
return "", 0, err
}
var response struct {
Code int `json:"code"`
Data struct {
Token string `json:"token"`
Ttl string `json:"ttl"`
} `json:"data"`
Message string `json:"message"`
}
if err2 := json.Unmarshal(respBody, &response); err2 != nil {
return "", 0, err2
}
ttl, err := strconv.ParseInt(response.Data.Ttl, 10, 64)
if err != nil {
return "", 0, err
}
return response.Data.Token, ttl, nil
}
func GetJsapiTicketByMKS(appId, secret string) (accessToken string, expiresIn int64, err error) {
uri := "http://marketapi.1688sup.com/mks/open/v1/wechat/getJsapiTicket"
body := struct {
AppId string `json:"app_id"`
Secret string `json:"secret"`
}{
AppId: appId,
Secret: secret,
}
bodyBytes, err := json.Marshal(body)
if err != nil {
return "", 0, err
}
h := http.Header{
"Content-Type": []string{"application/json"},
}
hc := &http.Client{
Timeout: 15 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 100, // 最大空闲连接数
MaxIdleConnsPerHost: 20, // 每个主机的最大空闲连接数
IdleConnTimeout: 30 * time.Second, // 空闲连接超时时间
},
}
isSuccess := func(code int) bool {
return code == http.StatusOK || code == http.StatusCreated
}
srv := request.NewService(request.WithHttpClient(hc), request.WithStatusCodeFunc(isSuccess))
_, respBody, err := srv.POST(uri, h, bodyBytes)
if err != nil {
return "", 0, err
}
var response struct {
Code int `json:"code"`
Data struct {
JsapiTicket string `json:"jsapi_ticket"`
Ttl string `json:"ttl"`
} `json:"data"`
Message string `json:"message"`
}
if err2 := json.Unmarshal(respBody, &response); err2 != nil {
return "", 0, err2
}
ttl, err := strconv.ParseInt(response.Data.Ttl, 10, 64)
if err != nil {
return "", 0, err
}
return response.Data.JsapiTicket, ttl, nil
}

View File

@ -1,12 +0,0 @@
package authorize
type TransferConfigRequest struct {
JsapiTicket string // 有效的jsapi_ticket,
Url string // 当前网页的URL不包含#及其后面部分
}
type TransferConfigResponse struct {
Timestamp int64 // 必填,生成签名的时间戳
NonceStr string // 必填,生成签名的随机串
Signature string // 必填,签名
}

View File

@ -1,135 +0,0 @@
package authorize
import (
"context"
"fmt"
"github.com/carlmjohnson/requests"
"net/url"
"time"
"transfer/internal/pkg/wechat/utils"
)
func AuthorizeUrl(_ context.Context, appId, redirectUri string) (url string) {
baseUrl := "https://open.weixin.qq.com/connect/oauth2/authorize"
responseType := "code"
scope := "snsapi_base"
return baseUrl + "?appid=" + appId + "&redirect_uri=" + redirectUri + "&response_type=" + responseType + "&scope=" + scope + "#wechat_redirect"
}
// GetOpenId 获取openid https://developers.weixin.qq.com/minigame/dev/api-backend/open-api/login/auth.code2Session.html
// https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html
func GetOpenId(ctx context.Context, appId, secret, authCode string) (openid string, err error) {
var uv = url.Values{}
uv.Set("appid", appId)
uv.Set("secret", secret)
uv.Set("code", authCode)
uv.Set("grant_type", "authorization_code")
var response struct {
//错误时
ErrCode int64 `json:"errcode"`
ErrMsg string `json:"errmsg"`
//正常情况下
Openid string `json:"openid"`
Unionid string `json:"unionid"`
SessionKey string `json:"session_key"`
}
baseurl := "https://api.weixin.qq.com/sns/oauth2/access_token"
if err = requests.URL(baseurl).Params(uv).ToJSON(&response).Fetch(ctx); err != nil {
return openid, fmt.Errorf("请求异常msg:" + err.Error())
}
if response.ErrCode != 0 {
return openid, fmt.Errorf("请求错误,%d,%s", response.ErrCode, response.ErrMsg)
}
return response.Openid, nil
}
// GetToken 获取授权token https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
func GetToken(ctx context.Context, appId, secret string) (accessToken string, expiresIn int64, err error) {
baseurl := "https://api.weixin.qq.com/cgi-bin/token"
var uv = url.Values{}
uv.Set("grant_type", "client_credential")
uv.Set("appid", appId)
uv.Set("secret", secret)
type OrderResp struct {
//错误时
ErrCode int64 `json:"errcode"`
ErrMsg string `json:"errmsg"`
//正常情况下
ExpiresIn int64 `json:"expires_in"`
AccessToken string `json:"access_token"`
}
var response OrderResp
err = requests.URL(baseurl).Post().Params(uv).ToJSON(&response).Fetch(ctx)
if err != nil {
return accessToken, expiresIn, fmt.Errorf("请求异常msg:" + err.Error())
}
if response.ErrCode != 0 {
return accessToken, expiresIn, fmt.Errorf("请求错误ErrCode[%d],ErrMsg[%s]", response.ErrCode, response.ErrMsg)
}
return response.AccessToken, response.ExpiresIn, nil
}
// GetJsapiTicket https://developers.weixin.qq.com/doc/service/guide/h5/jssdk.html
func GetJsapiTicket(ctx context.Context, accessToken string) (ticket string, expiresIn int64, err error) {
baseurl := "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken + "&type=jsapi"
type OrderResp struct {
//错误时
ErrCode int64 `json:"errcode"`
ErrMsg string `json:"errmsg"`
//正常情况下
ExpiresIn int64 `json:"expires_in"`
Ticket string `json:"ticket"`
}
var response OrderResp
err = requests.URL(baseurl).ToJSON(&response).Fetch(ctx)
if err != nil {
return accessToken, expiresIn, fmt.Errorf("请求异常msg:" + err.Error())
}
if response.ErrCode != 0 {
return accessToken, expiresIn, fmt.Errorf("请求错误ErrCode[%d],ErrMsg[%s]", response.ErrCode, response.ErrMsg)
}
return response.Ticket, response.ExpiresIn, nil
}
// WxConfig 转账通知 @link https://developers.weixin.qq.com/doc/service/guide/h5/jssdk.html#62
// 验证工具 https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
func WxConfig(request *TransferConfigRequest) (response *TransferConfigResponse, err error) {
nonceStr, err := utils.GenerateNonce()
if err != nil {
return nil, err
}
timestamp := time.Now().Unix()
params := map[string]any{
"noncestr": nonceStr,
"jsapi_ticket": request.JsapiTicket,
"timestamp": timestamp,
"url": request.Url,
}
return &TransferConfigResponse{
Timestamp: timestamp,
NonceStr: nonceStr,
Signature: utils.Sha1(utils.BuildSortedQueryString(params)),
}, nil
}

View File

@ -1,53 +0,0 @@
package authorize
import (
"context"
"testing"
)
func TestAuthorizeUrl(t *testing.T) {
// 公众号登录密码 fjxw1234
ctx := context.Background()
appId := "wxe3bd59243545fa8a"
//redirectUri := "https://lsxdwx.access.86698.cn/"
redirectUri := "https://transferweb-pre.86698.cn/home/V8X7D5ydg5jpPE9kKZ"
url := AuthorizeUrl(ctx, appId, redirectUri)
t.Logf("AuthorizeUrl() url = %s", url)
}
func TestGetOpenId(t *testing.T) {
ctx := context.Background()
appId := "wxe3bd59243545fa8a"
secret := "4c9649cb998f71038e187b4c58f5fda0"
//ojbqr6HpeWKFy9Sgdx8yCmmeVJiws
openId, err := GetOpenId(ctx, appId, secret, "051d57Ha15I7ZJ0YJRGa1uDBEP1d57HM")
if err != nil {
t.Errorf("GetOpenId() error = %v", err)
return
}
t.Logf("GetOpenId() openId = %ss", openId)
}
func TestGetToken(t *testing.T) {
appId := "wxe3bd59243545fa8a"
secret := "4c9649cb998f71038e187b4c58f5fda0"
gotAccessToken, gotExpiresIn, err := GetTokenByMKS(appId, secret)
if err != nil {
t.Errorf("GetToken() error = %v", err)
return
}
t.Logf("GetToken() gotAccessToken = %v, gotExpiresIn = %v", gotAccessToken, gotExpiresIn)
}
func TestGetJsapiTicket(t *testing.T) {
appId := "wxe3bd59243545fa8a"
secret := "4c9649cb998f71038e187b4c58f5fda0"
ticket, gotExpiresIn, err := GetJsapiTicketByMKS(appId, secret)
if err != nil {
t.Errorf("GetToken() error = %v", err)
return
}
// O3SMpm8bG7kJnF36aXbe85Ex-xY8i_9qz8lzJov4TMdcDS_pIj_GV8TaZdrDvlvz9aoiI-8BJWGmGvRwq6RqrA
t.Logf("GetToken() ticket = %v, gotExpiresIn = %v", ticket, gotExpiresIn)
}