Jerry 6 年之前
父节点
当前提交
b543cd218d
共有 3 个文件被更改,包括 104 次插入34 次删除
  1. 33 19
      README.md
  2. 51 14
      wechat_client_test.go
  3. 20 1
      wechat_servier_api.go

+ 33 - 19
README.md

@@ -25,6 +25,10 @@
 * 拉取订单评价数据:client.BatchQueryComment()
 
 ## 微信公共API
+
+* gopay.GetMiniPaySign() => 获取微信小程序支付所需要的paySign
+* gopay.GetH5PaySign() => 获取微信内H5支付所需要的paySign
+* gopay.GetAppPaySign() => 获取APP支付所需要的paySign
 * gopay.ParseNotifyResult() => 解析并返回微信支付异步通知的参数
 * gopay.VerifyPayResultSign() => 微信支付异步通知的签名验证和返回参数验签后的Sign
 * gopay.Code2Session() => 登录凭证校验:获取微信用户OpenId、UnionId、SessionKey
@@ -83,7 +87,7 @@ fmt.Println("UnionID:", userIdRsp.Unionid)
 fmt.Println("SessionKey:", userIdRsp.SessionKey)
 ```
 
-### 微信小程序支付,统一下单后,需要进一步获取微信小程序支付所需要的paySign
+### 微信小程序支付,统一下单成功后,需要进一步获取微信小程序支付所需要的paySign
 
 * 小程序支付所需要的参数,paySign由后端计算
     * timeStamp
@@ -92,21 +96,23 @@ fmt.Println("SessionKey:", userIdRsp.SessionKey)
     * signType
     * paySign
 
-> 官方文档说明[微信小程序支付API](https://developers.weixin.qq.com/miniprogram/dev/api/open-api/payment/wx.requestPayment.html)
+> 微信小程序支付官方文档[微信小程序支付API](https://developers.weixin.qq.com/miniprogram/dev/api/open-api/payment/wx.requestPayment.html)
 ```go
 timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
 packages := "prepay_id=" + wxRsp.PrepayId   //此处的 wxRsp.PrepayId ,统一下单成功后得到
-paySign := gopay.GetMiniPaySign("wxd678efh567hg6787", wxRsp.NonceStr, packages, gopay.SignType_MD5, timeStamp, "192006250b4c09247ec02edce69f6a2d")
+//    appId:APPID
+//    nonceStr:随即字符串
+//    prepayId:统一下单成功后得到的值
+//    signType:签名类型
+//    timeStamp:时间
+//    apiKey:API秘钥值
+paySign := gopay.GetMiniPaySign(AppID, wxRsp.NonceStr, packages, gopay.SignType_MD5, timeStamp, ApiKey)
 
 //微信小程序支付需要的参数信息
-fmt.Println("timeStamp:", timeStamp)
-fmt.Println("nonceStr:", wxRsp.NonceStr)
-fmt.Println("package:", packages)
-fmt.Println("signType:", gopay.SignType_MD5)
 fmt.Println("paySign:", paySign)
 ```
 
-### 微信内H5支付,统一下单后,需要进一步获取H5支付所需要的paySign
+### 微信内H5支付,统一下单成功后,需要进一步获取微信内H5支付所需要的paySign
 
 * 微信内H5支付所需要的参数,paySign由后端计算
     * appId
@@ -115,22 +121,23 @@ fmt.Println("paySign:", paySign)
     * package 
     * signType
     * paySign
-> 官方文档说明[微信内H5支付文档](https://pay.weixin.qq.com/wiki/doc/api/external/jsapi.php?chapter=7_7&index=6)
+> 微信内H5支付官方文档[微信内H5支付文档](https://pay.weixin.qq.com/wiki/doc/api/external/jsapi.php?chapter=7_7&index=6)
 ```go
 timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
 packages := "prepay_id=" + wxRsp.PrepayId   //此处的 wxRsp.PrepayId ,统一下单成功后得到
-paySign := gopay.GetH5PaySign("wxd678efh567hg6787", wxRsp.NonceStr, packages, gopay.SignType_MD5, timeStamp, "192006250b4c09247ec02edce69f6a2d")
+//    appId:APPID
+//    nonceStr:随即字符串
+//    prepayId:统一下单成功后得到的值
+//    signType:签名类型
+//    timeStamp:时间
+//    apiKey:API秘钥值
+paySign := gopay.GetH5PaySign(AppID, wxRsp.NonceStr, packages, gopay.SignType_MD5, timeStamp, ApiKey)
 
 //微信内H5支付需要的参数信息
-fmt.Println("appId:","wxd678efh567hg6787")
-fmt.Println("timeStamp:", timeStamp)
-fmt.Println("nonceStr:", wxRsp.NonceStr)
-fmt.Println("package:", packages)
-fmt.Println("signType:", gopay.SignType_MD5)
 fmt.Println("paySign:", paySign)
 ```
 
-### APP支付,统一下单后,需要进一步获取APP支付所需要的paySign
+### APP支付,统一下单成功后,需要进一步获取APP支付所需要的paySign
 
 * APP支付所需要的参数,paySign由后端计算
     * appid
@@ -140,15 +147,22 @@ fmt.Println("paySign:", paySign)
     * package 
     * timestamp
     * sign
-> 官方文档说明[APP端调起支付的参数列表文档](https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12)
+> APP支付官方文档[APP端调起支付的参数列表文档](https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12)
 ```go
 timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
 //注意:signType:此处签名方式,务必与统一下单时用的签名方式一致
 //注意:package:参数因为是固定值,不需开发者再传入
-sign := gopay.GetH5PaySign(appid, partnerid, wxRsp.NonceStr, prepayid, gopay.SignType_MD5, timeStamp, apiKey)
+//    appId:APPID
+//    partnerid:partnerid
+//    nonceStr:随即字符串
+//    prepayId:统一下单成功后得到的值
+//    signType:此处签名方式,务必与统一下单时用的签名方式一致
+//    timeStamp:时间
+//    apiKey:API秘钥值
+paySign := gopay.GetAppPaySign(appid, partnerid, wxRsp.NonceStr, prepayid, gopay.SignType_MD5, timeStamp, apiKey)
 
 //APP支付需要的参数信息
-fmt.Println("sign:", sign)
+fmt.Println("paySign:", paySign)
 ```
 
 ### 1、支付结果异步通知参数解析;2、参数解析和Sign值的验证

+ 51 - 14
wechat_client_test.go

@@ -24,7 +24,7 @@ func TestWeChatClient_UnifiedOrder(t *testing.T) {
 	body.Set("nonce_str", GetRandomString(32))
 	body.Set("body", "测试支付")
 	number := GetRandomString(32)
-	log.Println("Number:", number)
+	fmt.Println("out_trade_no:", number)
 	body.Set("out_trade_no", number)
 	body.Set("total_fee", 10)
 	body.Set("spbill_create_ip", "124.77.173.62")
@@ -39,6 +39,7 @@ func TestWeChatClient_UnifiedOrder(t *testing.T) {
 	wxRsp, err := client.UnifiedOrder(body)
 	if err != nil {
 		fmt.Println("Error:", err)
+		return
 	}
 	fmt.Println("wxRsp:", *wxRsp)
 	timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
@@ -67,8 +68,9 @@ func TestWeChatClient_QueryOrder(t *testing.T) {
 	wxRsp, err := client.QueryOrder(body)
 	if err != nil {
 		fmt.Println("Error:", err)
+		return
 	}
-	fmt.Println("Response:", wxRsp)
+	fmt.Println("wxRsp:", *wxRsp)
 }
 
 func TestWeChatClient_CloseOrder(t *testing.T) {
@@ -85,12 +87,12 @@ func TestWeChatClient_CloseOrder(t *testing.T) {
 	body.Set("nonce_str", GetRandomString(32))
 	body.Set("sign_type", SignType_MD5)
 
-	//请求订单查询,成功后得到结果
+	//请求关闭订单,成功后得到结果
 	wxRsp, err := client.CloseOrder(body)
 	if err != nil {
 		fmt.Println("Error:", err)
 	}
-	fmt.Println("Response:", wxRsp)
+	fmt.Println("wxRsp:", *wxRsp)
 }
 
 func TestWeChatClient_Refund(t *testing.T) {
@@ -120,8 +122,9 @@ func TestWeChatClient_Refund(t *testing.T) {
 	wxRsp, err := client.Refund(body, Cert_iguiyu+"/apiclient_cert.pem", Cert_iguiyu+"/apiclient_key.pem", Cert_iguiyu+"/apiclient_cert.p12")
 	if err != nil {
 		fmt.Println("Error:", err)
+		return
 	}
-	fmt.Println("Response:", wxRsp)
+	fmt.Println("wxRsp:", *wxRsp)
 }
 
 func TestWeChatClient_QueryRefund(t *testing.T) {
@@ -142,8 +145,9 @@ func TestWeChatClient_QueryRefund(t *testing.T) {
 	wxRsp, err := client.QueryRefund(body)
 	if err != nil {
 		fmt.Println("Error:", err)
+		return
 	}
-	fmt.Println("Response:", wxRsp)
+	fmt.Println("wxRsp:", *wxRsp)
 }
 
 func TestWeChatClient_DownloadBill(t *testing.T) {
@@ -161,12 +165,13 @@ func TestWeChatClient_DownloadBill(t *testing.T) {
 	body.Set("bill_date", "20190122")
 	body.Set("bill_type", "ALL")
 
-	//请求订单查询,成功后得到结果
+	//请求下载对账单,成功后得到结果(string类型字符串)
 	wxRsp, err := client.DownloadBill(body)
 	if err != nil {
 		fmt.Println("Error:", err)
+		return
 	}
-	fmt.Println("Response:", wxRsp)
+	fmt.Println("wxRsp:", wxRsp)
 }
 
 func TestWeChatClient_DownloadFundFlow(t *testing.T) {
@@ -175,6 +180,7 @@ func TestWeChatClient_DownloadFundFlow(t *testing.T) {
 	//    MchID:商户ID
 	//    ApiKey:Key值
 	//    isProd:是否是正式环境
+	//    好像不支持沙箱环境,因为沙箱环境默认需要用MD5签名,但是此接口仅支持HMAC-SHA256签名
 	client := NewWeChatClient(AppID, MchID_iguiyu, ApiKey_iguiyu, false)
 
 	//初始化参数结构体
@@ -184,12 +190,13 @@ func TestWeChatClient_DownloadFundFlow(t *testing.T) {
 	body.Set("bill_date", "20190122")
 	body.Set("account_type", "Basic")
 
-	//请求订单查询,成功后得到结果,沙箱环境下,证书路径参数可传空
+	//请求下载资金账单,成功后得到结果,沙箱环境下,证书路径参数可传空
 	wxRsp, err := client.DownloadFundFlow(body, "", "", "")
 	if err != nil {
 		fmt.Println("Error:", err)
+		return
 	}
-	fmt.Println("Response:", wxRsp)
+	fmt.Println("wxRsp:", wxRsp)
 }
 
 func TestWeChatClient_BatchQueryComment(t *testing.T) {
@@ -198,6 +205,7 @@ func TestWeChatClient_BatchQueryComment(t *testing.T) {
 	//    MchID:商户ID
 	//    ApiKey:Key值
 	//    isProd:是否是正式环境
+	//    好像不支持沙箱环境,因为沙箱环境默认需要用MD5签名,但是此接口仅支持HMAC-SHA256签名
 	client := NewWeChatClient(AppID, MchID_iguiyu, ApiKey_iguiyu, false)
 
 	//初始化参数结构体
@@ -208,10 +216,11 @@ func TestWeChatClient_BatchQueryComment(t *testing.T) {
 	body.Set("end_time", "20190122174000")
 	body.Set("offset", "0")
 
-	//请求订单查询,成功后得到结果,沙箱环境下,证书路径参数可传空
+	//请求拉取订单评价数据,成功后得到结果,沙箱环境下,证书路径参数可传空
 	wxRsp, err := client.BatchQueryComment(body, "", "", "")
 	if err != nil {
 		fmt.Println("Error:", err)
+		return
 	}
 	fmt.Println("Response:", wxRsp)
 }
@@ -229,7 +238,7 @@ func TestWeChatClient_Micropay(t *testing.T) {
 	body.Set("nonce_str", GetRandomString(32))
 	body.Set("body", "扫用户付款码支付")
 	number := GetRandomString(32)
-	log.Println("Number:", number)
+	log.Println("out_trade_no:", number)
 	body.Set("out_trade_no", number)
 	body.Set("total_fee", 1)
 	body.Set("spbill_create_ip", "124.77.173.62")
@@ -240,6 +249,7 @@ func TestWeChatClient_Micropay(t *testing.T) {
 	wxRsp, err := client.Micropay(body)
 	if err != nil {
 		fmt.Println("Error:", err)
+		return
 	}
 	fmt.Println("Response:", wxRsp)
 }
@@ -262,6 +272,7 @@ func TestWeChatClient_Reverse(t *testing.T) {
 	wxRsp, err := client.Reverse(body, "", "", "")
 	if err != nil {
 		fmt.Println("Error:", err)
+		return
 	}
 	fmt.Println("Response:", wxRsp)
 }
@@ -276,6 +287,10 @@ func TestMd5(t *testing.T) {
 }
 
 func TestCode2Session(t *testing.T) {
+	//获取微信用户的OpenId、SessionKey、UnionId
+	//    appId:APPID
+	//    appSecret:AppSecret
+	//    wxCode:小程序调用wx.login 获取的code
 	userIdRsp, err := Code2Session(AppID, APPSecret, "011EZg6p0VO47n1p2W4p0mle6p0EZg6u")
 	if err != nil {
 		fmt.Println("err:", err)
@@ -290,6 +305,9 @@ func TestCode2Session(t *testing.T) {
 }
 
 func TestGetAccessToken(t *testing.T) {
+	//获取小程序全局唯一后台接口调用凭据(AccessToken:157字符)
+	//    appId:APPID
+	//    appSecret:AppSecret
 	rsp, err := GetAccessToken(AppID, APPSecret)
 	if err != nil {
 		fmt.Println("err:", err)
@@ -303,6 +321,10 @@ func TestGetAccessToken(t *testing.T) {
 
 func TestGetPaidUnionId(t *testing.T) {
 	accessToken := "21_3puo3mxoK6Ry2bR7Dh-qdn41wUP1wClwke8Zhf9a_i39jfWRq9rhNJZZZHaOt_Yad-Gp6u9_46dGW0RbIMz3nANInRI3m-1glvCnGW47v63sjYWV1iyTKOHGwDVxEv78kY-0OfkmkiIveVqAZCZaAAAQTQ"
+	//用户支付完成后,获取该用户的 UnionId,无需用户授权。
+	//    accessToken:接口调用凭据
+	//    openId:用户的OpenID
+	//    transactionId:微信支付订单号
 	rsp, err := GetPaidUnionId(accessToken, "o0Df70MSI4Ygv2KQ2cLnoMN5CXI8", "4200000326201905256499385970")
 	if err != nil {
 		fmt.Println("err:", err)
@@ -315,12 +337,16 @@ func TestGetPaidUnionId(t *testing.T) {
 
 func TestGetWeChatUserInfo(t *testing.T) {
 	accessToken := "21_3puo3mxoK6Ry2bR7Dh-qdn41wUP1wClwke8Zhf9a_i39jfWRq9rhNJZZZHaOt_Yad-Gp6u9_46dGW0RbIMz3nANInRI3m-1glvCnGW47v63sjYWV1iyTKOHGwDVxEv78kY-0OfkmkiIveVqAZCZaAAAQTQ"
+	//获取用户基本信息(UnionID机制)
+	//    accessToken:接口调用凭据
+	//    openId:用户的OpenID
+	//    lang:默认为 zh_CN ,可选填 zh_CN 简体,zh_TW 繁体,en 英语
 	userInfo, err := GetWeChatUserInfo(accessToken, OpenID)
 	if err != nil {
 		fmt.Println("err:", err)
 		return
 	}
-	fmt.Println("userInfo:", userInfo)
+	fmt.Println("userInfo:", *userInfo)
 }
 
 func TestDecryptOpenDataToStruct(t *testing.T) {
@@ -329,6 +355,11 @@ func TestDecryptOpenDataToStruct(t *testing.T) {
 	session := "lyY4HPQbaOYzZdG+JcYK9w=="
 
 	phone := new(WeChatUserPhone)
+	//解密开放数据
+	//    encryptedData:包括敏感数据在内的完整用户信息的加密数据
+	//    iv:加密算法的初始向量
+	//    sessionKey:会话密钥
+	//    beanPtr:需要解析到的结构体指针
 	err := DecryptOpenDataToStruct(data, iv, session, phone)
 	if err != nil {
 		fmt.Println("err:", err)
@@ -341,7 +372,13 @@ func TestDecryptOpenDataToStruct(t *testing.T) {
 }
 
 func TestGetOpenIdByAuthCode(t *testing.T) {
-	openIdRsp, err := GetOpenIdByAuthCode(AppID, MchID_iguiyu, "135127679952609396", ApiKey_iguiyu, GetRandomString(32))
+	//授权码查询openid
+	//    appId:APPID
+	//    mchId:商户号
+	//    apiKey:ApiKey
+	//    authCode:用户授权码
+	//    nonceStr:随即字符串
+	openIdRsp, err := GetOpenIdByAuthCode(AppID, MchID_iguiyu, ApiKey_iguiyu, "135127679952609396", GetRandomString(32))
 	if err != nil {
 		fmt.Println("err:", err)
 		return

+ 20 - 1
wechat_servier_api.go

@@ -112,6 +112,12 @@ func VerifyPayResultSign(apiKey string, signType string, notifyRsp *WeChatNotify
 }
 
 //JSAPI支付,统一下单获取支付参数后,再次计算出小程序用的paySign
+//    appId:APPID
+//    nonceStr:随即字符串
+//    prepayId:统一下单成功后得到的值
+//    signType:签名类型
+//    timeStamp:时间
+//    apiKey:API秘钥值
 func GetMiniPaySign(appId, nonceStr, prepayId, signType, timeStamp, apiKey string) (paySign string) {
 	buffer := new(bytes.Buffer)
 	buffer.WriteString("appId=")
@@ -149,6 +155,12 @@ func GetMiniPaySign(appId, nonceStr, prepayId, signType, timeStamp, apiKey strin
 }
 
 //JSAPI支付,统一下单获取支付参数后,再次计算出微信内H5支付需要用的paySign
+//    appId:APPID
+//    nonceStr:随即字符串
+//    prepayId:统一下单成功后得到的值
+//    signType:签名类型
+//    timeStamp:时间
+//    apiKey:API秘钥值
 func GetH5PaySign(appId, nonceStr, prepayId, signType, timeStamp, apiKey string) (paySign string) {
 	buffer := new(bytes.Buffer)
 	buffer.WriteString("appId=")
@@ -186,7 +198,13 @@ func GetH5PaySign(appId, nonceStr, prepayId, signType, timeStamp, apiKey string)
 }
 
 //APP支付,统一下单获取支付参数后,再次计算APP支付所需要的的sign
+//    appId:APPID
+//    partnerid:partnerid
+//    nonceStr:随即字符串
+//    prepayId:统一下单成功后得到的值
 //    signType:此处签名方式,务必与统一下单时用的签名方式一致
+//    timeStamp:时间
+//    apiKey:API秘钥值
 func GetAppPaySign(appid, partnerid, noncestr, prepayid, signType, timestamp, apiKey string) (paySign string) {
 	buffer := new(bytes.Buffer)
 	buffer.WriteString("appid=")
@@ -302,9 +320,10 @@ func GetAccessToken(appId, appSecret string) (accessToken *AccessToken, err erro
 //授权码查询openid(AccessToken:157字符)
 //    appId:APPID
 //    mchId:商户号
+//    apiKey:ApiKey
 //    authCode:用户授权码
 //    nonceStr:随即字符串
-func GetOpenIdByAuthCode(appId, mchId, authCode, apiKey, nonceStr string) (openIdRsp *OpenIdByAuthCodeRsp, err error) {
+func GetOpenIdByAuthCode(appId, mchId, apiKey, authCode, nonceStr string) (openIdRsp *OpenIdByAuthCodeRsp, err error) {
 
 	url := "https://api.mch.weixin.qq.com/tools/authcodetoopenid"
 	body := make(BodyMap)