蛋蛋星球-制度模式
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wechat_v2.md 11 KiB

1 month ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. ## 微信v2
  2. > #### 推荐使用v3接口,官方在v3接口实现未覆盖或gopay未开发的接口,还继续用v2接口。
  3. - 已实现API列表附录:[API 列表附录](https://github.com/go-pay/gopay/blob/main/doc/wechat_v2.md#%E9%99%84%E5%BD%95)
  4. ---
  5. ### 1、初始化微信v2客户端并做配置
  6. 微信v2官方文档:[微信v2官方文档](https://pay.weixin.qq.com/wiki/doc/api/index.html)
  7. > 注意:微信支付下单等操作可用沙箱环境测试是否成功,但真正支付时,请使用正式环境 `isProd = true`,不然会报错。
  8. > 微信证书二选一:只传 `apiclient_cert.pem` 和 `apiclient_key.pem` 或者只传 `apiclient_cert.p12`
  9. ```go
  10. import (
  11. "github.com/go-pay/gopay/wechat"
  12. )
  13. // 初始化微信客户端
  14. // appId:应用ID
  15. // mchId:商户ID
  16. // apiKey:API秘钥值
  17. // isProd:是否是正式环境
  18. client := wechat.NewClient("wxdaa2ab9ef87b5497", mchId, apiKey, false)
  19. // 打开Debug开关,输出请求日志,默认关闭
  20. client.DebugSwitch = gopay.DebugOn
  21. // 自定义配置http请求接收返回结果body大小,默认 10MB
  22. client.SetBodySize() // 没有特殊需求,可忽略此配置
  23. // 设置国家:不设置默认 中国国内
  24. // wechat.China:中国国内
  25. // wechat.China2:中国国内备用
  26. // wechat.SoutheastAsia:东南亚
  27. // wechat.Other:其他国家
  28. client.SetCountry(wechat.China)
  29. // 添加微信pem证书
  30. client.AddCertPemFilePath()
  31. client.AddCertPemFileContent()
  32. // 添加微信pkcs12证书
  33. client.AddCertPkcs12FilePath()
  34. client.AddCertPkcs12FileContent()
  35. ```
  36. ### 2、API 方法调用及入参
  37. - #### 微信请求参数
  38. > 微信V2接口通用参数(mch_id、appid、sign)无需传入,client 请求时会默认处理
  39. 具体参数请根据不同接口查看:[微信支付接口文档](https://pay.weixin.qq.com/wiki/doc/api/index.html)
  40. ```go
  41. import (
  42. "github.com/go-pay/util"
  43. "github.com/go-pay/gopay/wechat"
  44. )
  45. // 初始化 BodyMap
  46. bm := make(gopay.BodyMap)
  47. bm.Set("nonce_str", util.RandomString(32)).
  48. Set("body", "H5支付").
  49. Set("out_trade_no", number).
  50. Set("total_fee", 1).
  51. Set("spbill_create_ip", "127.0.0.1").
  52. Set("notify_url", "https://www.fmm.ink").
  53. Set("trade_type", TradeType_H5).
  54. Set("device_info", "WEB").
  55. Set("sign_type", SignType_MD5).
  56. SetBodyMap("scene_info", func(bm gopay.BodyMap) {
  57. bm.SetBodyMap("h5_info", func(bm gopay.BodyMap) {
  58. bm.Set("type", "Wap")
  59. bm.Set("wap_url", "https://www.fmm.ink")
  60. bm.Set("wap_name", "H5测试支付")
  61. })
  62. }) /*.Set("openid", "o0Df70H2Q0fY8JXh1aFPIRyOBgu8")*/
  63. ```
  64. - #### client 方法调用
  65. ```go
  66. wxRsp, err := client.UnifiedOrder(bm)
  67. wxRsp, err := client.Micropay(bm)
  68. wxRsp, err := client.QueryOrder(bm)
  69. wxRsp, err := client.CloseOrder(bm)
  70. wxRsp, err := client.Reverse(bm)
  71. wxRsp, err := client.Refund(bm)
  72. wxRsp, err := client.QueryRefund(bm)
  73. wxRsp, err := client.DownloadBill(bm)
  74. wxRsp, err := client.DownloadFundFlow(bm)
  75. wxRsp, err := client.BatchQueryComment(bm)
  76. wxRsp, err := client.Transfer(bm)
  77. ...
  78. ```
  79. ### 3、微信统一下单后,获取微信小程序支付、APP支付、微信内H5支付所需要的 paySign
  80. > 微信小程序支付官方文档:[微信小程序支付API](https://developers.weixin.qq.com/miniprogram/dev/api/open-api/payment/wx.requestPayment.html)
  81. > APP支付官方文档:[APP端调起支付的参数列表文档](https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12)
  82. > 微信内H5支付官方文档:[微信内H5支付文档](https://pay.weixin.qq.com/wiki/doc/api/wxpay/ch/pay/OfficialPayMent/chapter5_5.shtml)
  83. ```go
  84. import (
  85. "github.com/go-pay/gopay/wechat"
  86. )
  87. // ====微信小程序 paySign====
  88. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  89. packages := "prepay_id=" + wxRsp.PrepayId // 此处的 wxRsp.PrepayId ,统一下单成功后得到
  90. // 获取微信小程序支付的 paySign
  91. // appId:AppID
  92. // nonceStr:随机字符串
  93. // packages:统一下单成功后拼接得到的值
  94. // signType:签名方式,务必与统一下单时用的签名方式一致
  95. // timeStamp:时间
  96. // apiKey:API秘钥值
  97. paySign := wechat.GetMiniPaySign(AppID, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, apiKey)
  98. // ====APP支付 paySign====
  99. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  100. // 获取APP支付的 paySign
  101. // 注意:package 参数因为是固定值,无需开发者再传入
  102. // appId:AppID
  103. // partnerid:partnerid
  104. // nonceStr:随机字符串
  105. // prepayId:统一下单成功后得到的值
  106. // signType:签名方式,务必与统一下单时用的签名方式一致
  107. // timeStamp:时间
  108. // apiKey:API秘钥值
  109. paySign := wechat.GetAppPaySign(appid, partnerid, wxRsp.NonceStr, wxRsp.PrepayId, wechat.SignType_MD5, timeStamp, apiKey)
  110. // ====微信内H5支付 paySign====
  111. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  112. packages := "prepay_id=" + wxRsp.PrepayId // 此处的 wxRsp.PrepayId ,统一下单成功后得到
  113. // 获取微信内H5支付 paySign
  114. // appId:AppID
  115. // nonceStr:随机字符串
  116. // packages:统一下单成功后拼接得到的值
  117. // signType:签名方式,务必与统一下单时用的签名方式一致
  118. // timeStamp:时间
  119. // apiKey:API秘钥值
  120. paySign := wechat.GetH5PaySign(AppID, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, apiKey)
  121. ```
  122. ### 4、同步返回参数验签Sign、异步通知参数解析和验签Sign、异步通知返回
  123. > 异步通知请求参数需要先解析,解析出来的结构体或BodyMap再验签(此处需要注意,`http.Request.Body` 只能解析一次,如果需要解析前调试,请处理好Body复用问题)
  124. [Gin Web框架(推荐)](https://github.com/gin-gonic/gin)
  125. [Echo Web框架](https://github.com/labstack/echo)
  126. ```go
  127. import (
  128. "github.com/go-pay/gopay"
  129. "github.com/go-pay/gopay/wechat"
  130. )
  131. // ====同步返回参数验签Sign====
  132. wxRsp, err := client.UnifiedOrder(bm)
  133. // 微信同步返回参数验签或异步通知参数验签
  134. // apiKey:API秘钥值
  135. // signType:签名类型(调用API方法时填写的类型)
  136. // bean:微信同步返回的结构体 wxRsp 或 异步通知解析的结构体 notifyReq
  137. // 返回参数 ok:是否验签通过
  138. // 返回参数 err:错误信息
  139. ok, err := wechat.VerifySign(apiKey, wechat.SignType_MD5, wxRsp)
  140. // ====支付异步通知参数解析和验签Sign====
  141. // 解析支付异步通知的参数
  142. // req:*http.Request
  143. // ctx.Request 是 gin 框架的获取 *http.Request
  144. // ctx.Request() 是 echo 框架的获取 *http.Request
  145. // 返回参数 notifyReq:通知的参数
  146. // 返回参数 err:错误信息
  147. notifyReq, err := wechat.ParseNotifyToBodyMap(ctx.Request)
  148. // 验签操作
  149. ok, err := wechat.VerifySign(apiKey, wechat.SignType_MD5, notifyReq)
  150. // ====退款异步通知参数解析,退款通知无sign,不用验签====
  151. //
  152. // 解析退款异步通知的参数,解析出来的 req_info 是加密数据,需解密
  153. // req:*http.Request
  154. // ctx.Request 是 gin 框架的获取 *http.Request
  155. // ctx.Request() 是 echo 框架的获取 *http.Request
  156. // 返回参数 notifyReq:通知的参数
  157. // 返回参数 err:错误信息
  158. notifyReq, err := wechat.ParseNotifyToBodyMap(c.Request)
  159. notifyReq, err := wechat.ParseRefundNotify(c.Request)
  160. // ==解密退款异步通知的加密参数 req_info ==
  161. refundNotify, err := wechat.DecryptRefundNotifyReqInfo(notifyReq.ReqInfo, apiKey)
  162. // ==异步通知,返回给微信平台的信息==
  163. rsp := new(wechat.NotifyResponse) // 回复微信的数据
  164. rsp.ReturnCode = gopay.SUCCESS
  165. rsp.ReturnMsg = gopay.OK
  166. // 此写法是 gin 框架返回微信的写法
  167. c.String(http.StatusOK, "%s", rsp.ToXmlString())
  168. // 此写法是 echo 框架返回微信的写法
  169. return c.String(http.StatusOK, rsp.ToXmlString())
  170. ```
  171. ### 5、公共API(仅部分说明)
  172. ---
  173. ## 附录:
  174. ### 微信支付v2 API
  175. * 统一下单:`client.UnifiedOrder()`
  176. * JSAPI - JSAPI支付(或小程序支付)
  177. * NATIVE - Native支付
  178. * APP - app支付
  179. * MWEB - H5支付
  180. * 提交付款码支付:`client.Micropay()`
  181. * 查询订单:`client.QueryOrder()`
  182. * 关闭订单:`client.CloseOrder()`
  183. * 撤销订单:`client.Reverse()`
  184. * 申请退款:`client.Refund()`
  185. * 查询退款:`client.QueryRefund()`
  186. * 下载对账单:`client.DownloadBill()`
  187. * 下载资金账单(正式):`client.DownloadFundFlow()`
  188. * 交易保障:`client.Report()`
  189. * 拉取订单评价数据(正式):`client.BatchQueryComment()`
  190. * 企业付款(正式):`client.Transfer()`
  191. * 查询企业付款(正式):`client.GetTransferInfo()`
  192. * 授权码查询OpenId(正式):`client.AuthCodeToOpenId()`
  193. * 公众号纯签约(正式):`client.EntrustPublic()`
  194. * APP纯签约-预签约接口-获取预签约ID(正式):`client.EntrustAppPre()`
  195. * H5纯签约(正式):`client.EntrustH5()`
  196. * 支付中签约(正式):`client.EntrustPaying()`
  197. * 请求单次分账(正式):`client.ProfitSharing()`
  198. * 请求多次分账(正式):`client.MultiProfitSharing()`
  199. * 查询分账结果(正式):`client.ProfitSharingQuery()`
  200. * 查询订单待分账金额 (正式):`client.ProfitSharingOrderAmountQuery()`
  201. * 查询最大分账比例 (正式):`client.ProfitSharingMerchantRatioQuery()`
  202. * 添加分账接收方(正式):`client.ProfitSharingAddReceiver()`
  203. * 删除分账接收方(正式):`client.ProfitSharingRemoveReceiver()`
  204. * 完结分账(正式):`client.ProfitSharingFinish()`
  205. * 分账回退(正式):`client.ProfitSharingReturn()`
  206. * 分账回退结果查询(正式):`client.ProfitSharingReturnQuery()`
  207. * 企业付款到银行卡API(正式):`client.PayBank()`
  208. * 查询企业付款到银行卡API(正式):`client.QueryBank()`
  209. * 获取RSA加密公钥API(正式):`client.GetRSAPublicKey()`
  210. * 发放现金红包:`client.SendCashRed()`
  211. * 发放现金裂变红包:`client.SendGroupCashRed()`
  212. * 发放小程序红包:`client.SendAppletRed()`
  213. * 查询红包记录:`client.QueryRedRecord()`
  214. * 订单附加信息提交(海关):`client.CustomsDeclareOrder()`
  215. * 订单附加信息查询(海关):`client.CustomsDeclareQuery()`
  216. * 订单附加信息重推(海关):`client.CustomsReDeclareOrder()`
  217. * 自定义方法请求微信API接口:`client.PostWeChatAPISelf()`
  218. ### 微信公共v2 API
  219. * `wechat.GetParamSign()` => 获取微信支付所需参数里的Sign值(通过支付参数计算Sign值)
  220. * `wechat.GetSanBoxParamSign()` => 获取微信支付沙箱环境所需参数里的Sign值(通过支付参数计算Sign值)
  221. * `wechat.GetMiniPaySign()` => 获取微信小程序支付所需要的paySign
  222. * `wechat.GetH5PaySign()` => 获取微信内H5支付所需要的paySign
  223. * `wechat.GetAppPaySign()` => 获取APP支付所需要的paySign
  224. * `wechat.ParseNotifyToBodyMap()` => 解析微信支付异步通知的参数到BodyMap
  225. * `wechat.ParseNotify()` => 解析微信支付异步通知的参数
  226. * `wechat.ParseRefundNotify()` => 解析微信退款异步通知的参数
  227. * `wechat.VerifySign()` => 微信同步返回参数验签或异步通知参数验签
  228. * `wechat.GetOpenIdByAuthCode()` => 授权码查询openid
  229. * `wechat.GetOauth2AccessToken()` => 微信第三方登录,code 换取 access_token
  230. * `wechat.RefreshOauth2AccessToken()` => 刷新微信第三方登录后,获取到的 access_token
  231. * `wechat.CheckOauth2AccessToken()` => 检验授权凭证(access_token)是否有效
  232. * `wechat.DecryptRefundNotifyReqInfo()` => 解密微信退款异步通知的加密数据