# 微信支付

微信云托管通过[开放接口服务](/miniprogram/dev/wxcloudservice/wxcloudrun/src/guide/weixin/open)封装了微信支付原有的接口，所以在使用前需要开启「开放接口服务」

要了解微信支付接口的运作和使用理论，请前往[使用指南](/miniprogram/dev/wxcloudservice/wxcloudrun/src/guide/weixin/pay)

我们也给出了一个 [Node.js 案例](https://github.com/WeixinCloud/wxcloudrun-pay-nodejs)、[PHP 案例](https://github.com/TCloudBase/wxcloudrun-pay-demo)，具体可以前往查看学习。

**如果在接口请求时出现 302、400，返回空值等情况，可以在请求时加 header `content-type:'application/json'` 解决。**

如果在请求时返回 `{ return_code: 'FAIL', return_msg: '受理关系不存在' }`，则需要前往[微信云托管控制台 - 设置 - 其他设置 - 微信支付配置](https://cloud.weixin.qq.com/cloudrun/settings/other)绑定商户号到已授权状态。

具体方法的详细文档如下：

## 一、[支付接口](order/index)

接口名称 | 接口 | 需要 OpenID
-- | -- | --
[统一下单](order/unified) | `http://api.weixin.qq.com/_/pay/unifiedOrder` | ✅ |
[查询订单](order/query) | `http://api.weixin.qq.com/_/pay/queryorder` |  |
[关闭订单](order/close) | `http://api.weixin.qq.com/_/pay/closeorder` |  |
[下载对账单](order/bill) | `http://api.weixin.qq.com/_/pay/downloadbill` |  |
[申请退款](order/refund) | `http://api.weixin.qq.com/_/pay/refund` | ✅ |
[查询退款](order/queryrefund) | `http://api.weixin.qq.com/_/pay/queryrefund` |  |

## 二、[分账接口](account/index)

接口名称 | 接口 | 需要 OpenID
-- | -- | --
[添加分账接收方](account/addreceiver) | `http://api.weixin.qq.com/_/pay/profitsharingaddreceiver` |  |
[删除分账接收方](account/delreceiver) | `http://api.weixin.qq.com/_/pay/profitsharingremovereceiver` |  |
[请求单次分账](account/onesharing) | `http://api.weixin.qq.com/_/pay/profitsharing` |  |
[请求多次分账](account/sharing) | `http://api.weixin.qq.com/_/pay/multiprofitsharing` |  |
[完结分账](account/doneshare) | `http://api.weixin.qq.com/_/pay/profitsharingfinish` |  |
[查询分账结果](account/queryshare) | `http://api.weixin.qq.com/_/pay/profitsharingquery` |  |
[分账回退](account/refundshare) | `http://api.weixin.qq.com/_/pay/profitsharingreturn` |  |
[回退结果查询](account/queryrefundshare) | `http://api.weixin.qq.com/_/pay/profitsharingreturnquery` |  |

## 三、[结果回调](callback/index)

## 四、代码示例 - Node.js

以下代码实现了下单到退款的基本业务逻辑，只是用于参考，实际接入请根据自己的业务情况改造，比如将触发订单由流程决定，添加校验逻辑等。

完整例子可以前往 [GitHub 仓库](https://github.com/WeixinCloud/wxcloudrun-pay-nodejs)

### 1. 服务端代码

``` js
const express = require('express')
const request = require('request')

const app = express()
app.use(express.json())

const mchId = process.env.mch_id || '1XXXXXXXXX' // 这里商户号需要替换成自己的
// 也可以在部署时设定环境变量【mch_id】为商户号

// 统一下单
app.post('/unifiedOrder', async function (req, res) {
  const ip = req.headers['x-forwarded-for'] // 小程序直接callcontainer请求会存在
  const openid = req.headers['x-wx-openid'] // 小程序直接callcontainer请求会存在
  // 如果是业务异步流程需自己替换openid来源
  const { text, noid, fee } = req.body
  const payreq = {
    body: text, // 订单描述
    out_trade_no: noid, // 自定义订单号
    sub_mch_id: mchId, // 微信支付商户号
    total_fee: fee, // 金额，单位：分
    openid: openid, // 用户唯一身份ID
    spbill_create_ip: ip, // 用户客户端IP地址
    env_id: req.headers['x-wx-env'], // 接收回调的环境ID
    callback_type: 2, // 云托管服务接收回调，填2
    container: {
      service: req.headers['x-wx-service'], // 回调的服务名称
      path: '/' // 回调的路径
    }
  }
  console.log('[unifiedOrder]请求体', payreq)
  const info = await callpay('unifiedorder', payreq)
  console.log('[unifiedOrder]响应体', info)
  res.send(info)
})

// 查询订单
app.post('/queryorder', async function (req, res) {
  const { noid } = req.body
  const payreq = {
    out_trade_no: noid, // 自定义订单号
    sub_mch_id: mchId // 微信支付商户号
  }
  console.log('[queryorder]请求体', payreq)
  const info = await callpay('queryorder', payreq)
  console.log('[queryorder]响应体', info)
  res.send(info)
})

// 关闭订单
app.post('/closeorder', async function (req, res) {
  const { noid } = req.body
  const payreq = {
    out_trade_no: noid, // 自定义订单号
    sub_mch_id: mchId // 微信支付商户号
  }
  console.log('[closeorder]请求体', payreq)
  const info = await callpay('closeorder', payreq)
  console.log('[closeorder]响应体', info)
  res.send(info)
})

// 发起退款
app.post('/refund', async function (req, res) {
  const { text, noid, fee } = req.body
  const payreq = {
    body: text, // 订单描述
    out_trade_no: noid, // 自定义订单号
    out_refund_no: `R_${noid}`, // 自定义退款单号
    sub_mch_id: mchId, // 微信支付商户号
    total_fee: fee, // 订单金额，单位：分
    refund_fee: fee, // 退款金额，单位：分
    refund_desc: `${text}_退款`, // 订单退款描述
    env_id: req.headers['x-wx-env'], // 接收回调的环境ID
    callback_type: 2, // 云托管服务接收回调，填2
    container: {
      service: req.headers['x-wx-service'], // 回调的服务名称
      path: '/' // 回调的路径
    }
  }
  console.log('[refund]请求体', payreq)
  const info = await callpay('refund', payreq)
  console.log('[refund]响应体', info)
  res.send(info)
})

// 查询退款
app.post('/queryrefund', async function (req, res) {
  const { noid } = req.body
  const payreq = {
    out_trade_no: noid, // 自定义订单号
    sub_mch_id: mchId // 微信支付商户号
  }
  console.log('[queryrefund]请求体', payreq)
  const info = await callpay('queryrefund', payreq)
  console.log('[queryrefund]响应体', info)
  res.send(info)
})

// 接收回调信息
app.all('/', function (req, res) {
  console.log('回调请求头', req.headers)
  console.log('回调收到内容', req.body || req.query)
  res.send('success')
})

app.listen(80, function () {
  console.log('服务启动成功！')
})

function callpay (action, paybody) {
  return new Promise((resolve, reject) => {
    request({
      url: `http://api.weixin.qq.com/_/pay/${action}`,
      method: 'POST',
      headers: {
        'content-type': 'application/json'
      },
      body: JSON.stringify(paybody)
    }, function (error, res) {
      if (error) {
        resolve(error)
      } else {
        resolve(res.body)
      }
    })
  })
}
```

### 2. 在小程序中调用

``` js
wx.cloud.callContainer({
  config: {
    env: "prod-xxxxxx" // 替换自己的环境ID
  },
  path: "/order",
  header: {
    "X-WX-SERVICE": "pay", // 替换自己的服务
    "content-type": "application/json"
  },
  method: "POST",
  data: {
    text: "测试支付", // 自定义
    noid: "2021WERUN1647840687637", // 自定义
    fee: 1 // 分，金额自定义
  }
})
```

### 3. 在公众号中调用

公众号（服务号）中调用前，需要在[管理后台](https://mp.weixin.qq.com)开通配置微信支付，具体配置过程跟小程序一致。

然后在网页中初始化公众号 SDK，获取 `chooseWXPay` 接口权限。

从服务端中获取支付 payment 信息，传入 `chooseWXPay` 接口发起调用即可。

具体可以参见代码案例：[GitHub 仓库文件夹](https://github.com/WeixinCloud/wxcloudrun-pay-nodejs/tree/master/web)

![](https://res8.wxqcloud.qq.com.cn/wxdoc/e6ea1253-f84c-427e-b379-a4066ef0b8b4.png)
