Jerry 6 лет назад
Родитель
Сommit
628c4ff233
5 измененных файлов с 38 добавлено и 14 удалено
  1. 1 0
      README.md
  2. 1 0
      README_EN.md
  3. 1 1
      examples/wechat/wx_UnifiedOrder.go
  4. 13 8
      wechat_client.go
  5. 22 5
      wechat_params.go

+ 1 - 0
README.md

@@ -40,6 +40,7 @@
 ## 微信公共API
 
 * gopay.GetWeChatParamSign() => 获取微信支付所需参数里的Sign值(通过支付参数计算Sign值)
+* gopay.GetWeChatSanBoxParamSign() => 获取微信支付沙箱环境所需参数里的Sign值(通过支付参数计算Sign值)
 * gopay.GetMiniPaySign() => 获取微信小程序支付所需要的paySign
 * gopay.GetH5PaySign() => 获取微信内H5支付所需要的paySign
 * gopay.GetAppPaySign() => 获取APP支付所需要的paySign

+ 1 - 0
README_EN.md

@@ -39,6 +39,7 @@ The Golang SDK for WeChat and AliPay
 ## WeChat Public API
 
 * gopay.GetWeChatParamSign() => 获取微信支付所需参数里的Sign值(通过支付参数计算Sign值)
+* gopay.GetWeChatSanBoxParamSign() => 获取微信支付沙箱环境所需参数里的Sign值(通过支付参数计算Sign值)
 * gopay.GetMiniPaySign() => Obtain the paySign required for WeChat Applet Payment
 * gopay.GetH5PaySign() => Obtain the paySign required for H5 Payment in WeChat
 * gopay.GetAppPaySign() => Obtain the paySign required for App Payment

+ 1 - 1
examples/wechat/wx_UnifiedOrder.go

@@ -10,7 +10,7 @@ import (
 func UnifiedOrder() {
 	//初始化微信客户端
 	//    appId:应用ID
-	//    MchID:商户ID
+	//    mchId:商户ID
 	//    apiKey:API秘钥值
 	//    isProd:是否是正式环境
 	client := gopay.NewWeChatClient("wxdaa2ab9ef87b5497", "1368139502", "GFDS8j98rewnmgl45wHTt980jg543abc", false)

+ 13 - 8
wechat_client.go

@@ -330,7 +330,7 @@ func (this *weChatClient) BatchQueryComment(body BodyMap, certFilePath, keyFileP
 
 //企业向微信用户个人付款
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1
-//    此方法未支持沙箱环境,默认正式环境,转账请慎重
+//    注意:此方法未支持沙箱环境,默认正式环境,转账请慎重
 func (this *weChatClient) Transfer(body BodyMap, certFilePath, keyFilePath, pkcs12FilePath string) (wxRsp *WeChatTransfersResponse, err error) {
 	var bytes []byte
 	var sign string
@@ -358,7 +358,7 @@ func (this *weChatClient) Transfer(body BodyMap, certFilePath, keyFilePath, pkcs
 	agent.TLSClientConfig(tlsConfig)
 
 	//本地计算Sign
-	sign = getLocalSign(this.apiKey, SignType_MD5, body)
+	sign = getWeChatReleaseSign(this.apiKey, SignType_MD5, body)
 
 	body.Set("sign", sign)
 	reqXML := generateXml(body)
@@ -390,22 +390,27 @@ func (this *weChatClient) doWeChat(body BodyMap, path string, tlsConfig ...*tls.
 	body.Set("appid", this.AppId)
 	body.Set("mch_id", this.MchId)
 	//===============生成参数===================
+	if body.Get("sign") != null {
+		goto GoRequest
+	}
+
+	//计算Sign值
 	if !this.isProd {
 		//沙箱环境
 		body.Set("sign_type", SignType_MD5)
-		//从微信接口获取SanBoxSignKey
-		key, err := getSanBoxSign(this.MchId, body.Get("nonce_str"), this.apiKey, SignType_MD5)
+		//沙箱环境Sign值
+		sign, err = getWeChatSignBoxSign(this.MchId, this.apiKey, body)
 		if err != nil {
-			//fmt.Println("getSanBoxSign:", err)
+			//fmt.Println("getWeChatSignBoxSign:", err)
 			return nil, err
 		}
-		sign = getLocalSign(key, body.Get("sign_type"), body)
 	} else {
 		//正式环境
-		//本地计算Sign
-		sign = getLocalSign(this.apiKey, body.Get("sign_type"), body)
+		sign = getWeChatReleaseSign(this.apiKey, body.Get("sign_type"), body)
 	}
 	body.Set("sign", sign)
+
+GoRequest:
 	reqXML := generateXml(body)
 	//fmt.Println("reqXML:",reqXML)
 	//===============发起请求===================

+ 22 - 5
wechat_params.go

@@ -31,8 +31,8 @@ func (this *weChatClient) SetCountry(country Country) (client *weChatClient) {
 	return this
 }
 
-//本地通过支付参数计算Sign值
-func getLocalSign(apiKey string, signType string, bm BodyMap) (sign string) {
+//获取微信支付正式环境Sign值
+func getWeChatReleaseSign(apiKey string, signType string, bm BodyMap) (sign string) {
 	signStr := bm.EncodeWeChatSignParams(apiKey)
 	//fmt.Println("signStr:", signStr)
 	var hashSign []byte
@@ -49,15 +49,32 @@ func getLocalSign(apiKey string, signType string, bm BodyMap) (sign string) {
 	return
 }
 
+//获取微信支付沙箱环境Sign值
+func getWeChatSignBoxSign(mchId, apiKey string, bm BodyMap) (sign string, err error) {
+
+	//从微信接口获取SanBox的ApiKey
+	sanBoxApiKey, err := getSanBoxKey(mchId, GetRandomString(32), apiKey, SignType_MD5)
+	if err != nil {
+		return null, err
+	}
+	signStr := bm.EncodeWeChatSignParams(sanBoxApiKey)
+	//fmt.Println("signStr:", signStr)
+	hash := md5.New()
+	hash.Write([]byte(signStr))
+	hashSign := hash.Sum(nil)
+	sign = strings.ToUpper(hex.EncodeToString(hashSign))
+	return sign, nil
+}
+
 //从微信提供的接口获取:SandboxSignKey
-func getSanBoxSign(mchId, nonceStr, apiKey, signType string) (key string, err error) {
+func getSanBoxKey(mchId, nonceStr, apiKey, signType string) (key string, err error) {
 	body := make(BodyMap)
 	body.Set("mch_id", mchId)
 	body.Set("nonce_str", nonceStr)
 
 	//计算沙箱参数Sign
-	sanboxSign := getLocalSign(apiKey, signType, body)
-	//沙箱环境:获取key后,重新计算Sign
+	sanboxSign := getWeChatReleaseSign(apiKey, signType, body)
+	//沙箱环境:获取沙箱环境ApiKey
 	key, err = getSanBoxSignKey(mchId, nonceStr, sanboxSign)
 	if err != nil {
 		return null, err