微信红包
This commit is contained in:
parent
9cb8d100d8
commit
442d51a364
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
@ -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 // 必填,签名
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
@ -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)
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue