You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
2.6 KiB
Go

package wechat
import (
"crypto/sha1"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"io"
"net/http"
)
type WechatService struct {
AppId string
AppSecret string
client *http.Client
}
func NewWechatService(appId, appSecret string) *WechatService {
return &WechatService{appId, appSecret, nil}
}
func (ws *WechatService) GetOpenID(code string) (string, error) {
url := fmt.Sprintf(
"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
ws.AppId,
ws.AppSecret,
code,
)
resp, err := http.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()
var res struct {
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token"`
OpenID string `json:"openid"`
Scope string `json:"scope"`
ErrCode int `json:"errcode"`
ErrMsg string `json:"errmsg"`
}
if err := json.NewDecoder(resp.Body).Decode(&res); err != nil {
return "", errors.New("Failed to decode response")
}
fmt.Printf("%+v\n", res)
if res.ErrCode != 0 {
return "", errors.New(fmt.Sprintf("WeChat error: %s", res.ErrMsg))
}
// 🎯 获取到 openid
return res.OpenID, nil
}
func (ws *WechatService) GetAccessToken() (string, error) {
url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", ws.AppId, ws.AppSecret)
resp, err := http.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()
var result map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return "", err
}
// 获取 access_token
accessToken, ok := result["access_token"].(string)
if !ok {
return "", errors.New("获取 access_token 失败")
}
return accessToken, nil
}
func (ws *WechatService) GetJsapiTicket(accessToken string) (string, error) {
url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi", accessToken)
resp, err := http.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()
var result map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return "", err
}
// 获取 jsapi_ticket
jsapiTicket, ok := result["ticket"].(string)
if !ok {
return "", errors.New("获取 jsapi_ticket 失败")
}
return jsapiTicket, nil
}
func (ws *WechatService) SignWxConfig(signStr string) (string, error) {
h := sha1.New()
_, err := io.WriteString(h, signStr)
if err != nil {
return "", err
}
signature := hex.EncodeToString(h.Sum(nil))
return signature, nil
}