# 微信支付

开发者可以使用微信云托管来实现相应的支付功能,无需关心证书、微信支付服务器端文档,使用简单,代码较少,只需要调用相应的接口即可。此外,因为微信云托管基于微信私有协议实现,官方通过服务商提供支付接口对接支持,不依赖第三方模块,免去泄漏证书、支付情况等其他敏感信息的风险。同时,微信云托管还支持接收微信支付进行支付和退款的回调,安全高效。

目前微信支付已支付微信小程序、公众号(服务号)

相比于微信支付原始接入,云托管的微信支付能力是官方团队做的一个封装,也就是说你使用的是封装接口,云托管在这里的角色是一个「微信支付服务商」,所以如果你也是「微信支付服务商」,就不推荐云托管这里的微信支付。

但你只是接入微信支付用于支付收款,或者分账对账等基础能力,则可以使用云托管提供的此微信支付能力。

# 能力介绍

微信云托管封装了微信支付,封装后的接口与微信支付原接口的不同点在于:

  1. 私有安全链路,免证书管理
  2. 商户号填入 sub_mch_id 字段,小程序/公众号 appid 填入 sub_appid 字段
  3. 免填写以下字段:mch_id、appid、sign、sign_type
  4. 接口入参和返回值都为 JSON 而不是 XML

以下以统一下单为例子讲解开发流程:

  1. 小程序或公众号调用微信云托管,在微信云托管中调用统一下单接口,参数中带上接收异步支付结果的服务名称和其所在云环境ID
  2. 统一下单接口返回的成功结果对象中有 payment 字段,该字段即是小程序端发起支付的接口(wx.requestPayment)所需的所有信息
  3. 小程序端拿到后端结果,调用 wx.requestPayemnt 发起支付
  4. 支付完成后,在统一下单接口中配置的云托管服务将收到支付结果通知,具体详见结果回调

注意:收到支付结果回调的云托管服务必须返回一个 { "errcode": 0 } 的对象,否则会认为回调处理失败,在接下来两天内会持续收到回调,直到返回成功为止;具体返回值协议见统一下单接口文档

# 开通&资质

  1. 你需要有一个微信支付商户号,可以前往此处进行开通注册。

  2. 拥有商户号后,关注“微信支付商户助手”公众号。

  3. 前往微信云托管控制台 - 设置 - 其他设置 - 微信支付配置绑定商户号。

  4. 在绑定过程中,“微信支付商户助手”会发送开通消息至商户号超级管理员微信中,需要商户号超级管理员在微信接收消息并确认。确认后即可授权成功,小程序支付参考小程序接入指引;公众号支付参考公众号接入指引

  • 如果你小程序有多个环境,只需要在其中一个环境里操作上述绑定过程即可,此绑定关系是支付和小程序的,而不是云托管环境。

  • 即使你的微信云托管环境在之后删除了,或者被其他小程序的环境资源复用了,也不会影响这里的支付绑定关系。

  • 商户号 —— 小程序,这个关系绑定后,后续的各种环境操作和资源复用操作,都不会影响此关系。

  • 如需取消绑定,可以直接在小程序后台微信支付控制台操作。

# 资源复用情况下配置

如果你的小程序A,想要使用云托管提供的微信支付能力,但是小程序A自己没有云托管环境,而是使用了小程序B的环境资源复用。

以上这种情况下,可以直接在小程序B的资源复用环境里操作小程序A的支付开通。

在这里操作,只是代为小程序A执行配置,实际关系还是商户号——小程序A,跟小程序B没有任何关系。即使后续小程序A用其他小程序的环境资源复用,也不用重新执行绑定。

目前云托管微信支付只支持小程序使用,也就是关系是「商户号—小程序」的才可以使用。 所以即使这个小程序由一个公众号的云托管环境资源复用,或者由一个第三方平台环境资源复用,也不会影响该小程序使用支付。

资源复用环境中调用支付接口,需要按照云调用资源复用指引,或开放接口服务资源复用指引使用

# 分账能力申请

官方本身是一个服务商(不参与分账,只提供分账接口能力),接入的商户都作为子商户,而具体分账都由开发者调用接口决定。 微信支付分账能力需要通过填写以下资料申请接入:

https://wj.qq.com/s2/7475529/37ee/

我们仅用于接入评估与需求分析,会保障以上信息安全,评估通过后申请的商户号会收到授权邀请通知,确认通过后即可调用以下接口进行分账。

# 接口使用

微信云托管提供了微信支付相关接口和服务端回调,包括统一下单、查询订单、关闭订单、申请退款、查询退款、下载对账单,具体文档见API文档

# 1. 自行签名【方式一】

  1. 获取 cloudbase_access_token,参见指引文档
  2. 计算 CloudBase 标准凭证。参考 Cloudbase Open API,将两个签名放置在 Header 中。
  3. 构建请求 URL,调用微信支付的 URL 格式如下,其中 env 为微信云托管环境ID
http://{env}.internal.ap-shanghai.tcb-api.tencentcloudapi.com/api/v2/envs/{env}/wx/pay?cloudbase_access_token={cloudbase_access_token}

# 2. 开放接口服务【方式二·推荐】

使用开放接口服务,通过 POST 请求微信支付接口 /_/pay/接口名称,从而调用微信支付能力。

开放接口服务支持的支付接口如下:

接口名称 接口 需要 OpenID
统一下单 http://api.weixin.qq.com/_/pay/unifiedorder
查询订单 http://api.weixin.qq.com/_/pay/queryorder
关闭订单 http://api.weixin.qq.com/_/pay/closeorder
下载对账单 http://api.weixin.qq.com/_/pay/downloadbill
申请退款 http://api.weixin.qq.com/_/pay/refund
查询退款 http://api.weixin.qq.com/_/pay/queryrefund
添加分账接收方 http://api.weixin.qq.com/_/pay/profitsharingaddreceiver
删除分账接收方 http://api.weixin.qq.com/_/pay/profitsharingremovereceiver
请求单次分账 http://api.weixin.qq.com/_/pay/profitsharing
请求多次分账 http://api.weixin.qq.com/_/pay/multiprofitsharing
完结分账 http://api.weixin.qq.com/_/pay/profitsharingfinish
查询分账结果 http://api.weixin.qq.com/_/pay/profitsharingquery
分账回退 http://api.weixin.qq.com/_/pay/profitsharingreturn
回退结果查询 http://api.weixin.qq.com/_/pay/profitsharingreturnquery

# 参数说明

每个接口对应的参数说明详见各接口对应文档,通过「开放接口服务」使用时,需使用 JSON 格式发送请求。

下面以查询订单接口作为示例。

POST http://api.weixin.qq.com/_/pay/queryorder

Content-Type: application/json

{
  "sub_mch_id": "1900000109",
  "transaction_id": "1009660380201506130728806387",
  "out_trade_no": "1217752501201407033233368018",
  "nonce_str": "C380BEC2BFD727A4B6845133519F3AD6"
}

对于 需要 OpenID 的接口,需要在 JSON 顶层加入 OpenID 字段,示例统一下单接口调用形式如下。

POST http://api.weixin.qq.com/_/pay/unifiedOrder

Content-Type: application/json

{
  "openid": "exampleopenid123456",
  "body" : "小秋TIT店-周公子超市", 
  "out_trade_no": "sds11a1f11232", 
  "spbill_create_ip" : "127.0.0.1", 
  "sub_mch_id" : "1900006511", 
  "total_fee" : 1, 
  "env_id": "test-f0b102", 
  "callback_type": 2, 
  "container": { 
      "service": "test", 
      "path": "/paycallback" 
  }
}

# CURL 参考示例

POST http://api.weixin.qq.com/_/pay/对应接口名称

以统一下单接口(unifiedOrder)为例,对应 Path 为 /_/pay/unifiedOrder

curl --location --request POST 'http://api.weixin.qq.com/_/pay/unifiedOrder' \
--header 'Content-Type: application/json' \
--data-raw '{
        "openid": "oFkBexampleopenidOvsi8i8",
        "body" : "小秋TIT店-周公子超市", 
        "out_trade_no": "sds11a1f11232", 
        "spbill_create_ip" : "127.0.0.1", 
        "sub_mch_id" : "1900006511", 
        "total_fee" : 1, 
        "env_id": "test-f0b102", 
        "callback_type": 2, 
        "container": { 
            "service": "test", 
            "path": "/paycallback" 
        }
}' -v