Jerry hace 6 años
padre
commit
6dce59e992
Se han modificado 10 ficheros con 340 adiciones y 259 borrados
  1. 39 3
      alipay_client_test.go
  2. 9 9
      alipay_params.go
  3. 116 116
      alipay_rsp.go
  4. 87 49
      alipay_service_api.go
  5. 15 15
      constant.go
  6. 33 48
      util.go
  7. 2 2
      wechat_client.go
  8. 22 0
      wechat_client_test.go
  9. 13 13
      wechat_rsp.go
  10. 4 4
      wechat_service_api.go

+ 39 - 3
alipay_client_test.go

@@ -30,8 +30,13 @@ func TestJsonToString(t *testing.T) {
 }
 
 type People struct {
-	Name string `json:"name"`
-	Age  int    `json:"age"`
+	Name string `json:"name,omitempty"`
+	Age  int    `json:"age,omitempty"`
+	List []*struct {
+		Address string `json:"address,omitempty"`
+		Age     int    `json:"age,omitempty"`
+		Phone   string `json:"phone,omitempty"`
+	} `json:"list,omitempty"`
 }
 
 func TestAliPayParams(t *testing.T) {
@@ -48,7 +53,7 @@ func TestAliPayParams(t *testing.T) {
 	fmt.Println("result:", bodyMap.Get("people"))
 }
 
-func TestVerifyAliPaySign(t *testing.T) {
+func TestSyncVerifyAliPaySign(t *testing.T) {
 	signData := `{"code":"10000","msg":"Success","buyer_logon_id":"854***@qq.com","buyer_pay_amount":"0.01","buyer_user_id":"2088102363632794","fund_bill_list":[{"amount":"0.01","fund_channel":"PCREDIT"}],"gmt_payment":"2019-08-29 20:14:05","invoice_amount":"0.01","out_trade_no":"GZ201901301040361012","point_amount":"0.00","receipt_amount":"0.01","total_amount":"0.01","trade_no":"2019082922001432790585537960"}`
 	sign := "bk3SzX0CZRI811IJioS2XKQHcgMixUT8mYyGQj+vcOAQas7GIYi6LpykqqSc3m7+yvqoG0TdX/c2JjYnpw/J53JxtC2IC4vsLuIPIgghVo5qafsfSxEJ22w20RZDatI2dYqFVcj8Jp+4aesQ8zMMNw7cX9NLyk7kw3DecYeyQp+zrZMueZPqLh88Z+54G+e6QuSU++0ouqQVd4PkpPqy6YI+8MdMUX4Ve0jOQxMmYH8BC6n5ZsTH/uEaLEtzYVZdSw/xdSQ7K1SH73aEH8XbRYx6rL7RkKksrdvhezX+ThDjQ+fTWjvNFrGcg3fmqXRy2elvoalu+BQmqlkWWjEJYA=="
 	aliPayPublicKey := "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp8gueNlkbiDidz6FBQEBpqoRgH8h7JtsPtYW0nzAqy1MME4mFnDSMfSKlreUomS3a55gmBopL1eF4/Km/dEnaL5tCY9+24SKn1D4iyls+lvz/ZjvUjVwxoUYBh8kkcxMZSDeDz8//o+9qZTrICVP2a4sBB8T0XmU4gxfw8FsmtoomBH1nLk3AO7wgRN2a3+SRSAmxrhIGDmF1lljSlhY32eJpJ2TZQKaWNW+7yDBU/0Wt3kQVY84vr14yYagnSCiIfqyVFqePayRtmVJDr5qvSXr51tdqs2zKZCu+26X7JAF4BSsaq4gmY5DmDTm4TohCnBduI1+bPGD+igVmtl05wIDAQAB"
@@ -59,6 +64,37 @@ func TestVerifyAliPaySign(t *testing.T) {
 	}
 }
 
+func TestVerifyAliPaySign(t *testing.T) {
+	// 测试,假数据,无法验签通过
+	bm := make(BodyMap)
+	bm.Set("sign", "kPbQIjX+xQc8F0/A6/AocELIjhhZnGbcBN6G4MM/HmfWL4ZiHM6fWl5NQhzXJusaklZ1LFuMo+lHQUELAYeugH8LYFvxnNajOvZhuxNFbN2LhF0l/KL8ANtj8oyPM4NN7Qft2kWJTDJUpQOzCzNnV9hDxh5AaT9FPqRS6ZKxnzM=")
+	bm.Set("sign_type", "RSA2")
+	bm.Set("total_amount", "2.00")
+	bm.Set("buyer_id", "2088102116773037")
+	bm.Set("body", "大乐透2.1")
+	bm.Set("trade_no", "2016071921001003030200089909")
+	bm.Set("refund_fee", "0.00")
+	bm.Set("notify_time", "2016-07-19 14:10:49")
+	bm.Set("subject", "大乐透2.1")
+	bm.Set("charset", "utf-8")
+	bm.Set("notify_type", "trade_status_sync")
+	bm.Set("out_trade_no", "0719141034-6418")
+	bm.Set("gmt_close", "2016-07-19 14:10:46")
+	bm.Set("gmt_payment", "2016-07-19 14:10:47")
+	bm.Set("trade_status", "TRADE_SUCCESS")
+	bm.Set("version", "1.0")
+	bm.Set("gmt_create", "2016-07-19 14:10:44")
+	bm.Set("app_id", "2015102700040153")
+	bm.Set("seller_id", "2088102119685838")
+	bm.Set("notify_id", "4a91b7a78a503640467525113fb7d8bg8e")
+
+	ok, err := VerifyAliPaySign("aliPayPublicKey", bm)
+	if err != nil {
+		fmt.Println("err:", err)
+		return
+	}
+	fmt.Println("OK:", ok)
+}
 func TestSubString(t *testing.T) {
 	str := `{"alipay_trade_pay_response":{"code":"10000","msg":"Success","buyer_logon_id":"854***@qq.com","buyer_pay_amount":"0.01","buyer_user_id":"2088102363632794","fund_bill_list":[{"amount":"0.01","fund_channel":"PCREDIT"}],"gmt_payment":"2019-08-29 20:22:02","invoice_amount":"0.01","out_trade_no":"GZ201901301040361013","point_amount":"0.00","receipt_amount":"0.01","total_amount":"0.01","trade_no":"2019082922001432790585666965"},"sign":"DSX/wmE0nnuxQrWfJZtq0fNntcx5UYtVV35P2VZpoTC2KlIWr4eGNiXcetbb7AkI/1Tyd0+cNtcGMgB7SYzTB15/wDE0vJ+eT5ucqhNkER1kcuCC0k9OkZzU5w8wCJzOgAy52Wso9KnrwkY86mJWt3dC8DNCCi1rlf1a8bTGIBG/diJaKAgP1lGT3aW8jeGGM98zLabqDUNvck2qkgctGR49kBb0ZYmIzmY0x5goVyKnaCkcC/d1VTIIMz81mJbeqU8UZk6TqEplCC8J+dYEUj04pAO4/lwIg/YZdKj3Pz1136/+uy669Pew88+74J/u/zPsehC44PxcUk9YKmkNyw=="}`
 

+ 9 - 9
alipay_params.go

@@ -43,26 +43,26 @@ func (a *AliPayClient) SetAppCertSN(appCertSN string) (client *AliPayClient) {
 	return a
 }
 
-//设置 支付宝根证书SN
+// 设置 支付宝根证书SN
 //    alipayRootCertSN:支付宝根证书SN,通过 gopay.GetCertSN() 获取
 func (a *AliPayClient) SetAliPayRootCertSN(alipayRootCertSN string) (client *AliPayClient) {
 	a.AlipayRootCertSN = alipayRootCertSN
 	return a
 }
 
-//设置支付后的ReturnUrl
+// 设置支付后的ReturnUrl
 func (a *AliPayClient) SetReturnUrl(url string) (client *AliPayClient) {
 	a.ReturnUrl = url
 	return a
 }
 
-//设置支付宝服务器主动通知商户服务器里指定的页面http/https路径。
+// 设置支付宝服务器主动通知商户服务器里指定的页面http/https路径。
 func (a *AliPayClient) SetNotifyUrl(url string) (client *AliPayClient) {
 	a.NotifyUrl = url
 	return a
 }
 
-//设置编码格式,如utf-8,gbk,gb2312等,默认推荐使用 utf-8
+// 设置编码格式,如utf-8,gbk,gb2312等,默认推荐使用 utf-8
 func (a *AliPayClient) SetCharset(charset string) (client *AliPayClient) {
 	if charset == null {
 		a.Charset = "utf-8"
@@ -72,7 +72,7 @@ func (a *AliPayClient) SetCharset(charset string) (client *AliPayClient) {
 	return a
 }
 
-//设置签名算法类型,目前支持RSA2和RSA,默认推荐使用 RSA2
+// 设置签名算法类型,目前支持RSA2和RSA,默认推荐使用 RSA2
 func (a *AliPayClient) SetSignType(signType string) (client *AliPayClient) {
 	if signType == null {
 		a.SignType = "RSA2"
@@ -82,19 +82,19 @@ func (a *AliPayClient) SetSignType(signType string) (client *AliPayClient) {
 	return a
 }
 
-//设置应用授权
+// 设置应用授权
 func (a *AliPayClient) SetAppAuthToken(appAuthToken string) (client *AliPayClient) {
 	a.AppAuthToken = appAuthToken
 	return a
 }
 
-//设置用户信息授权
+// 设置用户信息授权
 func (a *AliPayClient) SetAuthToken(authToken string) (client *AliPayClient) {
 	a.AuthToken = authToken
 	return a
 }
 
-//获取参数签名
+// 获取参数签名
 func getRsaSign(bm BodyMap, signType, privateKey string) (sign string, err error) {
 	var (
 		block          *pem.Block
@@ -131,7 +131,7 @@ func getRsaSign(bm BodyMap, signType, privateKey string) (sign string, err error
 	return
 }
 
-//格式化请求URL参数
+// 格式化请求URL参数
 func FormatAliPayURLParam(body BodyMap) (urlParam string) {
 	v := url.Values{}
 	for key, value := range body {

+ 116 - 116
alipay_rsp.go

@@ -1,40 +1,40 @@
 package gopay
 
 type AliPayNotifyRequest struct {
-	NotifyTime        string                  `json:"notify_time,omitempty"`
-	NotifyType        string                  `json:"notify_type,omitempty"`
-	NotifyId          string                  `json:"notify_id,omitempty"`
-	AppId             string                  `json:"app_id,omitempty"`
-	Charset           string                  `json:"charset,omitempty"`
-	Version           string                  `json:"version,omitempty"`
-	SignType          string                  `json:"sign_type,omitempty"`
-	Sign              string                  `json:"sign,omitempty"`
-	AuthAppId         string                  `json:"auth_app_id,omitempty"`
-	TradeNo           string                  `json:"trade_no,omitempty"`
-	OutTradeNo        string                  `json:"out_trade_no,omitempty"`
-	OutBizNo          string                  `json:"out_biz_no,omitempty"`
-	BuyerId           string                  `json:"buyer_id,omitempty"`
-	BuyerLogonId      string                  `json:"buyer_logon_id,omitempty"`
-	SellerId          string                  `json:"seller_id,omitempty"`
-	SellerEmail       string                  `json:"seller_email,omitempty"`
-	TradeStatus       string                  `json:"trade_status,omitempty"`
-	TotalAmount       string                  `json:"total_amount,omitempty"`
-	ReceiptAmount     string                  `json:"receipt_amount,omitempty"`
-	InvoiceAmount     string                  `json:"invoice_amount,omitempty"`
-	BuyerPayAmount    string                  `json:"buyer_pay_amount,omitempty"`
-	PointAmount       string                  `json:"point_amount,omitempty"`
-	RefundFee         string                  `json:"refund_fee,omitempty"`
-	Subject           string                  `json:"subject,omitempty"`
-	Body              string                  `json:"body,omitempty"`
-	GmtCreate         string                  `json:"gmt_create,omitempty"`
-	GmtPayment        string                  `json:"gmt_payment,omitempty"`
-	GmtRefund         string                  `json:"gmt_refund,omitempty"`
-	GmtClose          string                  `json:"gmt_close,omitempty"`
-	FundBillList      []fundBillListInfo      `json:"fund_bill_list,omitempty"`
-	PassbackParams    string                  `json:"passback_params,omitempty"`
-	VoucherDetailList []voucherDetailListInfo `json:"voucher_detail_list,omitempty"`
-	Method            string                  `json:"method,omitempty"`    //电脑网站支付 支付宝请求 return_url 同步返回参数
-	Timestamp         string                  `json:"timestamp,omitempty"` //电脑网站支付 支付宝请求 return_url 同步返回参数
+	NotifyTime        string                   `json:"notify_time,omitempty"`
+	NotifyType        string                   `json:"notify_type,omitempty"`
+	NotifyId          string                   `json:"notify_id,omitempty"`
+	AppId             string                   `json:"app_id,omitempty"`
+	Charset           string                   `json:"charset,omitempty"`
+	Version           string                   `json:"version,omitempty"`
+	SignType          string                   `json:"sign_type,omitempty"`
+	Sign              string                   `json:"sign,omitempty"`
+	AuthAppId         string                   `json:"auth_app_id,omitempty"`
+	TradeNo           string                   `json:"trade_no,omitempty"`
+	OutTradeNo        string                   `json:"out_trade_no,omitempty"`
+	OutBizNo          string                   `json:"out_biz_no,omitempty"`
+	BuyerId           string                   `json:"buyer_id,omitempty"`
+	BuyerLogonId      string                   `json:"buyer_logon_id,omitempty"`
+	SellerId          string                   `json:"seller_id,omitempty"`
+	SellerEmail       string                   `json:"seller_email,omitempty"`
+	TradeStatus       string                   `json:"trade_status,omitempty"`
+	TotalAmount       string                   `json:"total_amount,omitempty"`
+	ReceiptAmount     string                   `json:"receipt_amount,omitempty"`
+	InvoiceAmount     string                   `json:"invoice_amount,omitempty"`
+	BuyerPayAmount    string                   `json:"buyer_pay_amount,omitempty"`
+	PointAmount       string                   `json:"point_amount,omitempty"`
+	RefundFee         string                   `json:"refund_fee,omitempty"`
+	Subject           string                   `json:"subject,omitempty"`
+	Body              string                   `json:"body,omitempty"`
+	GmtCreate         string                   `json:"gmt_create,omitempty"`
+	GmtPayment        string                   `json:"gmt_payment,omitempty"`
+	GmtRefund         string                   `json:"gmt_refund,omitempty"`
+	GmtClose          string                   `json:"gmt_close,omitempty"`
+	FundBillList      []*fundBillListInfo      `json:"fund_bill_list,omitempty"`
+	PassbackParams    string                   `json:"passback_params,omitempty"`
+	VoucherDetailList []*voucherDetailListInfo `json:"voucher_detail_list,omitempty"`
+	Method            string                   `json:"method,omitempty"`    //电脑网站支付 支付宝请求 return_url 同步返回参数
+	Timestamp         string                   `json:"timestamp,omitempty"` //电脑网站支付 支付宝请求 return_url 同步返回参数
 }
 
 type fundBillListInfo struct {
@@ -68,9 +68,9 @@ type AliPayUserPhone struct {
 
 //===================================================
 type AliPayTradePayResponse struct {
-	Response payResponse `json:"alipay_trade_pay_response,omitempty"`
-	SignData string      `json:"-"`
-	Sign     string      `json:"sign"`
+	Response *payResponse `json:"alipay_trade_pay_response,omitempty"`
+	SignData string       `json:"-"`
+	Sign     string       `json:"sign"`
 }
 
 type payResponse struct {
@@ -94,7 +94,7 @@ type payResponse struct {
 	PointAmount     string `json:"point_amount,omitempty"`
 	InvoiceAmount   string `json:"invoice_amount,omitempty"`
 	GmtPayment      string `json:"gmt_payment,omitempty"`
-	FundBillList    []struct {
+	FundBillList    []*struct {
 		FundChannel string `json:"fund_channel,omitempty"`
 		BankCode    string `json:"bank_code,omitempty"`
 		Amount      string `json:"amount,omitempty"`
@@ -104,7 +104,7 @@ type payResponse struct {
 	StoreName           string `json:"store_name,omitempty"`
 	BuyerUserId         string `json:"buyer_user_id,omitempty"`
 	DiscountGoodsDetail string `json:"discount_goods_detail,omitempty"`
-	VoucherDetailList   []struct {
+	VoucherDetailList   []*struct {
 		Id                         string `json:"id,omitempty"`
 		Name                       string `json:"name,omitempty"`
 		Type                       string `json:"type,omitempty"`
@@ -131,9 +131,9 @@ type payResponse struct {
 
 //===================================================
 type AliPayTradeQueryResponse struct {
-	Response queryResponse `json:"alipay_trade_query_response,omitempty"`
-	SignData string        `json:"-"`
-	Sign     string        `json:"sign"`
+	Response *queryResponse `json:"alipay_trade_query_response,omitempty"`
+	SignData string         `json:"-"`
+	Sign     string         `json:"sign"`
 }
 
 type queryResponse struct {
@@ -160,7 +160,7 @@ type queryResponse struct {
 	ReceiptAmount   string `json:"receipt_amount,omitempty"`
 	StoreId         string `json:"store_id,omitempty"`
 	TerminalId      string `json:"terminal_id,omitempty"`
-	FundBillList    []struct {
+	FundBillList    []*struct {
 		FundChannel string `json:"fund_channel,omitempty"`
 		BankCode    string `json:"bank_code,omitempty"`
 		Amount      string `json:"amount,omitempty"`
@@ -171,8 +171,8 @@ type queryResponse struct {
 	ChargeAmount    string `json:"charge_amount,omitempty"`
 	ChargeFlags     string `json:"charge_flags,omitempty"`
 	SettlementId    string `json:"settlement_id,omitempty"`
-	TradeSettleInfo struct {
-		TradeSettleDetailList []struct {
+	TradeSettleInfo *struct {
+		TradeSettleDetailList []*struct {
 			OperationType     string `json:"operation_type,omitempty"`
 			OperationSerialNo string `json:"operation_serial_no,omitempty"`
 			OperationDt       string `json:"operation_dt,omitempty"`
@@ -194,9 +194,9 @@ type queryResponse struct {
 
 //===================================================
 type AliPayTradeCreateResponse struct {
-	Response createResponse `json:"alipay_trade_create_response,omitempty"`
-	SignData string         `json:"-"`
-	Sign     string         `json:"sign"`
+	Response *createResponse `json:"alipay_trade_create_response,omitempty"`
+	SignData string          `json:"-"`
+	Sign     string          `json:"sign"`
 }
 
 type createResponse struct {
@@ -210,9 +210,9 @@ type createResponse struct {
 
 //===================================================
 type AliPayTradeCloseResponse struct {
-	Response closeResponse `json:"alipay_trade_close_response,omitempty"`
-	SignData string        `json:"-"`
-	Sign     string        `json:"sign"`
+	Response *closeResponse `json:"alipay_trade_close_response,omitempty"`
+	SignData string         `json:"-"`
+	Sign     string         `json:"sign"`
 }
 
 type closeResponse struct {
@@ -226,9 +226,9 @@ type closeResponse struct {
 
 //===================================================
 type AliPayTradeCancelResponse struct {
-	Response cancelResponse `json:"alipay_trade_cancel_response,omitempty"`
-	SignData string         `json:"-"`
-	Sign     string         `json:"sign"`
+	Response *cancelResponse `json:"alipay_trade_cancel_response,omitempty"`
+	SignData string          `json:"-"`
+	Sign     string          `json:"sign"`
 }
 
 type cancelResponse struct {
@@ -246,8 +246,8 @@ type cancelResponse struct {
 
 //===================================================
 type AliPaySystemOauthTokenResponse struct {
-	Response      oauthTokenInfo `json:"alipay_system_oauth_token_response,omitempty"`
-	ErrorResponse struct {
+	Response      *oauthTokenInfo `json:"alipay_system_oauth_token_response,omitempty"`
+	ErrorResponse *struct {
 		Code    string `json:"code,omitempty"`
 		Msg     string `json:"msg,omitempty"`
 		SubCode string `json:"sub_code,omitempty"`
@@ -267,9 +267,9 @@ type oauthTokenInfo struct {
 
 //===================================================
 type AlipayUserInfoShareResponse struct {
-	Response userInfoShare `json:"alipay_user_info_share_response,omitempty"`
-	SignData string        `json:"-"`
-	Sign     string        `json:"sign"`
+	Response *userInfoShare `json:"alipay_user_info_share_response,omitempty"`
+	SignData string         `json:"-"`
+	Sign     string         `json:"sign"`
 }
 
 type userInfoShare struct {
@@ -291,27 +291,27 @@ type userInfoShare struct {
 
 //===================================================
 type AliPayTradeRefundResponse struct {
-	Response refundResponse `json:"alipay_trade_refund_response,omitempty"`
-	SignData string         `json:"-"`
-	Sign     string         `json:"sign"`
+	Response *refundResponse `json:"alipay_trade_refund_response,omitempty"`
+	SignData string          `json:"-"`
+	Sign     string          `json:"sign"`
 }
 
 type refundResponse struct {
-	Code                    string          `json:"code,omitempty"`
-	Msg                     string          `json:"msg,omitempty"`
-	SubCode                 string          `json:"sub_code,omitempty"`
-	SubMsg                  string          `json:"sub_msg,omitempty"`
-	TradeNo                 string          `json:"trade_no,omitempty"`
-	OutTradeNo              string          `json:"out_trade_no,omitempty"`
-	BuyerLogonId            string          `json:"buyer_logon_id,omitempty"`
-	FundChange              string          `json:"fund_change,omitempty"`
-	RefundFee               string          `json:"refund_fee,omitempty"`
-	RefundCurrency          string          `json:"refund_currency,omitempty"`
-	GmtRefundPay            string          `json:"gmt_refund_pay,omitempty"`
-	RefundDetailItemList    []tradeFundBill `json:"refund_detail_item_list,omitempty"`
-	StoreName               string          `json:"store_name,omitempty"`
-	BuyerUserId             string          `json:"buyer_user_id,omitempty"`
-	RefundPresetPaytoolList []struct {
+	Code                    string           `json:"code,omitempty"`
+	Msg                     string           `json:"msg,omitempty"`
+	SubCode                 string           `json:"sub_code,omitempty"`
+	SubMsg                  string           `json:"sub_msg,omitempty"`
+	TradeNo                 string           `json:"trade_no,omitempty"`
+	OutTradeNo              string           `json:"out_trade_no,omitempty"`
+	BuyerLogonId            string           `json:"buyer_logon_id,omitempty"`
+	FundChange              string           `json:"fund_change,omitempty"`
+	RefundFee               string           `json:"refund_fee,omitempty"`
+	RefundCurrency          string           `json:"refund_currency,omitempty"`
+	GmtRefundPay            string           `json:"gmt_refund_pay,omitempty"`
+	RefundDetailItemList    []*tradeFundBill `json:"refund_detail_item_list,omitempty"`
+	StoreName               string           `json:"store_name,omitempty"`
+	BuyerUserId             string           `json:"buyer_user_id,omitempty"`
+	RefundPresetPaytoolList []*struct {
 		Amount         []string `json:"amount,omitempty"`
 		AssertTypeCode string   `json:"assert_type_code,omitempty"`
 	} `json:"refund_preset_paytool_list,omitempty"`
@@ -331,9 +331,9 @@ type tradeFundBill struct {
 
 //===================================================
 type AliPayTradeFastpayRefundQueryResponse struct {
-	Response refundQueryResponse `json:"alipay_trade_fastpay_refund_query_response,omitempty"`
-	SignData string              `json:"-"`
-	Sign     string              `json:"sign"`
+	Response *refundQueryResponse `json:"alipay_trade_fastpay_refund_query_response,omitempty"`
+	SignData string               `json:"-"`
+	Sign     string               `json:"sign"`
 }
 
 type refundQueryResponse struct {
@@ -347,7 +347,7 @@ type refundQueryResponse struct {
 	RefundReason   string `json:"refund_reason,omitempty"`
 	TotalAmount    string `json:"total_amount,omitempty"`
 	RefundAmount   string `json:"refund_amount,omitempty"`
-	RefundRoyaltys []struct {
+	RefundRoyaltys []*struct {
 		RefundAmount  string `json:"refund_amount,omitempty"`
 		RoyaltyType   string `json:"royalty_type,omitempty"`
 		ResultCode    string `json:"result_code,omitempty"`
@@ -356,20 +356,20 @@ type refundQueryResponse struct {
 		TransIn       string `json:"trans_in,omitempty"`
 		TransInEmail  string `json:"trans_in_email,omitempty"`
 	} `json:"refund_royaltys,omitempty"`
-	GmtRefundPay                 string          `json:"gmt_refund_pay,omitempty"`
-	RefundDetailItemList         []tradeFundBill `json:"refund_detail_item_list,omitempty"`
-	SendBackFee                  string          `json:"send_back_fee,omitempty"`
-	RefundSettlementId           string          `json:"refund_settlement_id,omitempty"`
-	PresentRefundBuyerAmount     string          `json:"present_refund_buyer_amount,omitempty"`
-	PresentRefundDiscountAmount  string          `json:"present_refund_discount_amount,omitempty"`
-	PresentRefundMdiscountAmount string          `json:"present_refund_mdiscount_amount,omitempty"`
+	GmtRefundPay                 string           `json:"gmt_refund_pay,omitempty"`
+	RefundDetailItemList         []*tradeFundBill `json:"refund_detail_item_list,omitempty"`
+	SendBackFee                  string           `json:"send_back_fee,omitempty"`
+	RefundSettlementId           string           `json:"refund_settlement_id,omitempty"`
+	PresentRefundBuyerAmount     string           `json:"present_refund_buyer_amount,omitempty"`
+	PresentRefundDiscountAmount  string           `json:"present_refund_discount_amount,omitempty"`
+	PresentRefundMdiscountAmount string           `json:"present_refund_mdiscount_amount,omitempty"`
 }
 
 //===================================================
 type AliPayTradeOrderSettleResponse struct {
-	Response orderSettleResponse `json:"alipay_trade_order_settle_response,omitempty"`
-	SignData string              `json:"-"`
-	Sign     string              `json:"sign"`
+	Response *orderSettleResponse `json:"alipay_trade_order_settle_response,omitempty"`
+	SignData string               `json:"-"`
+	Sign     string               `json:"sign"`
 }
 type orderSettleResponse struct {
 	Code    string `json:"code,omitempty"`
@@ -381,9 +381,9 @@ type orderSettleResponse struct {
 
 //===================================================
 type AlipayTradePrecreateResponse struct {
-	Response precreateResponse `json:"alipay_trade_precreate_response,omitempty"`
-	SignData string            `json:"-"`
-	Sign     string            `json:"sign"`
+	Response *precreateResponse `json:"alipay_trade_precreate_response,omitempty"`
+	SignData string             `json:"-"`
+	Sign     string             `json:"sign"`
 }
 
 type precreateResponse struct {
@@ -397,9 +397,9 @@ type precreateResponse struct {
 
 //===================================================
 type AliPayTradePageRefundResponse struct {
-	Response pageRefundResponse `json:"alipay_trade_page_refund_response,omitempty"`
-	SignData string             `json:"-"`
-	Sign     string             `json:"sign"`
+	Response *pageRefundResponse `json:"alipay_trade_page_refund_response,omitempty"`
+	SignData string              `json:"-"`
+	Sign     string              `json:"sign"`
 }
 
 type pageRefundResponse struct {
@@ -415,9 +415,9 @@ type pageRefundResponse struct {
 
 //===================================================
 type AlipayFundTransToaccountTransferResponse struct {
-	Response transToaccountTransferResponse `json:"alipay_fund_trans_toaccount_transfer_response,omitempty"`
-	SignData string                         `json:"-"`
-	Sign     string                         `json:"sign"`
+	Response *transToaccountTransferResponse `json:"alipay_fund_trans_toaccount_transfer_response,omitempty"`
+	SignData string                          `json:"-"`
+	Sign     string                          `json:"sign"`
 }
 
 type transToaccountTransferResponse struct {
@@ -432,9 +432,9 @@ type transToaccountTransferResponse struct {
 
 //===================================================
 type ZhimaCreditScoreGetResponse struct {
-	Response scoreGetResponse `json:"zhima_credit_score_get_response,omitempty"`
-	SignData string           `json:"-"`
-	Sign     string           `json:"sign"`
+	Response *scoreGetResponse `json:"zhima_credit_score_get_response,omitempty"`
+	SignData string            `json:"-"`
+	Sign     string            `json:"sign"`
 }
 
 type scoreGetResponse struct {
@@ -448,9 +448,9 @@ type scoreGetResponse struct {
 
 //===================================================
 type AliPayOpenAuthTokenAppResponse struct {
-	Response authTokenAppResponse `json:"alipay_open_auth_token_app_response,omitempty"`
-	SignData string               `json:"-"`
-	Sign     string               `json:"sign"`
+	Response *authTokenAppResponse `json:"alipay_open_auth_token_app_response,omitempty"`
+	SignData string                `json:"-"`
+	Sign     string                `json:"sign"`
 }
 
 type authTokenAppResponse struct {
@@ -464,7 +464,7 @@ type authTokenAppResponse struct {
 	AppRefreshToken string `json:"app_refresh_token,omitempty"`
 	ExpiresIn       int    `json:"expires_in,omitempty"`
 	ReExpiresIn     int    `json:"re_expires_in,omitempty"`
-	Tokens          []struct {
+	Tokens          []*struct {
 		AppAuthToken    string `json:"app_auth_token,omitempty"`
 		AppRefreshToken string `json:"app_refresh_token,omitempty"`
 		AuthAppId       string `json:"auth_app_id,omitempty"`
@@ -476,9 +476,9 @@ type authTokenAppResponse struct {
 
 //===================================================
 type AliPayUserCertifyOpenInitResponse struct {
-	Response userCertifyOpenInitResponse `json:"alipay_user_certify_open_initialize_response,omitempty"`
-	SignData string                      `json:"-"`
-	Sign     string                      `json:"sign"`
+	Response *userCertifyOpenInitResponse `json:"alipay_user_certify_open_initialize_response,omitempty"`
+	SignData string                       `json:"-"`
+	Sign     string                       `json:"sign"`
 }
 
 type userCertifyOpenInitResponse struct {
@@ -491,9 +491,9 @@ type userCertifyOpenInitResponse struct {
 
 //===================================================
 type AliPayUserCertifyOpenCertifyResponse struct {
-	Response userCertifyOpenCertifyResponse `json:"alipay_user_certify_open_certify_response,omitempty"`
-	SignData string                         `json:"-"`
-	Sign     string                         `json:"sign"`
+	Response *userCertifyOpenCertifyResponse `json:"alipay_user_certify_open_certify_response,omitempty"`
+	SignData string                          `json:"-"`
+	Sign     string                          `json:"sign"`
 }
 
 type userCertifyOpenCertifyResponse struct {
@@ -505,9 +505,9 @@ type userCertifyOpenCertifyResponse struct {
 
 //===================================================
 type AliPayUserCertifyOpenQueryResponse struct {
-	Response userCertifyOpenQueryResponse `json:"alipay_user_certify_open_query_response,omitempty"`
-	SignData string                       `json:"-"`
-	Sign     string                       `json:"sign"`
+	Response *userCertifyOpenQueryResponse `json:"alipay_user_certify_open_query_response,omitempty"`
+	SignData string                        `json:"-"`
+	Sign     string                        `json:"sign"`
 }
 
 type userCertifyOpenQueryResponse struct {

+ 87 - 49
alipay_service_api.go

@@ -22,7 +22,7 @@ import (
 )
 
 // 允许进行 sn 提取的证书签名算法
-var allowSignatureAlgorithm map[string]bool = map[string]bool{
+var allowSignatureAlgorithm = map[string]bool{
 	"MD2-RSA":       true,
 	"MD5-RSA":       true,
 	"SHA1-RSA":      true,
@@ -34,54 +34,82 @@ var allowSignatureAlgorithm map[string]bool = map[string]bool{
 	"SHA512-RSAPSS": true,
 }
 
+// 解析支付宝支付异步通知的结果到BodyMap
+//    req:*http.Request
+//    返回参数bm:Notify请求的参数
+//    返回参数err:错误信息
+//    文档:https://docs.open.alipay.com/203/105286/
+func ParseAliPayNotifyResultToBodyMap(req *http.Request) (bm BodyMap, err error) {
+	if err = req.ParseForm(); err != nil {
+		return nil, err
+	}
+	var form map[string][]string = req.Form
+	bm = make(BodyMap, len(form))
+	for k, v := range form {
+		if len(v) == 1 {
+			bm.Set(k, v[0])
+		}
+	}
+	return
+}
+
 // ParseAliPayNotifyResult 解析支付宝支付完成后的Notify信息
+//    req:*http.Request
+//    返回参数notifyReq:Notify请求的参数
+//    返回参数err:错误信息
+//    文档:https://docs.open.alipay.com/203/105286/
 func ParseAliPayNotifyResult(req *http.Request) (notifyReq *AliPayNotifyRequest, err error) {
 	notifyReq = new(AliPayNotifyRequest)
-	notifyReq.NotifyTime = req.FormValue("notify_time")
-	notifyReq.NotifyType = req.FormValue("notify_type")
-	notifyReq.NotifyId = req.FormValue("notify_id")
-	notifyReq.AppId = req.FormValue("app_id")
-	notifyReq.Charset = req.FormValue("charset")
-	notifyReq.Version = req.FormValue("version")
-	notifyReq.SignType = req.FormValue("sign_type")
-	notifyReq.Sign = req.FormValue("sign")
-	notifyReq.AuthAppId = req.FormValue("auth_app_id")
-	notifyReq.TradeNo = req.FormValue("trade_no")
-	notifyReq.OutTradeNo = req.FormValue("out_trade_no")
-	notifyReq.OutBizNo = req.FormValue("out_biz_no")
-	notifyReq.BuyerId = req.FormValue("buyer_id")
-	notifyReq.BuyerLogonId = req.FormValue("buyer_logon_id")
-	notifyReq.SellerId = req.FormValue("seller_id")
-	notifyReq.SellerEmail = req.FormValue("seller_email")
-	notifyReq.TradeStatus = req.FormValue("trade_status")
-	notifyReq.TotalAmount = req.FormValue("total_amount")
-	notifyReq.ReceiptAmount = req.FormValue("receipt_amount")
-	notifyReq.InvoiceAmount = req.FormValue("invoice_amount")
-	notifyReq.BuyerPayAmount = req.FormValue("buyer_pay_amount")
-	notifyReq.PointAmount = req.FormValue("point_amount")
-	notifyReq.RefundFee = req.FormValue("refund_fee")
-	notifyReq.Subject = req.FormValue("subject")
-	notifyReq.Body = req.FormValue("body")
-	notifyReq.GmtCreate = req.FormValue("gmt_create")
-	notifyReq.GmtPayment = req.FormValue("gmt_payment")
-	notifyReq.GmtRefund = req.FormValue("gmt_refund")
-	notifyReq.GmtClose = req.FormValue("gmt_close")
-	billList := req.FormValue("fund_bill_list")
+	if err = req.ParseForm(); err != nil {
+		return
+	}
+	notifyReq.NotifyTime = req.Form.Get("notify_time")
+	notifyReq.NotifyType = req.Form.Get("notify_type")
+	notifyReq.NotifyId = req.Form.Get("notify_id")
+	notifyReq.AppId = req.Form.Get("app_id")
+	notifyReq.Charset = req.Form.Get("charset")
+	notifyReq.Version = req.Form.Get("version")
+	notifyReq.SignType = req.Form.Get("sign_type")
+	notifyReq.Sign = req.Form.Get("sign")
+	notifyReq.AuthAppId = req.Form.Get("auth_app_id")
+	notifyReq.TradeNo = req.Form.Get("trade_no")
+	notifyReq.OutTradeNo = req.Form.Get("out_trade_no")
+	notifyReq.OutBizNo = req.Form.Get("out_biz_no")
+	notifyReq.BuyerId = req.Form.Get("buyer_id")
+	notifyReq.BuyerLogonId = req.Form.Get("buyer_logon_id")
+	notifyReq.SellerId = req.Form.Get("seller_id")
+	notifyReq.SellerEmail = req.Form.Get("seller_email")
+	notifyReq.TradeStatus = req.Form.Get("trade_status")
+	notifyReq.TotalAmount = req.Form.Get("total_amount")
+	notifyReq.ReceiptAmount = req.Form.Get("receipt_amount")
+	notifyReq.InvoiceAmount = req.Form.Get("invoice_amount")
+	notifyReq.BuyerPayAmount = req.Form.Get("buyer_pay_amount")
+	notifyReq.PointAmount = req.Form.Get("point_amount")
+	notifyReq.RefundFee = req.Form.Get("refund_fee")
+	notifyReq.Subject = req.Form.Get("subject")
+	notifyReq.Body = req.Form.Get("body")
+	notifyReq.GmtCreate = req.Form.Get("gmt_create")
+	notifyReq.GmtPayment = req.Form.Get("gmt_payment")
+	notifyReq.GmtRefund = req.Form.Get("gmt_refund")
+	notifyReq.GmtClose = req.Form.Get("gmt_close")
+	notifyReq.PassbackParams = req.Form.Get("passback_params")
+
+	billList := req.Form.Get("fund_bill_list")
 	if billList != null {
-		bills := make([]fundBillListInfo, 0)
+		bills := make([]*fundBillListInfo, 0)
 		if err = json.Unmarshal([]byte(billList), &bills); err != nil {
-			return nil, fmt.Errorf("xml.Unmarshal:%s", err.Error())
+			return nil, fmt.Errorf(`"fund_bill_list" xml.Unmarshal:%s`, err.Error())
 		}
 		notifyReq.FundBillList = bills
 	} else {
 		notifyReq.FundBillList = nil
 	}
-	notifyReq.PassbackParams = req.FormValue("passback_params")
-	detailList := req.FormValue("voucher_detail_list")
+
+	detailList := req.Form.Get("voucher_detail_list")
 	if detailList != null {
-		details := make([]voucherDetailListInfo, 0)
+		details := make([]*voucherDetailListInfo, 0)
 		if err = json.Unmarshal([]byte(detailList), &details); err != nil {
-			return nil, fmt.Errorf("xml.Unmarshal:%s", err.Error())
+			return nil, fmt.Errorf(`"voucher_detail_list" xml.Unmarshal:%s`, err.Error())
 		}
 		notifyReq.VoucherDetailList = details
 	} else {
@@ -109,7 +137,7 @@ A:开发者上传自己的应用公钥证书后,开放平台会为开发者
 // VerifyAliPaySign 支付宝同步返回验签或异步通知验签
 //    注意:APP支付,手机网站支付,电脑网站支付 暂不支持同步返回验签
 //    aliPayPublicKey:支付宝公钥
-//    bean: 同步返回验签时,此参数为 aliRsp.SignData ;异步通知验签时,此参数为异步通知解析的结构体 notifyReq
+//    bean: 同步返回验签时,此参数为字符串 aliRsp.SignData ;异步通知验签时,此参数为异步通知解析的结构体或BodyMap:notifyReq 或 bm
 //    syncSign:同步返回验签时,此参数必传,即:aliRsp.Sign ;异步通知验签时,不传此参数,否则会出错。
 //    返回参数ok:是否验签通过
 //    返回参数err:错误信息
@@ -132,18 +160,28 @@ func VerifyAliPaySign(aliPayPublicKey string, bean interface{}, syncSign ...stri
 		signData = bean.(string)
 		goto Verify
 	}
-	if bs, err = json.Marshal(bean); err != nil {
-		return false, fmt.Errorf("json.Marshal:%s", err.Error())
-	}
 	bm = make(BodyMap)
-	if err = json.Unmarshal(bs, &bm); err != nil {
-		return false, fmt.Errorf("json.Unmarshal:%s", err.Error())
-	}
-	bodySign = bm.Get("sign")
-	bodySignType = bm.Get("sign_type")
-	bm.Remove("sign")
-	bm.Remove("sign_type")
-	signData = bm.EncodeAliPaySignParams()
+	if reflect.ValueOf(bean).Kind() == reflect.Map {
+		if bm, ok = bean.(BodyMap); ok {
+			bodySign = bm.Get("sign")
+			bodySignType = bm.Get("sign_type")
+			bm.Remove("sign")
+			bm.Remove("sign_type")
+			signData = bm.EncodeAliPaySignParams()
+		}
+	} else {
+		if bs, err = json.Marshal(bean); err != nil {
+			return false, fmt.Errorf("json.Marshal:%s", err.Error())
+		}
+		if err = json.Unmarshal(bs, &bm); err != nil {
+			return false, fmt.Errorf("json.Unmarshal:%s", err.Error())
+		}
+		bodySign = bm.Get("sign")
+		bodySignType = bm.Get("sign_type")
+		bm.Remove("sign")
+		bm.Remove("sign_type")
+		signData = bm.EncodeAliPaySignParams()
+	}
 Verify:
 	pKey = FormatAliPayPublicKey(aliPayPublicKey)
 	if err = verifyAliPaySign(signData, bodySign, bodySignType, pKey); err != nil {

+ 15 - 15
constant.go

@@ -5,22 +5,22 @@ const (
 	TimeLayout string = "2006-01-02 15:04:05"
 	DateLayout string = "2006-01-02"
 	Version    string = "1.4.3"
-	//微信
-	//===========================================================================================
+	// 微信
+	// ===========================================================================================
 
-	//境外国家地区
-	China         Country = 1 //中国国内
-	China2        Country = 2 //中国国内(冗灾方案)
-	SoutheastAsia Country = 3 //东南亚
-	Other         Country = 4 //其他国家
+	// 境外国家地区
+	China         Country = 1 // 中国国内
+	China2        Country = 2 // 中国国内(冗灾方案)
+	SoutheastAsia Country = 3 // 东南亚
+	Other         Country = 4 // 其他国家
 
-	//URL
+	// URL
 	wxBaseUrlCh  = "https://api.mch.weixin.qq.com/"   //中国国内
 	wxBaseUrlCh2 = "https://api2.mch.weixin.qq.com/"  //中国国内
 	wxBaseUrlHk  = "https://apihk.mch.weixin.qq.com/" //东南亚
 	wxBaseUrlUs  = "https://apius.mch.weixin.qq.com/" //其他
 
-	//正式
+	// 正式
 	wxMicropay          = "pay/micropay"                          //提交付款码支付
 	wxUnifiedorder      = "pay/unifiedorder"                      //统一下单
 	wxOrderquery        = "pay/orderquery"                        //查询订单
@@ -40,7 +40,7 @@ const (
 	wxEntrustApplyPay   = "pay/pappayapply"                       //申请扣款
 	wxEntrustQueryOrder = "pay/paporderquery"                     //查询扣款订单
 
-	//SanBox
+	// SanBox
 	wxSandboxGetsignkey        = "https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey"
 	wxSandboxMicropay          = "sandboxnew/pay/micropay"
 	wxSandboxUnifiedorder      = "sandboxnew/pay/unifiedorder"
@@ -53,21 +53,21 @@ const (
 	wxSandboxDownloadfundflow  = "sandboxnew/pay/downloadfundflow"
 	wxSandboxBatchquerycomment = "sandboxnew/billcommentsp/batchquerycomment"
 
-	//支付类型
+	// 支付类型
 	TradeType_Mini   = "JSAPI"
 	TradeType_JsApi  = "JSAPI"
 	TradeType_App    = "APP"
 	TradeType_H5     = "MWEB"
 	TradeType_Native = "NATIVE"
 
-	//签名方式
+	// 签名方式
 	SignType_MD5         = "MD5"
 	SignType_HMAC_SHA256 = "HMAC-SHA256"
 
-	//支付宝
-	//===========================================================================================
+	// 支付宝
+	// ==========================================================================================
 
-	//URL
+	// URL
 	zfbBaseUrl            = "https://openapi.alipay.com/gateway.do"
 	zfbSandboxBaseUrl     = "https://openapi.alipaydev.com/gateway.do"
 	zfbBaseUrlUtf8        = "https://openapi.alipay.com/gateway.do?charset=utf-8"

+ 33 - 48
util.go

@@ -17,29 +17,12 @@ import (
 
 type BodyMap map[string]interface{}
 
-//设置参数
-//    value:仅支持类型 string,int,int64,float32,float64,ptr,struct,slice,map 类型,其他类型一律设置空字符串
+// 设置参数
 func (bm BodyMap) Set(key string, value interface{}) {
-	vKind := reflect.ValueOf(value).Kind()
-	switch vKind {
-	case reflect.String:
-		bm[key] = value.(string)
-	case reflect.Int:
-		bm[key] = Int2String(value.(int))
-	case reflect.Int64:
-		bm[key] = Int642String(value.(int64))
-	case reflect.Float32:
-		bm[key] = Float32ToString(value.(float32))
-	case reflect.Float64:
-		bm[key] = Float64ToString(value.(float64))
-	case reflect.Ptr, reflect.Struct, reflect.Map, reflect.Slice:
-		bm[key] = value
-	default:
-		bm[key] = null
-	}
+	bm[key] = value
 }
 
-//获取参数
+// 获取参数
 func (bm BodyMap) Get(key string) string {
 	if bm == nil {
 		return null
@@ -73,7 +56,7 @@ func jsonToString(v interface{}) (str string) {
 	return
 }
 
-//删除参数
+// 删除参数
 func (bm BodyMap) Remove(key string) {
 	delete(bm, key)
 }
@@ -165,20 +148,22 @@ func (bm BodyMap) EncodeAliPaySignParams() string {
 	}
 	sort.Strings(keyList)
 	for _, k := range keyList {
-		buf.WriteString(k)
-		buf.WriteByte('=')
-		buf.WriteString(bm.Get(k))
-		buf.WriteByte('&')
+		if v := bm.Get(k); v != null {
+			buf.WriteString(k)
+			buf.WriteByte('=')
+			buf.WriteString(v)
+			buf.WriteByte('&')
+		}
 	}
 	return buf.String()[:buf.Len()-1]
 }
 
-//HttpAgent
+// HttpAgent
 func HttpAgent() (agent *gorequest.SuperAgent) {
 	return gorequest.New().TLSClientConfig(&tls.Config{InsecureSkipVerify: true})
 }
 
-//获取随机字符串
+// 获取随机字符串
 //    length:字符串长度
 func GetRandomString(length int) string {
 	str := "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
@@ -195,26 +180,26 @@ func GetRandomString(length int) string {
 	return string(result)
 }
 
-//解析时间
+// 解析时间
 func ParseDateTime(timeStr string) (datetime time.Time) {
 	datetime, _ = time.ParseInLocation(TimeLayout, timeStr, time.Local)
 	return
 }
 
-//字符串转Float64
+// 字符串转Float64
 func String2Float64(floatStr string) (floatNum float64) {
 	floatNum, _ = strconv.ParseFloat(floatStr, 64)
 	return
 }
 
-//字符串转Float32
+// 字符串转Float32
 func String2Float32(floatStr string) (floatNum float32) {
 	float, _ := strconv.ParseFloat(floatStr, 32)
 	floatNum = float32(float)
 	return
 }
 
-//Float64转字符串
+// Float64转字符串
 //    floatNum:float64数字
 //    prec:精度位数(不传则默认float数字精度)
 func Float64ToString(floatNum float64, prec ...int) (floatStr string) {
@@ -226,7 +211,7 @@ func Float64ToString(floatNum float64, prec ...int) (floatStr string) {
 	return
 }
 
-//Float32转字符串
+// Float32转字符串
 //    floatNum:float32数字
 //    prec:精度位数(不传则默认float数字精度)
 func Float32ToString(floatNum float32, prec ...int) (floatStr string) {
@@ -238,66 +223,66 @@ func Float32ToString(floatNum float32, prec ...int) (floatStr string) {
 	return
 }
 
-//字符串转Int
+// 字符串转Int
 func String2Int(intStr string) (intNum int) {
 	intNum, _ = strconv.Atoi(intStr)
 	return
 }
 
-//字符串转Int32
+// 字符串转Int32
 func String2Int32(intStr string) (int32Num int32) {
 	intNum, _ := strconv.Atoi(intStr)
 	int32Num = int32(intNum)
 	return
 }
 
-//字符串转Int64
+// 字符串转Int64
 func String2Int64(intStr string) (int64Num int64) {
 	intNum, _ := strconv.Atoi(intStr)
 	int64Num = int64(intNum)
 	return
 }
 
-//Int转字符串
+// Int转字符串
 func Int2String(intNum int) (intStr string) {
 	intStr = strconv.Itoa(intNum)
 	return
 }
 
-//Int32转字符串
+// Int32转字符串
 func Int322String(intNum int32) (int32Str string) {
-	//10, 代表10进制
+	// 10, 代表10进制
 	int32Str = strconv.FormatInt(int64(intNum), 10)
 	return
 }
 
-//Int64转字符串
+// Int64转字符串
 func Int642String(intNum int64) (int64Str string) {
-	//10, 代表10进制
+	// 10, 代表10进制
 	int64Str = strconv.FormatInt(intNum, 10)
 	return
 }
 
-//解密填充模式(去除补全码) PKCS7UnPadding
-//解密时,需要在最后面去掉加密时添加的填充byte
+// 解密填充模式(去除补全码) PKCS7UnPadding
+// 解密时,需要在最后面去掉加密时添加的填充byte
 func PKCS7UnPadding(origData []byte) (bs []byte) {
 	length := len(origData)
-	unPaddingNumber := int(origData[length-1]) //找到Byte数组最后的填充byte 数字
+	unPaddingNumber := int(origData[length-1]) // 找到Byte数组最后的填充byte 数字
 	if unPaddingNumber <= 16 {
-		bs = origData[:(length - unPaddingNumber)] //只截取返回有效数字内的byte数组
+		bs = origData[:(length - unPaddingNumber)] // 只截取返回有效数字内的byte数组
 	} else {
 		bs = origData
 	}
 	return
 }
 
-//解密填充模式(去除补全码) PKCS5UnPadding
-//解密时,需要在最后面去掉加密时添加的填充byte
+// 解密填充模式(去除补全码) PKCS5UnPadding
+// 解密时,需要在最后面去掉加密时添加的填充byte
 func PKCS5UnPadding(origData []byte) (bs []byte) {
 	length := len(origData)
-	unPaddingNumber := int(origData[length-1]) //找到Byte数组最后的填充byte
+	unPaddingNumber := int(origData[length-1]) // 找到Byte数组最后的填充byte
 	if unPaddingNumber <= 16 {
-		bs = origData[:(length - unPaddingNumber)] //只截取返回有效数字内的byte数组
+		bs = origData[:(length - unPaddingNumber)] // 只截取返回有效数字内的byte数组
 	} else {
 		bs = origData
 	}

+ 2 - 2
wechat_client.go

@@ -336,7 +336,7 @@ func (w *WeChatClient) Transfer(body BodyMap, certFilePath, keyFilePath, pkcs12F
 	return
 }
 
-// 公众号纯签约
+// 公众号纯签约(未完成)
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_1&index=1
 func (w *WeChatClient) EntrustPublic(body BodyMap) (bs []byte, err error) {
 	bs, err = w.doWeChat(body, wxEntrustPublic)
@@ -344,7 +344,7 @@ func (w *WeChatClient) EntrustPublic(body BodyMap) (bs []byte, err error) {
 	return nil, nil
 }
 
-//向微信发送请求 ok
+// 向微信发送请求 ok
 func (w *WeChatClient) doWeChat(body BodyMap, path string, tlsConfig ...*tls.Config) (bytes []byte, err error) {
 	body.Set("appid", w.AppId)
 	body.Set("mch_id", w.MchId)

+ 22 - 0
wechat_client_test.go

@@ -138,3 +138,25 @@ func TestDecryptRefundNotifyReqInfo(t *testing.T) {
 	}
 	fmt.Println("refundNotify:", *refundNotify)
 }
+
+func TestBodyMap_Set_Get(t *testing.T) {
+	bm := make(BodyMap)
+	sceneInfo := make(map[string]map[string]string)
+	h5Info := make(map[string]string)
+	h5Info["type"] = "Wap"
+	h5Info["wap_url"] = "http://www.gopay.ink"
+	h5Info["wap_name"] = "H5测试支付"
+	sceneInfo["h5_info"] = h5Info
+	bm.Set("scene_info", sceneInfo)
+	fmt.Println("Get1:", bm.Get("scene_info"))
+
+	bm.Set("student", &Student{
+		Name:  "Jerry",
+		Age:   26,
+		Sign:  "123465",
+		Phone: "123654987",
+	})
+
+	fmt.Println("Get2:", bm.Get("student"))
+
+}

+ 13 - 13
wechat_rsp.go

@@ -322,23 +322,23 @@ type WeChatUserInfo struct {
 
 // 微信小程序解密后 用户手机号结构体
 type WeChatUserPhone struct {
-	PhoneNumber     string        `json:"phoneNumber,omitempty"`
-	PurePhoneNumber string        `json:"purePhoneNumber,omitempty"`
-	CountryCode     string        `json:"countryCode,omitempty"`
-	Watermark       watermarkInfo `json:"watermark,omitempty"`
+	PhoneNumber     string         `json:"phoneNumber,omitempty"`
+	PurePhoneNumber string         `json:"purePhoneNumber,omitempty"`
+	CountryCode     string         `json:"countryCode,omitempty"`
+	Watermark       *watermarkInfo `json:"watermark,omitempty"`
 }
 
 // 微信小程序解密后 用户信息结构体
 type WeChatAppletUserInfo struct {
-	OpenId    string        `json:"openId,omitempty"`
-	NickName  string        `json:"nickName,omitempty"`
-	Gender    int           `json:"gender,omitempty"`
-	City      string        `json:"city,omitempty"`
-	Province  string        `json:"province,omitempty"`
-	Country   string        `json:"country,omitempty"`
-	AvatarUrl string        `json:"avatarUrl,omitempty"`
-	UnionId   string        `json:"unionId,omitempty"`
-	Watermark watermarkInfo `json:"watermark,omitempty"`
+	OpenId    string         `json:"openId,omitempty"`
+	NickName  string         `json:"nickName,omitempty"`
+	Gender    int            `json:"gender,omitempty"`
+	City      string         `json:"city,omitempty"`
+	Province  string         `json:"province,omitempty"`
+	Country   string         `json:"country,omitempty"`
+	AvatarUrl string         `json:"avatarUrl,omitempty"`
+	UnionId   string         `json:"unionId,omitempty"`
+	Watermark *watermarkInfo `json:"watermark,omitempty"`
 }
 
 type watermarkInfo struct {

+ 4 - 4
wechat_service_api.go

@@ -19,7 +19,7 @@ import (
 	"strings"
 )
 
-//获取微信支付所需参数里的Sign值(通过支付参数计算Sign值)
+// 获取微信支付所需参数里的Sign值(通过支付参数计算Sign值)
 //    注意:BodyMap中如无 sign_type 参数,默认赋值 sign_type 为 MD5
 //    appId:应用ID
 //    mchId:商户ID
@@ -46,7 +46,7 @@ func GetWeChatParamSign(appId, mchId, apiKey string, bm BodyMap) (sign string) {
 	return
 }
 
-//获取微信支付沙箱环境所需参数里的Sign值(通过支付参数计算Sign值)
+// 获取微信支付沙箱环境所需参数里的Sign值(通过支付参数计算Sign值)
 //    注意:沙箱环境默认 sign_type 为 MD5
 //    appId:应用ID
 //    mchId:商户ID
@@ -69,7 +69,7 @@ func GetWeChatSanBoxParamSign(appId, mchId, apiKey string, bm BodyMap) (sign str
 	return
 }
 
-//解析微信支付异步通知的结果到BodyMap
+// 解析微信支付异步通知的结果到BodyMap
 //    req:*http.Request
 //    返回参数bm:Notify请求的参数
 //    返回参数err:错误信息
@@ -85,7 +85,7 @@ func ParseWeChatNotifyResultToBodyMap(req *http.Request) (bm BodyMap, err error)
 	return
 }
 
-//解析微信支付异步通知的参数
+// 解析微信支付异步通知的参数
 //    req:*http.Request
 //    返回参数notifyReq:Notify请求的参数
 //    返回参数err:错误信息