Jerry %!s(int64=6) %!d(string=hai) anos
pai
achega
010012e399
Modificáronse 18 ficheiros con 456 adicións e 159 borrados
  1. 72 72
      alipay/client.go
  2. 0 0
      alipay/client_test.go
  3. 0 0
      alipay/model.go
  4. 0 0
      alipay/param.go
  5. 0 0
      alipay/service_api.go
  6. 33 10
      body_map.go
  7. 20 0
      gopay_test.go
  8. 1 1
      http_client.go
  9. 84 0
      qq/client.go
  10. 42 0
      qq/client_test.go
  11. 57 0
      qq/model.go
  12. 73 0
      qq/param.go
  13. 0 1
      qq/qq_client.go
  14. 56 56
      wechat/client.go
  15. 0 0
      wechat/client_test.go
  16. 5 5
      wechat/model.go
  17. 11 12
      wechat/param.go
  18. 2 2
      wechat/service_api.go

+ 72 - 72
alipay/alipay_client.go → alipay/client.go

@@ -44,14 +44,14 @@ func NewClient(appId, privateKey string, isProd bool) (client *Client) {
 
 
 // alipay.trade.fastpay.refund.query(统一收单交易退款查询)
 // alipay.trade.fastpay.refund.query(统一收单交易退款查询)
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.fastpay.refund.query
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.fastpay.refund.query
-func (a *Client) TradeFastPayRefundQuery(body gopay.BodyMap) (aliRsp *TradeFastpayRefundQueryResponse, err error) {
+func (a *Client) TradeFastPayRefundQuery(bm gopay.BodyMap) (aliRsp *TradeFastpayRefundQueryResponse, err error) {
 	var (
 	var (
 		bs []byte
 		bs []byte
 	)
 	)
-	if body.Get("out_trade_no") == gopay.NULL && body.Get("trade_no") == gopay.NULL {
+	if bm.Get("out_trade_no") == gopay.NULL && bm.Get("trade_no") == gopay.NULL {
 		return nil, errors.New("out_trade_no and trade_no are not allowed to be NULL at the same time")
 		return nil, errors.New("out_trade_no and trade_no are not allowed to be NULL at the same time")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.trade.fastpay.refund.query"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.trade.fastpay.refund.query"); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(TradeFastpayRefundQueryResponse)
 	aliRsp = new(TradeFastpayRefundQueryResponse)
@@ -68,14 +68,14 @@ func (a *Client) TradeFastPayRefundQuery(body gopay.BodyMap) (aliRsp *TradeFastp
 
 
 // alipay.trade.order.settle(统一收单交易结算接口)
 // alipay.trade.order.settle(统一收单交易结算接口)
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.order.settle
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.order.settle
-func (a *Client) TradeOrderSettle(body gopay.BodyMap) (aliRsp *TradeOrderSettleResponse, err error) {
+func (a *Client) TradeOrderSettle(bm gopay.BodyMap) (aliRsp *TradeOrderSettleResponse, err error) {
 	var (
 	var (
 		bs []byte
 		bs []byte
 	)
 	)
-	if body.Get("out_request_no") == gopay.NULL || body.Get("trade_no") == gopay.NULL {
+	if bm.Get("out_request_no") == gopay.NULL || bm.Get("trade_no") == gopay.NULL {
 		return nil, errors.New("out_request_no or trade_no are not allowed to be NULL")
 		return nil, errors.New("out_request_no or trade_no are not allowed to be NULL")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.trade.order.settle"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.trade.order.settle"); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(TradeOrderSettleResponse)
 	aliRsp = new(TradeOrderSettleResponse)
@@ -92,14 +92,14 @@ func (a *Client) TradeOrderSettle(body gopay.BodyMap) (aliRsp *TradeOrderSettleR
 
 
 // alipay.trade.create(统一收单交易创建接口)
 // alipay.trade.create(统一收单交易创建接口)
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.create
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.create
-func (a *Client) TradeCreate(body gopay.BodyMap) (aliRsp *TradeCreateResponse, err error) {
+func (a *Client) TradeCreate(bm gopay.BodyMap) (aliRsp *TradeCreateResponse, err error) {
 	var (
 	var (
 		bs []byte
 		bs []byte
 	)
 	)
-	if body.Get("out_trade_no") == gopay.NULL && body.Get("buyer_id") == gopay.NULL {
+	if bm.Get("out_trade_no") == gopay.NULL && bm.Get("buyer_id") == gopay.NULL {
 		return nil, errors.New("out_trade_no and buyer_id are not allowed to be NULL at the same time")
 		return nil, errors.New("out_trade_no and buyer_id are not allowed to be NULL at the same time")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.trade.create"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.trade.create"); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(TradeCreateResponse)
 	aliRsp = new(TradeCreateResponse)
@@ -116,14 +116,14 @@ func (a *Client) TradeCreate(body gopay.BodyMap) (aliRsp *TradeCreateResponse, e
 
 
 // alipay.trade.close(统一收单交易关闭接口)
 // alipay.trade.close(统一收单交易关闭接口)
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.close
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.close
-func (a *Client) TradeClose(body gopay.BodyMap) (aliRsp *TradeCloseResponse, err error) {
+func (a *Client) TradeClose(bm gopay.BodyMap) (aliRsp *TradeCloseResponse, err error) {
 	var (
 	var (
 		bs []byte
 		bs []byte
 	)
 	)
-	if body.Get("out_trade_no") == gopay.NULL && body.Get("trade_no") == gopay.NULL {
+	if bm.Get("out_trade_no") == gopay.NULL && bm.Get("trade_no") == gopay.NULL {
 		return nil, errors.New("out_trade_no and trade_no are not allowed to be NULL at the same time")
 		return nil, errors.New("out_trade_no and trade_no are not allowed to be NULL at the same time")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.trade.close"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.trade.close"); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(TradeCloseResponse)
 	aliRsp = new(TradeCloseResponse)
@@ -140,14 +140,14 @@ func (a *Client) TradeClose(body gopay.BodyMap) (aliRsp *TradeCloseResponse, err
 
 
 // alipay.trade.cancel(统一收单交易撤销接口)
 // alipay.trade.cancel(统一收单交易撤销接口)
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.cancel
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.cancel
-func (a *Client) TradeCancel(body gopay.BodyMap) (aliRsp *TradeCancelResponse, err error) {
+func (a *Client) TradeCancel(bm gopay.BodyMap) (aliRsp *TradeCancelResponse, err error) {
 	var (
 	var (
 		bs []byte
 		bs []byte
 	)
 	)
-	if body.Get("out_trade_no") == gopay.NULL && body.Get("trade_no") == gopay.NULL {
+	if bm.Get("out_trade_no") == gopay.NULL && bm.Get("trade_no") == gopay.NULL {
 		return nil, errors.New("out_trade_no and trade_no are not allowed to be NULL at the same time")
 		return nil, errors.New("out_trade_no and trade_no are not allowed to be NULL at the same time")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.trade.cancel"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.trade.cancel"); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(TradeCancelResponse)
 	aliRsp = new(TradeCancelResponse)
@@ -164,14 +164,14 @@ func (a *Client) TradeCancel(body gopay.BodyMap) (aliRsp *TradeCancelResponse, e
 
 
 // alipay.trade.refund(统一收单交易退款接口)
 // alipay.trade.refund(统一收单交易退款接口)
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.refund
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.refund
-func (a *Client) TradeRefund(body gopay.BodyMap) (aliRsp *TradeRefundResponse, err error) {
+func (a *Client) TradeRefund(bm gopay.BodyMap) (aliRsp *TradeRefundResponse, err error) {
 	var (
 	var (
 		bs []byte
 		bs []byte
 	)
 	)
-	if body.Get("out_trade_no") == gopay.NULL && body.Get("trade_no") == gopay.NULL {
+	if bm.Get("out_trade_no") == gopay.NULL && bm.Get("trade_no") == gopay.NULL {
 		return nil, errors.New("out_trade_no and trade_no are not allowed to be NULL at the same time")
 		return nil, errors.New("out_trade_no and trade_no are not allowed to be NULL at the same time")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.trade.refund"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.trade.refund"); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 	aliRsp = new(TradeRefundResponse)
 	aliRsp = new(TradeRefundResponse)
@@ -188,14 +188,14 @@ func (a *Client) TradeRefund(body gopay.BodyMap) (aliRsp *TradeRefundResponse, e
 
 
 // alipay.trade.page.refund(统一收单退款页面接口)
 // alipay.trade.page.refund(统一收单退款页面接口)
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.page.refund
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.page.refund
-func (a *Client) TradePageRefund(body gopay.BodyMap) (aliRsp *TradePageRefundResponse, err error) {
+func (a *Client) TradePageRefund(bm gopay.BodyMap) (aliRsp *TradePageRefundResponse, err error) {
 	var (
 	var (
 		bs []byte
 		bs []byte
 	)
 	)
-	if body.Get("out_trade_no") == gopay.NULL && body.Get("trade_no") == gopay.NULL {
+	if bm.Get("out_trade_no") == gopay.NULL && bm.Get("trade_no") == gopay.NULL {
 		return nil, errors.New("out_trade_no and trade_no are not allowed to be NULL at the same time")
 		return nil, errors.New("out_trade_no and trade_no are not allowed to be NULL at the same time")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.trade.page.refund"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.trade.page.refund"); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(TradePageRefundResponse)
 	aliRsp = new(TradePageRefundResponse)
@@ -212,12 +212,12 @@ func (a *Client) TradePageRefund(body gopay.BodyMap) (aliRsp *TradePageRefundRes
 
 
 // alipay.trade.precreate(统一收单线下交易预创建)
 // alipay.trade.precreate(统一收单线下交易预创建)
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.precreate
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.precreate
-func (a *Client) TradePrecreate(body gopay.BodyMap) (aliRsp *TradePrecreateResponse, err error) {
+func (a *Client) TradePrecreate(bm gopay.BodyMap) (aliRsp *TradePrecreateResponse, err error) {
 	var bs []byte
 	var bs []byte
-	if body.Get("out_trade_no") == gopay.NULL {
+	if bm.Get("out_trade_no") == gopay.NULL {
 		return nil, errors.New("out_trade_no is not allowed to be NULL")
 		return nil, errors.New("out_trade_no is not allowed to be NULL")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.trade.precreate"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.trade.precreate"); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(TradePrecreateResponse)
 	aliRsp = new(TradePrecreateResponse)
@@ -234,12 +234,12 @@ func (a *Client) TradePrecreate(body gopay.BodyMap) (aliRsp *TradePrecreateRespo
 
 
 // alipay.trade.pay(统一收单交易支付接口)
 // alipay.trade.pay(统一收单交易支付接口)
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.pay
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.pay
-func (a *Client) TradePay(body gopay.BodyMap) (aliRsp *TradePayResponse, err error) {
+func (a *Client) TradePay(bm gopay.BodyMap) (aliRsp *TradePayResponse, err error) {
 	var bs []byte
 	var bs []byte
-	if body.Get("out_trade_no") == gopay.NULL {
+	if bm.Get("out_trade_no") == gopay.NULL {
 		return nil, errors.New("out_trade_no is not allowed to be NULL")
 		return nil, errors.New("out_trade_no is not allowed to be NULL")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.trade.pay"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.trade.pay"); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(TradePayResponse)
 	aliRsp = new(TradePayResponse)
@@ -256,14 +256,14 @@ func (a *Client) TradePay(body gopay.BodyMap) (aliRsp *TradePayResponse, err err
 
 
 // alipay.trade.query(统一收单线下交易查询)
 // alipay.trade.query(统一收单线下交易查询)
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.query
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.query
-func (a *Client) TradeQuery(body gopay.BodyMap) (aliRsp *TradeQueryResponse, err error) {
+func (a *Client) TradeQuery(bm gopay.BodyMap) (aliRsp *TradeQueryResponse, err error) {
 	var (
 	var (
 		bs []byte
 		bs []byte
 	)
 	)
-	if body.Get("out_trade_no") == gopay.NULL && body.Get("trade_no") == gopay.NULL {
+	if bm.Get("out_trade_no") == gopay.NULL && bm.Get("trade_no") == gopay.NULL {
 		return nil, errors.New("out_trade_no and trade_no are not allowed to be NULL at the same time")
 		return nil, errors.New("out_trade_no and trade_no are not allowed to be NULL at the same time")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.trade.query"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.trade.query"); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(TradeQueryResponse)
 	aliRsp = new(TradeQueryResponse)
@@ -280,12 +280,12 @@ func (a *Client) TradeQuery(body gopay.BodyMap) (aliRsp *TradeQueryResponse, err
 
 
 // alipay.trade.app.pay(app支付接口2.0)
 // alipay.trade.app.pay(app支付接口2.0)
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.app.pay
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.app.pay
-func (a *Client) TradeAppPay(body gopay.BodyMap) (payParam string, err error) {
+func (a *Client) TradeAppPay(bm gopay.BodyMap) (payParam string, err error) {
 	var bs []byte
 	var bs []byte
-	if body.Get("out_trade_no") == gopay.NULL {
+	if bm.Get("out_trade_no") == gopay.NULL {
 		return gopay.NULL, errors.New("out_trade_no is not allowed to be NULL")
 		return gopay.NULL, errors.New("out_trade_no is not allowed to be NULL")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.trade.app.pay"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.trade.app.pay"); err != nil {
 		return gopay.NULL, err
 		return gopay.NULL, err
 	}
 	}
 	payParam = string(bs)
 	payParam = string(bs)
@@ -294,13 +294,13 @@ func (a *Client) TradeAppPay(body gopay.BodyMap) (payParam string, err error) {
 
 
 // alipay.trade.wap.pay(手机网站支付接口2.0)
 // alipay.trade.wap.pay(手机网站支付接口2.0)
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.wap.pay
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.wap.pay
-func (a *Client) TradeWapPay(body gopay.BodyMap) (payUrl string, err error) {
+func (a *Client) TradeWapPay(bm gopay.BodyMap) (payUrl string, err error) {
 	var bs []byte
 	var bs []byte
-	if body.Get("out_trade_no") == gopay.NULL {
+	if bm.Get("out_trade_no") == gopay.NULL {
 		return gopay.NULL, errors.New("out_trade_no is not allowed to be NULL")
 		return gopay.NULL, errors.New("out_trade_no is not allowed to be NULL")
 	}
 	}
-	body.Set("product_code", "QUICK_WAP_WAY")
-	if bs, err = a.doAliPay(body, "alipay.trade.wap.pay"); err != nil {
+	bm.Set("product_code", "QUICK_WAP_WAY")
+	if bs, err = a.doAliPay(bm, "alipay.trade.wap.pay"); err != nil {
 		return gopay.NULL, err
 		return gopay.NULL, err
 	}
 	}
 	payUrl = string(bs)
 	payUrl = string(bs)
@@ -309,13 +309,13 @@ func (a *Client) TradeWapPay(body gopay.BodyMap) (payUrl string, err error) {
 
 
 // alipay.trade.page.pay(统一收单下单并支付页面接口)
 // alipay.trade.page.pay(统一收单下单并支付页面接口)
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.page.pay
 //    文档地址:https://docs.open.alipay.com/api_1/alipay.trade.page.pay
-func (a *Client) TradePagePay(body gopay.BodyMap) (payUrl string, err error) {
+func (a *Client) TradePagePay(bm gopay.BodyMap) (payUrl string, err error) {
 	var bs []byte
 	var bs []byte
-	if body.Get("out_trade_no") == gopay.NULL {
+	if bm.Get("out_trade_no") == gopay.NULL {
 		return gopay.NULL, errors.New("out_trade_no is not allowed to be NULL")
 		return gopay.NULL, errors.New("out_trade_no is not allowed to be NULL")
 	}
 	}
-	body.Set("product_code", "FAST_INSTANT_TRADE_PAY")
-	if bs, err = a.doAliPay(body, "alipay.trade.page.pay"); err != nil {
+	bm.Set("product_code", "FAST_INSTANT_TRADE_PAY")
+	if bs, err = a.doAliPay(bm, "alipay.trade.page.pay"); err != nil {
 		return gopay.NULL, err
 		return gopay.NULL, err
 	}
 	}
 	payUrl = string(bs)
 	payUrl = string(bs)
@@ -324,12 +324,12 @@ func (a *Client) TradePagePay(body gopay.BodyMap) (payUrl string, err error) {
 
 
 // alipay.fund.trans.toaccount.transfer(单笔转账到支付宝账户接口)
 // alipay.fund.trans.toaccount.transfer(单笔转账到支付宝账户接口)
 //    文档地址:https://docs.open.alipay.com/api_28/alipay.fund.trans.toaccount.transfer
 //    文档地址:https://docs.open.alipay.com/api_28/alipay.fund.trans.toaccount.transfer
-func (a *Client) FundTransToaccountTransfer(body gopay.BodyMap) (aliRsp *FundTransToaccountTransferResponse, err error) {
+func (a *Client) FundTransToaccountTransfer(bm gopay.BodyMap) (aliRsp *FundTransToaccountTransferResponse, err error) {
 	var bs []byte
 	var bs []byte
-	if body.Get("out_biz_no") == gopay.NULL {
+	if bm.Get("out_biz_no") == gopay.NULL {
 		return nil, errors.New("out_biz_no is not allowed to be NULL")
 		return nil, errors.New("out_biz_no is not allowed to be NULL")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.fund.trans.toaccount.transfer"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.fund.trans.toaccount.transfer"); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(FundTransToaccountTransferResponse)
 	aliRsp = new(FundTransToaccountTransferResponse)
@@ -352,15 +352,15 @@ func (a *Client) TradeOrderinfoSync(body gopay.BodyMap) {
 
 
 // alipay.system.oauth.token(换取授权访问令牌)
 // alipay.system.oauth.token(换取授权访问令牌)
 //    文档地址:https://docs.open.alipay.com/api_9/alipay.system.oauth.token
 //    文档地址:https://docs.open.alipay.com/api_9/alipay.system.oauth.token
-func (a *Client) SystemOauthToken(body gopay.BodyMap) (aliRsp *SystemOauthTokenResponse, err error) {
+func (a *Client) SystemOauthToken(bm gopay.BodyMap) (aliRsp *SystemOauthTokenResponse, err error) {
 	var bs []byte
 	var bs []byte
-	if body.Get("grant_type") == gopay.NULL {
+	if bm.Get("grant_type") == gopay.NULL {
 		return nil, errors.New("grant_type is not allowed to be NULL")
 		return nil, errors.New("grant_type is not allowed to be NULL")
 	}
 	}
-	if body.Get("code") == gopay.NULL && body.Get("refresh_token") == gopay.NULL {
+	if bm.Get("code") == gopay.NULL && bm.Get("refresh_token") == gopay.NULL {
 		return nil, errors.New("code and refresh_token are not allowed to be NULL at the same time")
 		return nil, errors.New("code and refresh_token are not allowed to be NULL at the same time")
 	}
 	}
-	if bs, err = systemOauthToken(a.AppId, a.PrivateKey, body, "alipay.system.oauth.token", a.IsProd); err != nil {
+	if bs, err = systemOauthToken(a.AppId, a.PrivateKey, bm, "alipay.system.oauth.token", a.IsProd); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(SystemOauthTokenResponse)
 	aliRsp = new(SystemOauthTokenResponse)
@@ -397,15 +397,15 @@ func (a *Client) UserInfoShare() (aliRsp *UserInfoShareResponse, err error) {
 
 
 // alipay.open.auth.token.app(换取应用授权令牌)
 // alipay.open.auth.token.app(换取应用授权令牌)
 //    文档地址:https://docs.open.alipay.com/api_9/alipay.open.auth.token.app
 //    文档地址:https://docs.open.alipay.com/api_9/alipay.open.auth.token.app
-func (a *Client) OpenAuthTokenApp(body gopay.BodyMap) (aliRsp *OpenAuthTokenAppResponse, err error) {
+func (a *Client) OpenAuthTokenApp(bm gopay.BodyMap) (aliRsp *OpenAuthTokenAppResponse, err error) {
 	var bs []byte
 	var bs []byte
-	if body.Get("grant_type") == gopay.NULL {
+	if bm.Get("grant_type") == gopay.NULL {
 		return nil, errors.New("grant_type is not allowed to be NULL")
 		return nil, errors.New("grant_type is not allowed to be NULL")
 	}
 	}
-	if body.Get("code") == gopay.NULL && body.Get("refresh_token") == gopay.NULL {
+	if bm.Get("code") == gopay.NULL && bm.Get("refresh_token") == gopay.NULL {
 		return nil, errors.New("code and refresh_token are not allowed to be NULL at the same time")
 		return nil, errors.New("code and refresh_token are not allowed to be NULL at the same time")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.open.auth.token.app"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.open.auth.token.app"); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(OpenAuthTokenAppResponse)
 	aliRsp = new(OpenAuthTokenAppResponse)
@@ -422,17 +422,17 @@ func (a *Client) OpenAuthTokenApp(body gopay.BodyMap) (aliRsp *OpenAuthTokenAppR
 
 
 // zhima.credit.score.get(芝麻分)
 // zhima.credit.score.get(芝麻分)
 //    文档地址:https://docs.open.alipay.com/api_8/zhima.credit.score.get
 //    文档地址:https://docs.open.alipay.com/api_8/zhima.credit.score.get
-func (a *Client) ZhimaCreditScoreGet(body gopay.BodyMap) (aliRsp *ZhimaCreditScoreGetResponse, err error) {
+func (a *Client) ZhimaCreditScoreGet(bm gopay.BodyMap) (aliRsp *ZhimaCreditScoreGetResponse, err error) {
 	var (
 	var (
 		bs []byte
 		bs []byte
 	)
 	)
-	if body.Get("product_code") == gopay.NULL {
-		body.Set("product_code", "w1010100100000000001")
+	if bm.Get("product_code") == gopay.NULL {
+		bm.Set("product_code", "w1010100100000000001")
 	}
 	}
-	if body.Get("transaction_id") == gopay.NULL {
+	if bm.Get("transaction_id") == gopay.NULL {
 		return nil, errors.New("transaction_id is not allowed to be NULL")
 		return nil, errors.New("transaction_id is not allowed to be NULL")
 	}
 	}
-	if bs, err = a.doAliPay(body, "zhima.credit.score.get"); err != nil {
+	if bs, err = a.doAliPay(bm, "zhima.credit.score.get"); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(ZhimaCreditScoreGetResponse)
 	aliRsp = new(ZhimaCreditScoreGetResponse)
@@ -449,23 +449,23 @@ func (a *Client) ZhimaCreditScoreGet(body gopay.BodyMap) (aliRsp *ZhimaCreditSco
 
 
 // alipay.user.certify.open.initialize(身份认证初始化服务)
 // alipay.user.certify.open.initialize(身份认证初始化服务)
 //    文档地址:https://docs.open.alipay.com/api_2/alipay.user.certify.open.initialize
 //    文档地址:https://docs.open.alipay.com/api_2/alipay.user.certify.open.initialize
-func (a *Client) UserCertifyOpenInit(body gopay.BodyMap) (aliRsp *UserCertifyOpenInitResponse, err error) {
+func (a *Client) UserCertifyOpenInit(bm gopay.BodyMap) (aliRsp *UserCertifyOpenInitResponse, err error) {
 	var (
 	var (
 		bs []byte
 		bs []byte
 	)
 	)
-	if body.Get("biz_code") == gopay.NULL {
+	if bm.Get("biz_code") == gopay.NULL {
 		return nil, errors.New("biz_code is not allowed to be NULL")
 		return nil, errors.New("biz_code is not allowed to be NULL")
 	}
 	}
-	if body.Get("outer_order_no") == gopay.NULL {
+	if bm.Get("outer_order_no") == gopay.NULL {
 		return nil, errors.New("outer_order_no is not allowed to be NULL")
 		return nil, errors.New("outer_order_no is not allowed to be NULL")
 	}
 	}
-	if body.Get("identity_param") == gopay.NULL {
+	if bm.Get("identity_param") == gopay.NULL {
 		return nil, errors.New("identity_param is not allowed to be NULL")
 		return nil, errors.New("identity_param is not allowed to be NULL")
 	}
 	}
-	if body.Get("merchant_config") == gopay.NULL {
+	if bm.Get("merchant_config") == gopay.NULL {
 		return nil, errors.New("merchant_config is not allowed to be NULL")
 		return nil, errors.New("merchant_config is not allowed to be NULL")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.user.certify.open.initialize"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.user.certify.open.initialize"); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(UserCertifyOpenInitResponse)
 	aliRsp = new(UserCertifyOpenInitResponse)
@@ -483,14 +483,14 @@ func (a *Client) UserCertifyOpenInit(body gopay.BodyMap) (aliRsp *UserCertifyOpe
 // alipay.user.certify.open.certify(身份认证开始认证)
 // alipay.user.certify.open.certify(身份认证开始认证)
 //    API文档地址:https://docs.open.alipay.com/api_2/alipay.user.certify.open.certify
 //    API文档地址:https://docs.open.alipay.com/api_2/alipay.user.certify.open.certify
 //    产品文档地址:https://docs.open.alipay.com/20181012100420932508/quickstart
 //    产品文档地址:https://docs.open.alipay.com/20181012100420932508/quickstart
-func (a *Client) UserCertifyOpenCertify(body gopay.BodyMap) (certifyUrl string, err error) {
+func (a *Client) UserCertifyOpenCertify(bm gopay.BodyMap) (certifyUrl string, err error) {
 	var (
 	var (
 		bs []byte
 		bs []byte
 	)
 	)
-	if body.Get("certify_id") == gopay.NULL {
+	if bm.Get("certify_id") == gopay.NULL {
 		return gopay.NULL, errors.New("certify_id is not allowed to be NULL")
 		return gopay.NULL, errors.New("certify_id is not allowed to be NULL")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.user.certify.open.certify"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.user.certify.open.certify"); err != nil {
 		return gopay.NULL, err
 		return gopay.NULL, err
 	}
 	}
 	certifyUrl = string(bs)
 	certifyUrl = string(bs)
@@ -499,14 +499,14 @@ func (a *Client) UserCertifyOpenCertify(body gopay.BodyMap) (certifyUrl string,
 
 
 // alipay.user.certify.open.query(身份认证记录查询)
 // alipay.user.certify.open.query(身份认证记录查询)
 //    文档地址:https://docs.open.alipay.com/api_2/alipay.user.certify.open.query
 //    文档地址:https://docs.open.alipay.com/api_2/alipay.user.certify.open.query
-func (a *Client) UserCertifyOpenQuery(body gopay.BodyMap) (aliRsp *UserCertifyOpenQueryResponse, err error) {
+func (a *Client) UserCertifyOpenQuery(bm gopay.BodyMap) (aliRsp *UserCertifyOpenQueryResponse, err error) {
 	var (
 	var (
 		bs []byte
 		bs []byte
 	)
 	)
-	if body.Get("certify_id") == gopay.NULL {
+	if bm.Get("certify_id") == gopay.NULL {
 		return nil, errors.New("certify_id is not allowed to be NULL")
 		return nil, errors.New("certify_id is not allowed to be NULL")
 	}
 	}
-	if bs, err = a.doAliPay(body, "alipay.user.certify.open.query"); err != nil {
+	if bs, err = a.doAliPay(bm, "alipay.user.certify.open.query"); err != nil {
 		return
 		return
 	}
 	}
 	aliRsp = new(UserCertifyOpenQueryResponse)
 	aliRsp = new(UserCertifyOpenQueryResponse)
@@ -522,13 +522,13 @@ func (a *Client) UserCertifyOpenQuery(body gopay.BodyMap) (aliRsp *UserCertifyOp
 }
 }
 
 
 // 向支付宝发送请求
 // 向支付宝发送请求
-func (a *Client) doAliPay(body gopay.BodyMap, method string) (bs []byte, err error) {
+func (a *Client) doAliPay(bm gopay.BodyMap, method string) (bs []byte, err error) {
 	var (
 	var (
 		bodyStr, url string
 		bodyStr, url string
 		bodyBs       []byte
 		bodyBs       []byte
 	)
 	)
-	if body != nil {
-		if bodyBs, err = json.Marshal(body); err != nil {
+	if bm != nil {
+		if bodyBs, err = json.Marshal(bm); err != nil {
 			return nil, fmt.Errorf("json.Marshal:%s", err.Error())
 			return nil, fmt.Errorf("json.Marshal:%s", err.Error())
 		}
 		}
 		bodyStr = string(bodyBs)
 		bodyStr = string(bodyBs)

+ 0 - 0
alipay/alipay_client_test.go → alipay/client_test.go


+ 0 - 0
alipay/alipay_model.go → alipay/model.go


+ 0 - 0
alipay/alipay_params.go → alipay/param.go


+ 0 - 0
alipay/alipay_service_api.go → alipay/service_api.go


+ 33 - 10
body_map.go

@@ -3,16 +3,22 @@ package gopay
 import (
 import (
 	"encoding/json"
 	"encoding/json"
 	"encoding/xml"
 	"encoding/xml"
+	"errors"
 	"io"
 	"io"
 	"sort"
 	"sort"
 	"strings"
 	"strings"
+	"sync"
 )
 )
 
 
 type BodyMap map[string]interface{}
 type BodyMap map[string]interface{}
 
 
+var mu sync.RWMutex
+
 // 设置参数
 // 设置参数
 func (bm BodyMap) Set(key string, value interface{}) {
 func (bm BodyMap) Set(key string, value interface{}) {
+	mu.Lock()
 	bm[key] = value
 	bm[key] = value
+	mu.Unlock()
 }
 }
 
 
 // 获取参数
 // 获取参数
@@ -20,18 +26,17 @@ func (bm BodyMap) Get(key string) string {
 	if bm == nil {
 	if bm == nil {
 		return NULL
 		return NULL
 	}
 	}
-	var (
-		value interface{}
-		ok    bool
-		v     string
-	)
-	if value, ok = bm[key]; !ok {
+	mu.RLock()
+	defer mu.RUnlock()
+	value, ok := bm[key]
+	if !ok {
 		return NULL
 		return NULL
 	}
 	}
-	if v, ok = value.(string); ok {
-		return v
+	v, ok := value.(string)
+	if !ok {
+		return convertToString(value)
 	}
 	}
-	return convertToString(value)
+	return v
 }
 }
 
 
 func convertToString(v interface{}) (str string) {
 func convertToString(v interface{}) (str string) {
@@ -51,7 +56,9 @@ func convertToString(v interface{}) (str string) {
 
 
 // 删除参数
 // 删除参数
 func (bm BodyMap) Remove(key string) {
 func (bm BodyMap) Remove(key string) {
+	mu.Lock()
 	delete(bm, key)
 	delete(bm, key)
+	mu.Unlock()
 }
 }
 
 
 type xmlMapMarshal struct {
 type xmlMapMarshal struct {
@@ -100,10 +107,12 @@ func (bm BodyMap) EncodeWeChatSignParams(apiKey string) string {
 		buf     strings.Builder
 		buf     strings.Builder
 		keyList []string
 		keyList []string
 	)
 	)
+	mu.RLock()
 	for k := range bm {
 	for k := range bm {
 		keyList = append(keyList, k)
 		keyList = append(keyList, k)
 	}
 	}
 	sort.Strings(keyList)
 	sort.Strings(keyList)
+	mu.RUnlock()
 	for _, k := range keyList {
 	for _, k := range keyList {
 		if v := bm.Get(k); v != NULL {
 		if v := bm.Get(k); v != NULL {
 			buf.WriteString(k)
 			buf.WriteString(k)
@@ -124,11 +133,12 @@ func (bm BodyMap) EncodeAliPaySignParams() string {
 		buf     strings.Builder
 		buf     strings.Builder
 		keyList []string
 		keyList []string
 	)
 	)
-	keyList = make([]string, 0, len(bm))
+	mu.RLock()
 	for k := range bm {
 	for k := range bm {
 		keyList = append(keyList, k)
 		keyList = append(keyList, k)
 	}
 	}
 	sort.Strings(keyList)
 	sort.Strings(keyList)
+	mu.RUnlock()
 	for _, k := range keyList {
 	for _, k := range keyList {
 		if v := bm.Get(k); v != NULL {
 		if v := bm.Get(k); v != NULL {
 			buf.WriteString(k)
 			buf.WriteString(k)
@@ -139,3 +149,16 @@ func (bm BodyMap) EncodeAliPaySignParams() string {
 	}
 	}
 	return buf.String()[:buf.Len()-1]
 	return buf.String()[:buf.Len()-1]
 }
 }
+
+func (bm BodyMap) CheckEmptyError(keys ...string) error {
+	var emptyKeys []string
+	for _, k := range keys {
+		if v := bm.Get(k); v == NULL {
+			emptyKeys = append(emptyKeys, k)
+		}
+	}
+	if len(emptyKeys) > 0 {
+		return errors.New(strings.Join(emptyKeys, ", ") + " : cannot be empty")
+	}
+	return nil
+}

+ 20 - 0
gopay_test.go

@@ -0,0 +1,20 @@
+package gopay
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestBodyMap_CheckParamsNull(t *testing.T) {
+	bm := make(BodyMap)
+	bm.Set("name", "jerry")
+	bm.Set("age", 2)
+	bm.Set("phone", "")
+	bm.Set("pi", 3.14)
+
+	err := bm.CheckEmptyError("name", "age", "phone")
+	if err != nil {
+		fmt.Println("err:", err)
+		return
+	}
+}

+ 1 - 1
http_client.go

@@ -132,7 +132,7 @@ func (c *Client) EndStruct(v interface{}) (res *http.Response, errs []error) {
 	case TypeXML:
 	case TypeXML:
 		err := xml.Unmarshal(bs, &v)
 		err := xml.Unmarshal(bs, &v)
 		if err != nil {
 		if err != nil {
-			c.Errors = append(c.Errors, fmt.Errorf("xml.Unmarshal:%s", err.Error()))
+			c.Errors = append(c.Errors, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err.Error()))
 			return nil, c.Errors
 			return nil, c.Errors
 		}
 		}
 		return res, nil
 		return res, nil

+ 84 - 0
qq/client.go

@@ -0,0 +1,84 @@
+package qq
+
+import (
+	"crypto/tls"
+	"encoding/xml"
+	"errors"
+	"fmt"
+	"strings"
+	"sync"
+
+	"github.com/iGoogle-ink/gopay"
+)
+
+type Client struct {
+	MchId      string
+	ApiKey     string
+	CertFile   []byte
+	KeyFile    []byte
+	Pkcs12File []byte
+	IsProd     bool
+	mu         sync.RWMutex
+}
+
+// 初始化QQ客户端(正式环境)
+//    mchId:商户ID
+//    ApiKey:API秘钥值
+func NewClient(mchId, apiKey string) (client *Client) {
+	return &Client{
+		MchId:  mchId,
+		ApiKey: apiKey,
+	}
+}
+
+// 提交付款码支付
+//    文档地址:https://qpay.qq.com/buss/wiki/43/1157
+func (q *Client) MicroPay(bm gopay.BodyMap) (qqRsp *MicroPayResponse, err error) {
+	err = bm.CheckEmptyError("sub_mch_id", "nonce_str", "body", "out_trade_no", "total_fee", "spbill_create_ip", "device_info", "auth_code")
+	if err != nil {
+		return nil, err
+	}
+	if bm.Get("trade_type") == gopay.NULL {
+		bm.Set("trade_type", TradeType_MicroPay)
+	}
+	bs, err := q.doQQ(bm, qqMicroPay, nil)
+	if err != nil {
+		return nil, err
+	}
+	qqRsp = new(MicroPayResponse)
+	if err = xml.Unmarshal(bs, qqRsp); err != nil {
+		return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err.Error())
+	}
+	return qqRsp, nil
+}
+
+// 向QQ发送请求
+func (q *Client) doQQ(bm gopay.BodyMap, url string, tlsConfig *tls.Config) (bs []byte, err error) {
+	bm.Set("mch_id", q.MchId)
+	if bm.Get("fee_type") == gopay.NULL {
+		bm.Set("fee_type", "CNY")
+	}
+
+	if bm.Get("sign") == gopay.NULL {
+		var sign string
+		sign = getReleaseSign(q.ApiKey, bm.Get("sign_type"), bm)
+		bm.Set("sign", sign)
+	}
+
+	httpClient := gopay.NewHttpClient()
+	if tlsConfig != nil {
+		httpClient.SetTLSConfig(tlsConfig)
+	}
+
+	res, bs, errs := httpClient.Type(gopay.TypeXML).Post(url).SendString(generateXml(bm)).EndBytes()
+	if len(errs) > 0 {
+		return nil, errs[0]
+	}
+	if res.StatusCode != 200 {
+		return nil, fmt.Errorf("HTTP Request Error, StatusCode = %d", res.StatusCode)
+	}
+	if strings.Contains(string(bs), "HTML") {
+		return nil, errors.New(string(bs))
+	}
+	return bs, nil
+}

+ 42 - 0
qq/client_test.go

@@ -0,0 +1,42 @@
+package qq
+
+import (
+	"fmt"
+	"os"
+	"testing"
+
+	"github.com/iGoogle-ink/gopay"
+)
+
+var (
+	client *Client
+	mchId  = "1368139502"
+	apiKey = "GFDS8j98rewnmgl45wHTt980jg543abc"
+)
+
+func TestMain(m *testing.M) {
+
+	// 初始化QQ客户端
+	//    mchId:商户ID
+	//    apiKey:API秘钥值
+	client = NewClient(mchId, apiKey)
+
+	//err := client.AddCertFilePath("", "", "")
+	//if err != nil {
+	//	panic(err)
+	//}
+
+	os.Exit(m.Run())
+}
+
+func TestClient_MicroPay(t *testing.T) {
+	bm := make(gopay.BodyMap)
+	bm.Set("sub_mch_id", "1368139502")
+
+	qqRsp, err := client.MicroPay(bm)
+	if err != nil {
+		fmt.Println("err:", err)
+		return
+	}
+	fmt.Println("qqRsp:", *qqRsp)
+}

+ 57 - 0
qq/model.go

@@ -0,0 +1,57 @@
+package qq
+
+const (
+	// URL
+	qqUnifiedOrder  = "https://qpay.qq.com/cgi-bin/pay/qpay_unified_order.cgi"              // 统一下单
+	qqMicroPay      = "https://qpay.qq.com/cgi-bin/pay/qpay_micro_pay.cgi"                  // 提交付款码支付
+	qqOrderQuery    = "https://qpay.qq.com/cgi-bin/pay/qpay_order_query.cgi"                // 订单查询
+	qqOrderClose    = "https://qpay.qq.com/cgi-bin/pay/qpay_close_order.cgi"                // 关闭订单
+	qqRefundQuery   = "https://qpay.qq.com/cgi-bin/pay/qpay_refund_query.cgi"               // 退款查询
+	qqStatementDown = "https://qpay.qq.com/cgi-bin/sp_download/qpay_mch_statement_down.cgi" // 交易账单
+	qqAccRoll       = "https://qpay.qq.com/cgi-bin/sp_download/qpay_mch_acc_roll.cgi"       // 资金账单
+	qqReverse       = "https://api.qpay.qq.com/cgi-bin/pay/qpay_reverse.cgi"                // 撤销订单
+	qqRefund        = "https://api.qpay.qq.com/cgi-bin/pay/qpay_refund.cgi"                 // 申请退款
+
+	// 支付类型
+	TradeType_MicroPay = "MICROPAY" // 提交付款码支付
+	TradeType_JsApi    = "JSAPI"    // 公众号支付
+	TradeType_Native   = "NATIVE"   // 原生扫码支付
+	TradeType_App      = "APP"      // APP支付
+	TradeType_Mini     = "MINIAPP"  // QQ小程序支付
+
+	// 签名方式
+	SignType_MD5         = "MD5"
+	SignType_HMAC_SHA256 = "HMAC-SHA256"
+)
+
+type MicroPayResponse struct {
+	ReturnCode     string `xml:"return_code,omitempty" json:"return_code,omitempty"`
+	ReturnMsg      string `xml:"return_msg,omitempty" json:"return_msg,omitempty"`
+	RetCode        string `xml:"retcode,omitempty" json:"retcode,omitempty"`
+	RetMsg         string `xml:"retmsg,omitempty" json:"retmsg,omitempty"`
+	ResultCode     string `xml:"result_code,omitempty" json:"result_code,omitempty"`
+	ErrCode        string `xml:"err_code,omitempty" json:"err_code,omitempty"`
+	ErrCodeDes     string `xml:"err_code_des,omitempty" json:"err_code_des,omitempty"`
+	Sign           string `xml:"sign,omitempty" json:"sign,omitempty"`
+	Appid          string `xml:"appid,omitempty" json:"appid,omitempty"`
+	SubAppid       string `xml:"sub_appid,omitempty" json:"sub_appid,omitempty"`
+	MchId          string `xml:"mch_id,omitempty" json:"mch_id,omitempty"`
+	SubMchId       string `xml:"sub_mch_id,omitempty" json:"sub_mch_id,omitempty"`
+	NonceStr       string `xml:"nonce_str,omitempty" json:"nonce_str,omitempty"`
+	DeviceInfo     string `xml:"device_info,omitempty" json:"device_info,omitempty"`
+	TradeType      string `xml:"trade_type,omitempty" json:"trade_type,omitempty"`
+	TradeState     string `xml:"trade_state,omitempty" json:"trade_state,omitempty"`
+	BankType       string `xml:"bank_type,omitempty" json:"bank_type,omitempty"`
+	FeeType        string `xml:"fee_type,omitempty" json:"fee_type,omitempty"`
+	TotalFee       int    `xml:"total_fee,omitempty" json:"total_fee,omitempty"`
+	CashFee        int    `xml:"cash_fee,omitempty" json:"cash_fee,omitempty"`
+	CouponFee0     int    `xml:"coupon_fee_0,omitempty" json:"coupon_fee_0,omitempty"`
+	CouponFee1     int    `xml:"coupon_fee_1,omitempty" json:"coupon_fee_1,omitempty"`
+	TransactionId  string `xml:"transaction_id,omitempty" json:"transaction_id,omitempty"`
+	OutTradeNo     string `xml:"out_trade_no,omitempty" json:"out_trade_no,omitempty"`
+	Attach         string `xml:"attach,omitempty" json:"attach,omitempty"`
+	TimeEnd        string `xml:"time_end,omitempty" json:"time_end,omitempty"`
+	TradeStateDesc string `xml:"trade_state_desc,omitempty" json:"trade_state_desc,omitempty"`
+	Openid         string `xml:"openid,omitempty" json:"openid,omitempty"`
+	SubOpenid      string `xml:"sub_openid,omitempty" json:"sub_openid,omitempty"`
+}

+ 73 - 0
qq/param.go

@@ -0,0 +1,73 @@
+package qq
+
+import (
+	"crypto/hmac"
+	"crypto/md5"
+	"crypto/sha256"
+	"encoding/hex"
+	"encoding/xml"
+	"hash"
+	"io/ioutil"
+	"strings"
+
+	"github.com/iGoogle-ink/gopay"
+)
+
+// 添加QQ证书 Byte 数组
+//    certFile:apiclient_cert.pem byte数组
+//    keyFile:apiclient_key.pem byte数组
+//    pkcs12File:apiclient_cert.p12 byte数组
+func (w *Client) AddCertFileByte(certFile, keyFile, pkcs12File []byte) {
+	w.mu.Lock()
+	w.CertFile = certFile
+	w.KeyFile = keyFile
+	w.Pkcs12File = pkcs12File
+	w.mu.Unlock()
+}
+
+// 添加QQ证书 Path 路径
+//    certFilePath:apiclient_cert.pem 路径
+//    keyFilePath:apiclient_key.pem 路径
+//    pkcs12FilePath:apiclient_cert.p12 路径
+//    返回err
+func (w *Client) AddCertFilePath(certFilePath, keyFilePath, pkcs12FilePath string) (err error) {
+	cert, err := ioutil.ReadFile(certFilePath)
+	if err != nil {
+		return err
+	}
+	key, err := ioutil.ReadFile(keyFilePath)
+	if err != nil {
+		return err
+	}
+	pkcs, err := ioutil.ReadFile(pkcs12FilePath)
+	if err != nil {
+		return err
+	}
+	w.mu.Lock()
+	w.CertFile = cert
+	w.KeyFile = key
+	w.Pkcs12File = pkcs
+	w.mu.Unlock()
+	return nil
+}
+
+// 生成请求XML的Body体
+func generateXml(bm gopay.BodyMap) (reqXml string) {
+	bs, err := xml.Marshal(bm)
+	if err != nil {
+		return gopay.NULL
+	}
+	return string(bs)
+}
+
+// 获取QQ支付正式环境Sign值
+func getReleaseSign(apiKey string, signType string, bm gopay.BodyMap) (sign string) {
+	var h hash.Hash
+	if signType == SignType_HMAC_SHA256 {
+		h = hmac.New(sha256.New, []byte(apiKey))
+	} else {
+		h = md5.New()
+	}
+	h.Write([]byte(bm.EncodeWeChatSignParams(apiKey)))
+	return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
+}

+ 0 - 1
qq/qq_client.go

@@ -1 +0,0 @@
-package qq

+ 56 - 56
wechat/wechat_client.go → wechat/client.go

@@ -38,77 +38,77 @@ func NewClient(appId, mchId, apiKey string, isProd bool) (client *Client) {
 
 
 // 提交付款码支付
 // 提交付款码支付
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1
-func (w *Client) Micropay(body gopay.BodyMap) (wxRsp *MicropayResponse, err error) {
+func (w *Client) Micropay(bm gopay.BodyMap) (wxRsp *MicropayResponse, err error) {
 	var bs []byte
 	var bs []byte
 	if w.IsProd {
 	if w.IsProd {
-		bs, err = w.doWeChat(body, wxMicropay)
+		bs, err = w.doWeChat(bm, wxMicropay, nil)
 	} else {
 	} else {
-		bs, err = w.doWeChat(body, wxSandboxMicropay)
+		bs, err = w.doWeChat(bm, wxSandboxMicropay, nil)
 	}
 	}
 	if err != nil {
 	if err != nil {
 		return
 		return
 	}
 	}
 	wxRsp = new(MicropayResponse)
 	wxRsp = new(MicropayResponse)
 	if err = xml.Unmarshal(bs, wxRsp); err != nil {
 	if err = xml.Unmarshal(bs, wxRsp); err != nil {
-		return nil, fmt.Errorf("xml.Unmarshal:%s", err.Error())
+		return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err.Error())
 	}
 	}
 	return
 	return
 }
 }
 
 
 // 统一下单
 // 统一下单
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
-func (w *Client) UnifiedOrder(body gopay.BodyMap) (wxRsp *UnifiedOrderResponse, err error) {
+func (w *Client) UnifiedOrder(bm gopay.BodyMap) (wxRsp *UnifiedOrderResponse, err error) {
 	var bs []byte
 	var bs []byte
 	if w.IsProd {
 	if w.IsProd {
-		bs, err = w.doWeChat(body, wxUnifiedorder)
+		bs, err = w.doWeChat(bm, wxUnifiedorder, nil)
 	} else {
 	} else {
-		body.Set("total_fee", 101)
-		bs, err = w.doWeChat(body, wxSandboxUnifiedorder)
+		bm.Set("total_fee", 101)
+		bs, err = w.doWeChat(bm, wxSandboxUnifiedorder, nil)
 	}
 	}
 	if err != nil {
 	if err != nil {
 		return
 		return
 	}
 	}
 	wxRsp = new(UnifiedOrderResponse)
 	wxRsp = new(UnifiedOrderResponse)
 	if err = xml.Unmarshal(bs, wxRsp); err != nil {
 	if err = xml.Unmarshal(bs, wxRsp); err != nil {
-		return nil, fmt.Errorf("xml.Unmarshal:%s", err.Error())
+		return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err.Error())
 	}
 	}
 	return
 	return
 }
 }
 
 
 // 查询订单
 // 查询订单
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2
-func (w *Client) QueryOrder(body gopay.BodyMap) (wxRsp *QueryOrderResponse, err error) {
+func (w *Client) QueryOrder(bm gopay.BodyMap) (wxRsp *QueryOrderResponse, err error) {
 	var bs []byte
 	var bs []byte
 	if w.IsProd {
 	if w.IsProd {
-		bs, err = w.doWeChat(body, wxOrderquery)
+		bs, err = w.doWeChat(bm, wxOrderquery, nil)
 	} else {
 	} else {
-		bs, err = w.doWeChat(body, wxSandboxOrderquery)
+		bs, err = w.doWeChat(bm, wxSandboxOrderquery, nil)
 	}
 	}
 	if err != nil {
 	if err != nil {
 		return
 		return
 	}
 	}
 	wxRsp = new(QueryOrderResponse)
 	wxRsp = new(QueryOrderResponse)
 	if err = xml.Unmarshal(bs, wxRsp); err != nil {
 	if err = xml.Unmarshal(bs, wxRsp); err != nil {
-		return nil, fmt.Errorf("xml.Unmarshal:%s", err.Error())
+		return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err.Error())
 	}
 	}
 	return
 	return
 }
 }
 
 
 // 关闭订单
 // 关闭订单
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3
-func (w *Client) CloseOrder(body gopay.BodyMap) (wxRsp *CloseOrderResponse, err error) {
+func (w *Client) CloseOrder(bm gopay.BodyMap) (wxRsp *CloseOrderResponse, err error) {
 	var bs []byte
 	var bs []byte
 	if w.IsProd {
 	if w.IsProd {
-		bs, err = w.doWeChat(body, wxCloseorder)
+		bs, err = w.doWeChat(bm, wxCloseorder, nil)
 	} else {
 	} else {
-		bs, err = w.doWeChat(body, wxSandboxCloseorder)
+		bs, err = w.doWeChat(bm, wxSandboxCloseorder, nil)
 	}
 	}
 	if err != nil {
 	if err != nil {
 		return
 		return
 	}
 	}
 	wxRsp = new(CloseOrderResponse)
 	wxRsp = new(CloseOrderResponse)
 	if err = xml.Unmarshal(bs, wxRsp); err != nil {
 	if err = xml.Unmarshal(bs, wxRsp); err != nil {
-		return nil, fmt.Errorf("xml.Unmarshal:%s", err.Error())
+		return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err.Error())
 	}
 	}
 	return
 	return
 }
 }
@@ -116,7 +116,7 @@ func (w *Client) CloseOrder(body gopay.BodyMap) (wxRsp *CloseOrderResponse, err
 // 撤销订单
 // 撤销订单
 //    注意:如已使用client.AddCertFilePath()或client.AddCertFileByte()添加过证书,参数certFilePath、keyFilePath、pkcs12FilePath全传空字符串 "",如方法需单独使用证书,则传证书Path
 //    注意:如已使用client.AddCertFilePath()或client.AddCertFileByte()添加过证书,参数certFilePath、keyFilePath、pkcs12FilePath全传空字符串 "",如方法需单独使用证书,则传证书Path
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3
-func (w *Client) Reverse(body gopay.BodyMap, certFilePath, keyFilePath, pkcs12FilePath string) (wxRsp *ReverseResponse, err error) {
+func (w *Client) Reverse(bm gopay.BodyMap, certFilePath, keyFilePath, pkcs12FilePath string) (wxRsp *ReverseResponse, err error) {
 	var (
 	var (
 		bs        []byte
 		bs        []byte
 		tlsConfig *tls.Config
 		tlsConfig *tls.Config
@@ -125,16 +125,16 @@ func (w *Client) Reverse(body gopay.BodyMap, certFilePath, keyFilePath, pkcs12Fi
 		if tlsConfig, err = w.addCertConfig(certFilePath, keyFilePath, pkcs12FilePath); err != nil {
 		if tlsConfig, err = w.addCertConfig(certFilePath, keyFilePath, pkcs12FilePath); err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
-		bs, err = w.doWeChat(body, wxReverse, tlsConfig)
+		bs, err = w.doWeChat(bm, wxReverse, tlsConfig)
 	} else {
 	} else {
-		bs, err = w.doWeChat(body, wxSandboxReverse)
+		bs, err = w.doWeChat(bm, wxSandboxReverse, nil)
 	}
 	}
 	if err != nil {
 	if err != nil {
 		return
 		return
 	}
 	}
 	wxRsp = new(ReverseResponse)
 	wxRsp = new(ReverseResponse)
 	if err = xml.Unmarshal(bs, wxRsp); err != nil {
 	if err = xml.Unmarshal(bs, wxRsp); err != nil {
-		return nil, fmt.Errorf("xml.Unmarshal:%s", err.Error())
+		return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err.Error())
 	}
 	}
 	return
 	return
 }
 }
@@ -142,7 +142,7 @@ func (w *Client) Reverse(body gopay.BodyMap, certFilePath, keyFilePath, pkcs12Fi
 // 申请退款
 // 申请退款
 //    注意:如已使用client.AddCertFilePath()或client.AddCertFileByte()添加过证书,参数certFilePath、keyFilePath、pkcs12FilePath全传空字符串 "",如方法需单独使用证书,则传证书Path
 //    注意:如已使用client.AddCertFilePath()或client.AddCertFileByte()添加过证书,参数certFilePath、keyFilePath、pkcs12FilePath全传空字符串 "",如方法需单独使用证书,则传证书Path
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
-func (w *Client) Refund(body gopay.BodyMap, certFilePath, keyFilePath, pkcs12FilePath string) (wxRsp *RefundResponse, err error) {
+func (w *Client) Refund(bm gopay.BodyMap, certFilePath, keyFilePath, pkcs12FilePath string) (wxRsp *RefundResponse, err error) {
 	var (
 	var (
 		bs        []byte
 		bs        []byte
 		tlsConfig *tls.Config
 		tlsConfig *tls.Config
@@ -151,47 +151,47 @@ func (w *Client) Refund(body gopay.BodyMap, certFilePath, keyFilePath, pkcs12Fil
 		if tlsConfig, err = w.addCertConfig(certFilePath, keyFilePath, pkcs12FilePath); err != nil {
 		if tlsConfig, err = w.addCertConfig(certFilePath, keyFilePath, pkcs12FilePath); err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
-		bs, err = w.doWeChat(body, wxRefund, tlsConfig)
+		bs, err = w.doWeChat(bm, wxRefund, tlsConfig)
 	} else {
 	} else {
-		bs, err = w.doWeChat(body, wxSandboxRefund)
+		bs, err = w.doWeChat(bm, wxSandboxRefund, nil)
 	}
 	}
 	if err != nil {
 	if err != nil {
 		return
 		return
 	}
 	}
 	wxRsp = new(RefundResponse)
 	wxRsp = new(RefundResponse)
 	if err = xml.Unmarshal(bs, wxRsp); err != nil {
 	if err = xml.Unmarshal(bs, wxRsp); err != nil {
-		return nil, fmt.Errorf("xml.Unmarshal:%s", err.Error())
+		return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err.Error())
 	}
 	}
 	return
 	return
 }
 }
 
 
 // 查询退款
 // 查询退款
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5
-func (w *Client) QueryRefund(body gopay.BodyMap) (wxRsp *QueryRefundResponse, err error) {
+func (w *Client) QueryRefund(bm gopay.BodyMap) (wxRsp *QueryRefundResponse, err error) {
 	var bs []byte
 	var bs []byte
 	if w.IsProd {
 	if w.IsProd {
-		bs, err = w.doWeChat(body, wxRefundquery)
+		bs, err = w.doWeChat(bm, wxRefundquery, nil)
 	} else {
 	} else {
-		bs, err = w.doWeChat(body, wxSandboxRefundquery)
+		bs, err = w.doWeChat(bm, wxSandboxRefundquery, nil)
 	}
 	}
 	if err != nil {
 	if err != nil {
 		return
 		return
 	}
 	}
 	wxRsp = new(QueryRefundResponse)
 	wxRsp = new(QueryRefundResponse)
 	if err = xml.Unmarshal(bs, wxRsp); err != nil {
 	if err = xml.Unmarshal(bs, wxRsp); err != nil {
-		return nil, fmt.Errorf("xml.Unmarshal:%s", err.Error())
+		return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err.Error())
 	}
 	}
 	return
 	return
 }
 }
 
 
 // 下载对账单
 // 下载对账单
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6
-func (w *Client) DownloadBill(body gopay.BodyMap) (wxRsp string, err error) {
+func (w *Client) DownloadBill(bm gopay.BodyMap) (wxRsp string, err error) {
 	var bs []byte
 	var bs []byte
 	if w.IsProd {
 	if w.IsProd {
-		bs, err = w.doWeChat(body, wxDownloadbill)
+		bs, err = w.doWeChat(bm, wxDownloadbill, nil)
 	} else {
 	} else {
-		bs, err = w.doWeChat(body, wxSandboxDownloadbill)
+		bs, err = w.doWeChat(bm, wxSandboxDownloadbill, nil)
 	}
 	}
 	if err != nil {
 	if err != nil {
 		return
 		return
@@ -204,7 +204,7 @@ func (w *Client) DownloadBill(body gopay.BodyMap) (wxRsp string, err error) {
 //    注意:如已使用client.AddCertFilePath()或client.AddCertFileByte()添加过证书,参数certFilePath、keyFilePath、pkcs12FilePath全传空字符串 "",如方法需单独使用证书,则传证书Path
 //    注意:如已使用client.AddCertFilePath()或client.AddCertFileByte()添加过证书,参数certFilePath、keyFilePath、pkcs12FilePath全传空字符串 "",如方法需单独使用证书,则传证书Path
 //    貌似不支持沙箱环境,因为沙箱环境默认需要用MD5签名,但是此接口仅支持HMAC-SHA256签名
 //    貌似不支持沙箱环境,因为沙箱环境默认需要用MD5签名,但是此接口仅支持HMAC-SHA256签名
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_18&index=7
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_18&index=7
-func (w *Client) DownloadFundFlow(body gopay.BodyMap, certFilePath, keyFilePath, pkcs12FilePath string) (wxRsp string, err error) {
+func (w *Client) DownloadFundFlow(bm gopay.BodyMap, certFilePath, keyFilePath, pkcs12FilePath string) (wxRsp string, err error) {
 	var (
 	var (
 		bs        []byte
 		bs        []byte
 		tlsConfig *tls.Config
 		tlsConfig *tls.Config
@@ -213,9 +213,9 @@ func (w *Client) DownloadFundFlow(body gopay.BodyMap, certFilePath, keyFilePath,
 		if tlsConfig, err = w.addCertConfig(certFilePath, keyFilePath, pkcs12FilePath); err != nil {
 		if tlsConfig, err = w.addCertConfig(certFilePath, keyFilePath, pkcs12FilePath); err != nil {
 			return gopay.NULL, err
 			return gopay.NULL, err
 		}
 		}
-		bs, err = w.doWeChat(body, wxDownloadfundflow, tlsConfig)
+		bs, err = w.doWeChat(bm, wxDownloadfundflow, tlsConfig)
 	} else {
 	} else {
-		bs, err = w.doWeChat(body, wxSandboxDownloadfundflow)
+		bs, err = w.doWeChat(bm, wxSandboxDownloadfundflow, nil)
 	}
 	}
 	if err != nil {
 	if err != nil {
 		return
 		return
@@ -228,19 +228,19 @@ func (w *Client) DownloadFundFlow(body gopay.BodyMap, certFilePath, keyFilePath,
 //    注意:如已使用client.AddCertFilePath()或client.AddCertFileByte()添加过证书,参数certFilePath、keyFilePath、pkcs12FilePath全传空字符串 "",如方法需单独使用证书,则传证书Path
 //    注意:如已使用client.AddCertFilePath()或client.AddCertFileByte()添加过证书,参数certFilePath、keyFilePath、pkcs12FilePath全传空字符串 "",如方法需单独使用证书,则传证书Path
 //    貌似不支持沙箱环境,因为沙箱环境默认需要用MD5签名,但是此接口仅支持HMAC-SHA256签名
 //    貌似不支持沙箱环境,因为沙箱环境默认需要用MD5签名,但是此接口仅支持HMAC-SHA256签名
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_17&index=11
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_17&index=11
-func (w *Client) BatchQueryComment(body gopay.BodyMap, certFilePath, keyFilePath, pkcs12FilePath string) (wxRsp string, err error) {
+func (w *Client) BatchQueryComment(bm gopay.BodyMap, certFilePath, keyFilePath, pkcs12FilePath string) (wxRsp string, err error) {
 	var (
 	var (
 		bs        []byte
 		bs        []byte
 		tlsConfig *tls.Config
 		tlsConfig *tls.Config
 	)
 	)
 	if w.IsProd {
 	if w.IsProd {
-		body.Set("sign_type", SignType_HMAC_SHA256)
+		bm.Set("sign_type", SignType_HMAC_SHA256)
 		if tlsConfig, err = w.addCertConfig(certFilePath, keyFilePath, pkcs12FilePath); err != nil {
 		if tlsConfig, err = w.addCertConfig(certFilePath, keyFilePath, pkcs12FilePath); err != nil {
 			return gopay.NULL, err
 			return gopay.NULL, err
 		}
 		}
-		bs, err = w.doWeChat(body, wxBatchquerycomment, tlsConfig)
+		bs, err = w.doWeChat(bm, wxBatchquerycomment, tlsConfig)
 	} else {
 	} else {
-		bs, err = w.doWeChat(body, wxSandboxBatchquerycomment)
+		bs, err = w.doWeChat(bm, wxSandboxBatchquerycomment, nil)
 	}
 	}
 	if err != nil {
 	if err != nil {
 		return
 		return
@@ -253,12 +253,12 @@ func (w *Client) BatchQueryComment(body gopay.BodyMap, certFilePath, keyFilePath
 //    注意:如已使用client.AddCertFilePath()或client.AddCertFileByte()添加过证书,参数certFilePath、keyFilePath、pkcs12FilePath全传空字符串 "",如方法需单独使用证书,则传证书Path
 //    注意:如已使用client.AddCertFilePath()或client.AddCertFileByte()添加过证书,参数certFilePath、keyFilePath、pkcs12FilePath全传空字符串 "",如方法需单独使用证书,则传证书Path
 //    注意:此方法未支持沙箱环境,默认正式环境,转账请慎重
 //    注意:此方法未支持沙箱环境,默认正式环境,转账请慎重
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1
-func (w *Client) Transfer(body gopay.BodyMap, certFilePath, keyFilePath, pkcs12FilePath string) (wxRsp *TransfersResponse, err error) {
+func (w *Client) Transfer(bm gopay.BodyMap, certFilePath, keyFilePath, pkcs12FilePath string) (wxRsp *TransfersResponse, err error) {
 	if certFilePath == gopay.NULL || keyFilePath == gopay.NULL || pkcs12FilePath == gopay.NULL {
 	if certFilePath == gopay.NULL || keyFilePath == gopay.NULL || pkcs12FilePath == gopay.NULL {
 		return nil, errors.New("cert file path not allow to input null")
 		return nil, errors.New("cert file path not allow to input null")
 	}
 	}
-	body.Set("mch_appid", w.AppId)
-	body.Set("mchid", w.MchId)
+	bm.Set("mch_appid", w.AppId)
+	bm.Set("mchid", w.MchId)
 	var (
 	var (
 		tlsConfig *tls.Config
 		tlsConfig *tls.Config
 		url       = wxBaseUrlCh + wxTransfers
 		url       = wxBaseUrlCh + wxTransfers
@@ -266,7 +266,7 @@ func (w *Client) Transfer(body gopay.BodyMap, certFilePath, keyFilePath, pkcs12F
 	if tlsConfig, err = w.addCertConfig(certFilePath, keyFilePath, pkcs12FilePath); err != nil {
 	if tlsConfig, err = w.addCertConfig(certFilePath, keyFilePath, pkcs12FilePath); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	body.Set("sign", getReleaseSign(w.ApiKey, SignType_MD5, body))
+	bm.Set("sign", getReleaseSign(w.ApiKey, SignType_MD5, bm))
 
 
 	httpClient := gopay.NewHttpClient().SetTLSConfig(tlsConfig).Type(gopay.TypeXML)
 	httpClient := gopay.NewHttpClient().SetTLSConfig(tlsConfig).Type(gopay.TypeXML)
 	if w.BaseURL != gopay.NULL {
 	if w.BaseURL != gopay.NULL {
@@ -275,7 +275,7 @@ func (w *Client) Transfer(body gopay.BodyMap, certFilePath, keyFilePath, pkcs12F
 		w.mu.RUnlock()
 		w.mu.RUnlock()
 	}
 	}
 	wxRsp = new(TransfersResponse)
 	wxRsp = new(TransfersResponse)
-	res, errs := httpClient.Post(url).SendString(generateXml(body)).EndStruct(wxRsp)
+	res, errs := httpClient.Post(url).SendString(generateXml(bm)).EndStruct(wxRsp)
 	if len(errs) > 0 {
 	if len(errs) > 0 {
 		return nil, errs[0]
 		return nil, errs[0]
 	}
 	}
@@ -287,35 +287,35 @@ func (w *Client) Transfer(body gopay.BodyMap, certFilePath, keyFilePath, pkcs12F
 
 
 // 公众号纯签约(未完成)
 // 公众号纯签约(未完成)
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_1&index=1
 //    文档地址:https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_1&index=1
-func (w *Client) EntrustPublic(body gopay.BodyMap) (bs []byte, err error) {
-	bs, err = w.doWeChat(body, wxEntrustPublic)
+func (w *Client) EntrustPublic(bm gopay.BodyMap) (bs []byte, err error) {
+	bs, err = w.doWeChat(bm, wxEntrustPublic, nil)
 
 
 	return nil, nil
 	return nil, nil
 }
 }
 
 
 // 向微信发送请求
 // 向微信发送请求
-func (w *Client) doWeChat(body gopay.BodyMap, path string, tlsConfig ...*tls.Config) (bs []byte, err error) {
+func (w *Client) doWeChat(bm gopay.BodyMap, path string, tlsConfig *tls.Config) (bs []byte, err error) {
 	var url = wxBaseUrlCh + path
 	var url = wxBaseUrlCh + path
-	body.Set("appid", w.AppId)
-	body.Set("mch_id", w.MchId)
+	bm.Set("appid", w.AppId)
+	bm.Set("mch_id", w.MchId)
 
 
-	if body.Get("sign") == gopay.NULL {
+	if bm.Get("sign") == gopay.NULL {
 		var sign string
 		var sign string
 		if !w.IsProd {
 		if !w.IsProd {
-			body.Set("sign_type", SignType_MD5)
-			sign, err = getSignBoxSign(w.MchId, w.ApiKey, body)
+			bm.Set("sign_type", SignType_MD5)
+			sign, err = getSignBoxSign(w.MchId, w.ApiKey, bm)
 			if err != nil {
 			if err != nil {
 				return nil, err
 				return nil, err
 			}
 			}
 		} else {
 		} else {
-			sign = getReleaseSign(w.ApiKey, body.Get("sign_type"), body)
+			sign = getReleaseSign(w.ApiKey, bm.Get("sign_type"), bm)
 		}
 		}
-		body.Set("sign", sign)
+		bm.Set("sign", sign)
 	}
 	}
 
 
 	httpClient := gopay.NewHttpClient()
 	httpClient := gopay.NewHttpClient()
 	if w.IsProd && tlsConfig != nil {
 	if w.IsProd && tlsConfig != nil {
-		httpClient.SetTLSConfig(tlsConfig[0])
+		httpClient.SetTLSConfig(tlsConfig)
 	}
 	}
 
 
 	if w.BaseURL != gopay.NULL {
 	if w.BaseURL != gopay.NULL {
@@ -324,7 +324,7 @@ func (w *Client) doWeChat(body gopay.BodyMap, path string, tlsConfig ...*tls.Con
 		w.mu.RUnlock()
 		w.mu.RUnlock()
 	}
 	}
 
 
-	res, bs, errs := httpClient.Type(gopay.TypeXML).Post(url).SendString(generateXml(body)).EndBytes()
+	res, bs, errs := httpClient.Type(gopay.TypeXML).Post(url).SendString(generateXml(bm)).EndBytes()
 	if len(errs) > 0 {
 	if len(errs) > 0 {
 		return nil, errs[0]
 		return nil, errs[0]
 	}
 	}

+ 0 - 0
wechat/wechat_client_test.go → wechat/client_test.go


+ 5 - 5
wechat/wechat_model.go → wechat/model.go

@@ -47,11 +47,11 @@ const (
 	wxSandboxBatchquerycomment = "sandboxnew/billcommentsp/batchquerycomment"
 	wxSandboxBatchquerycomment = "sandboxnew/billcommentsp/batchquerycomment"
 
 
 	// 支付类型
 	// 支付类型
-	TradeType_Mini   = "JSAPI"
-	TradeType_JsApi  = "JSAPI"
-	TradeType_App    = "APP"
-	TradeType_H5     = "MWEB"
-	TradeType_Native = "NATIVE"
+	TradeType_Mini   = "JSAPI"  // 小程序支付
+	TradeType_JsApi  = "JSAPI"  // JSAPI支付
+	TradeType_App    = "APP"    // app支付
+	TradeType_H5     = "MWEB"   // H5支付
+	TradeType_Native = "NATIVE" // Native支付
 
 
 	// 签名方式
 	// 签名方式
 	SignType_MD5         = "MD5"
 	SignType_MD5         = "MD5"

+ 11 - 12
wechat/wechat_params.go → wechat/param.go

@@ -58,24 +58,24 @@ func (w *Client) AddCertFileByte(certFile, keyFile, pkcs12File []byte) {
 //    pkcs12FilePath:apiclient_cert.p12 路径
 //    pkcs12FilePath:apiclient_cert.p12 路径
 //    返回err
 //    返回err
 func (w *Client) AddCertFilePath(certFilePath, keyFilePath, pkcs12FilePath string) (err error) {
 func (w *Client) AddCertFilePath(certFilePath, keyFilePath, pkcs12FilePath string) (err error) {
-	var (
-		cert, key, pkcs []byte
-	)
-	if cert, err = ioutil.ReadFile(certFilePath); err != nil {
-		return
+	cert, err := ioutil.ReadFile(certFilePath)
+	if err != nil {
+		return err
 	}
 	}
-	if key, err = ioutil.ReadFile(keyFilePath); err != nil {
-		return
+	key, err := ioutil.ReadFile(keyFilePath)
+	if err != nil {
+		return err
 	}
 	}
-	if pkcs, err = ioutil.ReadFile(pkcs12FilePath); err != nil {
-		return
+	pkcs, err := ioutil.ReadFile(pkcs12FilePath)
+	if err != nil {
+		return err
 	}
 	}
 	w.mu.Lock()
 	w.mu.Lock()
 	w.CertFile = cert
 	w.CertFile = cert
 	w.KeyFile = key
 	w.KeyFile = key
 	w.Pkcs12File = pkcs
 	w.Pkcs12File = pkcs
 	w.mu.Unlock()
 	w.mu.Unlock()
-	return
+	return nil
 }
 }
 
 
 func (w *Client) addCertConfig(certFilePath, keyFilePath, pkcs12FilePath string) (tlsConfig *tls.Config, err error) {
 func (w *Client) addCertConfig(certFilePath, keyFilePath, pkcs12FilePath string) (tlsConfig *tls.Config, err error) {
@@ -127,8 +127,7 @@ func getReleaseSign(apiKey string, signType string, bm gopay.BodyMap) (sign stri
 		h = md5.New()
 		h = md5.New()
 	}
 	}
 	h.Write([]byte(bm.EncodeWeChatSignParams(apiKey)))
 	h.Write([]byte(bm.EncodeWeChatSignParams(apiKey)))
-	sign = strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
-	return
+	return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
 }
 }
 
 
 // 获取微信支付沙箱环境Sign值
 // 获取微信支付沙箱环境Sign值

+ 2 - 2
wechat/wechat_service_api.go → wechat/service_api.go

@@ -84,7 +84,7 @@ func ParseNotifyResultToBodyMap(req *http.Request) (bm gopay.BodyMap, err error)
 	}
 	}
 	bm = make(gopay.BodyMap)
 	bm = make(gopay.BodyMap)
 	if err = xml.Unmarshal(bs, &bm); err != nil {
 	if err = xml.Unmarshal(bs, &bm); err != nil {
-		return nil, fmt.Errorf("xml.Unmarshal:%s", err.Error())
+		return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err.Error())
 	}
 	}
 	return
 	return
 }
 }
@@ -154,7 +154,7 @@ func DecryptRefundNotifyReqInfo(reqInfo, apiKey string) (refundNotify *RefundNot
 	bs = gopay.PKCS7UnPadding(encryptionB)
 	bs = gopay.PKCS7UnPadding(encryptionB)
 	refundNotify = new(RefundNotify)
 	refundNotify = new(RefundNotify)
 	if err = xml.Unmarshal(bs, refundNotify); err != nil {
 	if err = xml.Unmarshal(bs, refundNotify); err != nil {
-		return nil, fmt.Errorf("xml.Unmarshal:%s", err.Error())
+		return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err.Error())
 	}
 	}
 	return
 	return
 }
 }