|
|
@@ -10,11 +10,22 @@ import (
|
|
|
)
|
|
|
|
|
|
const (
|
|
|
+ // code2SessionURL 小程序登录
|
|
|
code2SessionURL = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
|
|
|
-
|
|
|
+ // checkEncryptedDataURL 检查加密信息
|
|
|
checkEncryptedDataURL = "https://api.weixin.qq.com/wxa/business/checkencryptedmsg?access_token=%s"
|
|
|
-
|
|
|
+ // getPhoneNumber 获取手机号
|
|
|
getPhoneNumber = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s"
|
|
|
+ // checkSessionURL 检验登录态
|
|
|
+ checkSessionURL = "https://api.weixin.qq.com/wxa/checksession?access_token=%s&signature=%s&openid=%s&sig_method=hmac_sha256"
|
|
|
+ // resetUserSessionKeyURL 重置登录态
|
|
|
+ resetUserSessionKeyURL = "https://api.weixin.qq.com/wxa/resetusersessionkey?access_token=%s&signature=%s&openid=%s&sig_method=hmac_sha256"
|
|
|
+ // getPluginOpenPIDURL 获取插件用户openPID
|
|
|
+ getPluginOpenPIDURL = "https://api.weixin.qq.com/wxa/getpluginopenpid?access_token=%s"
|
|
|
+ // getPaidUnionIDURL 支付后获取 UnionID
|
|
|
+ getPaidUnionIDURL = "https://api.weixin.qq.com/wxa/getpaidunionid"
|
|
|
+ // getUserEncryptKeyURL 获取用户encryptKey
|
|
|
+ getUserEncryptKeyURL = "https://api.weixin.qq.com/wxa/business/getuserencryptkey?access_token=%s&signature=%s&openid=%s&sig_method=hmac_sha256"
|
|
|
)
|
|
|
|
|
|
// Auth 登录/用户信息
|
|
|
@@ -65,9 +76,45 @@ func (auth *Auth) Code2SessionContext(ctx context2.Context, jsCode string) (resu
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+type (
|
|
|
+ // GetPaidUnionIDRequest 支付后获取UnionID请求
|
|
|
+ GetPaidUnionIDRequest struct {
|
|
|
+ OpenID string `json:"openid"`
|
|
|
+ TransactionID string `json:"transaction_id,omitempty"`
|
|
|
+ MchID string `json:"mch_id,omitempty"`
|
|
|
+ OutTradeNo string `json:"out_trade_no,omitempty"`
|
|
|
+ }
|
|
|
+
|
|
|
+ // GetPaidUnionIDResponse 支付后获取UnionID响应
|
|
|
+ GetPaidUnionIDResponse struct {
|
|
|
+ util.CommonError
|
|
|
+ UnionID string `json:"unionid"`
|
|
|
+ }
|
|
|
+)
|
|
|
+
|
|
|
// GetPaidUnionID 用户支付完成后,获取该用户的 UnionId,无需用户授权
|
|
|
-func (auth *Auth) GetPaidUnionID() {
|
|
|
- // TODO
|
|
|
+// see https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/basic-info/getPaidUnionid.html
|
|
|
+func (auth *Auth) GetPaidUnionID(req *GetPaidUnionIDRequest) (string, error) {
|
|
|
+ var (
|
|
|
+ accessToken string
|
|
|
+ err error
|
|
|
+ )
|
|
|
+ if accessToken, err = auth.GetAccessToken(); err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+ var url string
|
|
|
+ if req.TransactionID != "" {
|
|
|
+ url = fmt.Sprintf("%s?access_token=%s&openid=%s&transaction_id=%s", getPaidUnionIDURL, accessToken, req.OpenID, req.TransactionID)
|
|
|
+ } else {
|
|
|
+ url = fmt.Sprintf("%s?access_token=%s&openid=%s&mch_id=%s&out_trade_no=%s", getPaidUnionIDURL, accessToken, req.OpenID, req.MchID, req.OutTradeNo)
|
|
|
+ }
|
|
|
+ var response []byte
|
|
|
+ if response, err = util.HTTPGet(url); err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+ result := &GetPaidUnionIDResponse{}
|
|
|
+ err = util.DecodeWithError(response, result, "GetPaidUnionID")
|
|
|
+ return result.UnionID, err
|
|
|
}
|
|
|
|
|
|
// CheckEncryptedData .检查加密信息是否由微信生成(当前只支持手机号加密数据),只能检测最近3天生成的加密数据
|
|
|
@@ -146,3 +193,115 @@ func (auth *Auth) GetPhoneNumberContext(ctx context2.Context, code string) (*Get
|
|
|
func (auth *Auth) GetPhoneNumber(code string) (*GetPhoneNumberResponse, error) {
|
|
|
return auth.GetPhoneNumberContext(context2.Background(), code)
|
|
|
}
|
|
|
+
|
|
|
+// CheckSession 检验登录态
|
|
|
+// see https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/checkSessionKey.html
|
|
|
+func (auth *Auth) CheckSession(signature, openID string) error {
|
|
|
+ var (
|
|
|
+ accessToken string
|
|
|
+ err error
|
|
|
+ )
|
|
|
+ if accessToken, err = auth.GetAccessToken(); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ var response []byte
|
|
|
+ if response, err = util.HTTPGet(fmt.Sprintf(checkSessionURL, accessToken, signature, openID)); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ return util.DecodeWithCommonError(response, "CheckSession")
|
|
|
+}
|
|
|
+
|
|
|
+// ResetUserSessionKeyResponse 重置登录态响应
|
|
|
+type ResetUserSessionKeyResponse struct {
|
|
|
+ util.CommonError
|
|
|
+ OpenID string `json:"openid"`
|
|
|
+ SessionKey string `json:"session_key"`
|
|
|
+}
|
|
|
+
|
|
|
+// ResetUserSessionKey 重置登录态
|
|
|
+// see https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/ResetUserSessionKey.html
|
|
|
+func (auth *Auth) ResetUserSessionKey(signature, openID string) (*ResetUserSessionKeyResponse, error) {
|
|
|
+ var (
|
|
|
+ accessToken string
|
|
|
+ err error
|
|
|
+ )
|
|
|
+ if accessToken, err = auth.GetAccessToken(); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ var response []byte
|
|
|
+ if response, err = util.HTTPGet(fmt.Sprintf(resetUserSessionKeyURL, accessToken, signature, openID)); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ result := &ResetUserSessionKeyResponse{}
|
|
|
+ err = util.DecodeWithError(response, result, "ResetUserSessionKey")
|
|
|
+ return result, err
|
|
|
+}
|
|
|
+
|
|
|
+type (
|
|
|
+ // GetPluginOpenPIDRequest 获取插件用户openPID请求
|
|
|
+ GetPluginOpenPIDRequest struct {
|
|
|
+ Code string `json:"code"`
|
|
|
+ }
|
|
|
+
|
|
|
+ // GetPluginOpenPIDResponse 获取插件用户openPID响应
|
|
|
+ GetPluginOpenPIDResponse struct {
|
|
|
+ util.CommonError
|
|
|
+ OpenPID string `json:"openpid"`
|
|
|
+ }
|
|
|
+)
|
|
|
+
|
|
|
+// GetPluginOpenPID 获取插件用户openPID
|
|
|
+// see https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/basic-info/getPluginOpenPId.html
|
|
|
+func (auth *Auth) GetPluginOpenPID(code string) (string, error) {
|
|
|
+ var (
|
|
|
+ accessToken string
|
|
|
+ err error
|
|
|
+ )
|
|
|
+ if accessToken, err = auth.GetAccessToken(); err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+ req := &GetPluginOpenPIDRequest{
|
|
|
+ Code: code,
|
|
|
+ }
|
|
|
+ var response []byte
|
|
|
+ if response, err = util.PostJSON(fmt.Sprintf(getPluginOpenPIDURL, accessToken), req); err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+ result := &GetPluginOpenPIDResponse{}
|
|
|
+ err = util.DecodeWithError(response, result, "GetPluginOpenPID")
|
|
|
+ return result.OpenPID, err
|
|
|
+}
|
|
|
+
|
|
|
+// GetUserEncryptKeyResponse 获取用户encryptKey响应
|
|
|
+type GetUserEncryptKeyResponse struct {
|
|
|
+ util.CommonError
|
|
|
+ KeyInfoList []KeyInfo `json:"key_info_list"`
|
|
|
+}
|
|
|
+
|
|
|
+// KeyInfo 用户最近三次的加密key
|
|
|
+type KeyInfo struct {
|
|
|
+ EncryptKey string `json:"encrypt_key"`
|
|
|
+ Version int64 `json:"version"`
|
|
|
+ ExpireIn int64 `json:"expire_in"`
|
|
|
+ Iv string `json:"iv"`
|
|
|
+ CreateTime int64 `json:"create_time"`
|
|
|
+}
|
|
|
+
|
|
|
+// GetUserEncryptKey 获取用户encryptKey
|
|
|
+// see https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/internet/getUserEncryptKey.html
|
|
|
+func (auth *Auth) GetUserEncryptKey(signature, openID string) (*GetUserEncryptKeyResponse, error) {
|
|
|
+ var (
|
|
|
+ accessToken string
|
|
|
+ err error
|
|
|
+ )
|
|
|
+ if accessToken, err = auth.GetAccessToken(); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ var response []byte
|
|
|
+ if response, err = util.HTTPGet(fmt.Sprintf(getUserEncryptKeyURL, accessToken, signature, openID)); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ result := &GetUserEncryptKeyResponse{}
|
|
|
+ err = util.DecodeWithError(response, result, "GetUserEncryptKey")
|
|
|
+ return result, err
|
|
|
+}
|