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 }