ソースを参照

add func GetWeChatUserInfo and DecryptOpenDataToStruct

Jerry 6 年 前
コミット
9facee6653
1 ファイル変更83 行追加12 行削除
  1. 83 12
      wechat_servier_api.go

+ 83 - 12
wechat_servier_api.go

@@ -7,12 +7,19 @@ package gopay
 
 
 import (
 import (
 	"bytes"
 	"bytes"
+	"crypto/aes"
+	"crypto/cipher"
 	"crypto/hmac"
 	"crypto/hmac"
 	"crypto/md5"
 	"crypto/md5"
 	"crypto/sha256"
 	"crypto/sha256"
 	"crypto/tls"
 	"crypto/tls"
+	"encoding/base64"
 	"encoding/hex"
 	"encoding/hex"
+	"encoding/json"
+	"errors"
+	"fmt"
 	"github.com/parnurzeal/gorequest"
 	"github.com/parnurzeal/gorequest"
+	"reflect"
 	"strings"
 	"strings"
 )
 )
 
 
@@ -96,35 +103,77 @@ func GetH5PaySign(appId, nonceStr, prepayId, signType, timeStamp, secretKey stri
 	return
 	return
 }
 }
 
 
+//解密开放数据
+//    encryptedData:包括敏感数据在内的完整用户信息的加密数据
+//    iv:加密算法的初始向量
+//    sessionKey:会话密钥
+//    beanPtr:需要解析到的结构体指针
+func DecryptOpenDataToStruct(encryptedData, iv, sessionKey string, beanPtr interface{}) (err error) {
+	//验证参数类型
+	beanValue := reflect.ValueOf(beanPtr)
+	if beanValue.Kind() != reflect.Ptr {
+		return errors.New("传入beanPtr类型必须是以指针形式")
+	}
+	//验证interface{}类型
+	if beanValue.Elem().Kind() != reflect.Struct {
+		return errors.New("传入interface{}必须是结构体")
+	}
+	aesKey, _ := base64.StdEncoding.DecodeString(sessionKey)
+	ivKey, _ := base64.StdEncoding.DecodeString(iv)
+	cipherText, _ := base64.StdEncoding.DecodeString(encryptedData)
+
+	if len(cipherText)%len(aesKey) != 0 {
+		return errors.New("encryptedData is error")
+	}
+	//fmt.Println("cipherText:", cipherText)
+	block, err := aes.NewCipher(aesKey)
+	if err != nil {
+		return err
+	}
+	//解密
+	blockMode := cipher.NewCBCDecrypter(block, ivKey)
+	plainText := make([]byte, len(cipherText))
+	blockMode.CryptBlocks(plainText, cipherText)
+	//fmt.Println("plainText1:", plainText)
+	plainText = PKCS7UnPadding(plainText)
+	//fmt.Println("plainText:", plainText)
+	//解析
+	err = json.Unmarshal(plainText, beanPtr)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
 //获取微信用户的OpenId、SessionKey、UnionId
 //获取微信用户的OpenId、SessionKey、UnionId
 //    appId:APPID
 //    appId:APPID
 //    appSecret:AppSecret
 //    appSecret:AppSecret
 //    wxCode:小程序调用wx.login 获取的code
 //    wxCode:小程序调用wx.login 获取的code
-func Code2Session(appId, appSecret, wxCode string) (userRsp *Code2SessionRsp, err error) {
-	userRsp = new(Code2SessionRsp)
+func Code2Session(appId, appSecret, wxCode string) (sessionRsp *Code2SessionRsp, err error) {
+	sessionRsp = new(Code2SessionRsp)
 	url := "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + appSecret + "&js_code=" + wxCode + "&grant_type=authorization_code"
 	url := "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + appSecret + "&js_code=" + wxCode + "&grant_type=authorization_code"
 	agent := HttpAgent()
 	agent := HttpAgent()
-	_, _, errs := agent.Get(url).EndStruct(userRsp)
+	_, _, errs := agent.Get(url).EndStruct(sessionRsp)
 	if len(errs) > 0 {
 	if len(errs) > 0 {
 		return nil, errs[0]
 		return nil, errs[0]
 	} else {
 	} else {
-		return userRsp, nil
+		return sessionRsp, nil
 	}
 	}
 }
 }
 
 
 //获取小程序全局唯一后台接口调用凭据(AccessToken:157字符)
 //获取小程序全局唯一后台接口调用凭据(AccessToken:157字符)
 //    appId:APPID
 //    appId:APPID
 //    appSecret:AppSecret
 //    appSecret:AppSecret
-func GetAccessToken(appId, appSecret string) (rsp *GetAccessTokenRsp, err error) {
-	rsp = new(GetAccessTokenRsp)
+func GetAccessToken(appId, appSecret string) (accessToken *AccessToken, err error) {
+	accessToken = new(AccessToken)
 	url := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret
 	url := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret
 
 
 	agent := HttpAgent()
 	agent := HttpAgent()
-	_, _, errs := agent.Get(url).EndStruct(rsp)
+	_, _, errs := agent.Get(url).EndStruct(accessToken)
 	if len(errs) > 0 {
 	if len(errs) > 0 {
 		return nil, errs[0]
 		return nil, errs[0]
 	} else {
 	} else {
-		return rsp, nil
+		return accessToken, nil
 	}
 	}
 }
 }
 
 
@@ -132,15 +181,37 @@ func GetAccessToken(appId, appSecret string) (rsp *GetAccessTokenRsp, err error)
 //    accessToken:接口调用凭据
 //    accessToken:接口调用凭据
 //    openId:用户的OpenID
 //    openId:用户的OpenID
 //    transactionId:微信支付订单号
 //    transactionId:微信支付订单号
-func GetPaidUnionId(accessToken, openId, transactionId string) (rsp *GetPaidUnionIdRsp, err error) {
-	rsp = new(GetPaidUnionIdRsp)
+func GetPaidUnionId(accessToken, openId, transactionId string) (unionId *PaidUnionId, err error) {
+	unionId = new(PaidUnionId)
 	url := "https://api.weixin.qq.com/wxa/getpaidunionid?access_token=" + accessToken + "&openid=" + openId + "&transaction_id=" + transactionId
 	url := "https://api.weixin.qq.com/wxa/getpaidunionid?access_token=" + accessToken + "&openid=" + openId + "&transaction_id=" + transactionId
 
 
 	agent := HttpAgent()
 	agent := HttpAgent()
-	_, _, errs := agent.Get(url).EndStruct(rsp)
+	_, _, errs := agent.Get(url).EndStruct(unionId)
+	if len(errs) > 0 {
+		return nil, errs[0]
+	} else {
+		return unionId, nil
+	}
+}
+
+//获取用户基本信息(UnionID机制)
+//    accessToken:接口调用凭据
+//    openId:用户的OpenID
+//    lang:默认为 zh_CN ,可选填 zh_CN 简体,zh_TW 繁体,en 英语
+func GetWeChatUserInfo(accessToken, openId string, lang ...string) (userInfo *WeChatUserInfo, err error) {
+	userInfo = new(WeChatUserInfo)
+	var url string
+	if len(lang) > 0 {
+		url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openId + "&lang=" + lang[0]
+	} else {
+		url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openId + "&lang=zh_CN"
+	}
+	fmt.Println(url)
+	agent := HttpAgent()
+	_, _, errs := agent.Get(url).EndStruct(userInfo)
 	if len(errs) > 0 {
 	if len(errs) > 0 {
 		return nil, errs[0]
 		return nil, errs[0]
 	} else {
 	} else {
-		return rsp, nil
+		return userInfo, nil
 	}
 	}
 }
 }