# 申请退款

> 使用本接口需要开启[开放接口服务](/minigame/dev/wxcloudrun/src/guide/weixin/open)

当交易发生之后一段时间内，由于买家或者卖家的原因需要退款时，卖家可以通过退款接口将支付款退还给买家，微信支付将在收到退款请求并且验证成功之后，按照退款规则将支付款按原路退到买家账号上。注意：

1. 交易时间超过一年的订单无法提交退款；
2. 微信支付退款支持单笔交易分多次退款，多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。申请退款总金额不能超过订单金额。 一笔退款失败后重新提交，请不要更换退款单号，请使用原商户退款单号。
3. 请求频率限制：150qps，即每秒钟正常的申请退款请求次数不超过 150 次。错误或无效请求频率限制：6qps，即每秒钟异常或错误的退款申请请求不超过 6 次
4. 每个支付订单的部分退款次数不能超过 50 次

## 接口地址

``` bash
http://api.weixin.qq.com/_/pay/refund
```

## 关键参数说明

- 回调设置：`envId` 和 `container` 用来设置接收微信支付异步通知回调的云托管服务地址
- 返回字段 `payment`：该对象即是在小程序端调用 `wx.requestPayment` 所需的信息

## 入参数据

``` json
{
  "body":"测试微信支付",
  "out_trade_no":"2021WERUN1647840687637",
  "out_refund_no":"R2021WERUN1647840687637",
  "env_id":"环境ID",
  "sub_mch_id":"1712734762",
  "total_fee":1,
  "refund_fee":1,
  "refund_desc":"测试退款",
  "callback_type":2,
  "container":{
    "service":"pay",
    "path":"/"
  }
}
```

## 出参数据

``` json
{
  "errcode":0,
  "errmsg":"ok",
  "respdata":{
    "return_code":"SUCCESS",
    "return_msg":"OK",
    "result_code":"SUCCESS",
    "appid":"wxd2565e6a04246fd1",
    "mch_id":"1800780001",
    "sub_mch_id":"1712734762",
    "nonce_str":"CK9lmcq4mCXTXkRM",
    "sign":"356D60CC779C02FB2FAA9187FB13E122",
    "transaction_id":"4220001361307220321004860688",
    "out_trade_no":"2021WERUN1647840687637",
    "out_refund_no":"R2021WERUN1647840687637",
    "refund_id":"50302030148218522032126281690",
    "refund_fee":1,
    "total_fee":1,
    "cash_fee":1,
    "cash_refund_fee":1,
    "coupon_refund_fee":0,
    "coupon_refund_count":0,
    "coupon_type_list":[],
    "coupon_refund_id_list":[],
    "coupon_refund_fee_list":[]
  }
}
```

## 接收支付结果回调的入参和返回协议

详见[支付结果回调](/minigame/dev/wxcloudrun/src/development/pay/callback/index)。

## 参数说明

| 字段名| 变量名| 必填 | 类型 | 示例值 | 描述 |
|----|------|------|---|---|----|
| 结果通知类型 | callback_type | 是 | Int| 1 | 1 云函数 2 云托管 |
| 结果通知回调环境 | env_id | 是 | String| test-123 | 接收微信支付异步通知回调的云函数所在的环境 ID |
| 结果通知回调云函数名 | function_name | 否 | String| paycallback | 接收微信支付异步通知回调的云函数名 |
| 结果通知回调云托管信息 | container | 否 | Object|| 接收微信支付异步通知回调的云托管信息 |
| 子商户号| sub_mch_id| 是 | String(32) | 1900000109 | 微信支付分配的子商户号 |
| 随机字符串| nonce_str | 是 | String(32) | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | 随机字符串，不长于 32 位。推荐[随机数生成算法](https://pay.weixin.qq.com/doc/v2/partner/4011985884#2%E3%80%81%E7%94%9F%E6%88%90%E9%9A%8F%E6%9C%BA%E6%95%B0%E7%AE%97%E6%B3%95) |
| 微信订单号| transaction_id| 否 | String(32) | 1217752501201407033233368018 | 微信订单号。与商户订单号二选一填入。 |
| 商户订单号| out_trade_no| 否 | String(32) | 1217752501201407033233368018 | 商户系统内部订单号，要求 32 个字符内，只能是数字、大小写字母_-\|*@ ，且在同一个商户号下唯一。
transaction_id、out_trade_no 二选一，如果同时存在优先级：transaction_id> out_trade_no |
| 商户退款单号| out_refund_no | 是 | String(64) | 1.21775E+27| 商户系统内部的退款单号，商户系统内部唯一，只能是数字、大小写字母_-\|*@ ，同一退款单号多次请求只退一笔。 |
| 订单金额| total_fee | 是 | Int| 100| 订单总金额，单位为分，只能为整数，详见[支付金额](https://pay.weixin.qq.com/doc/v2/partner/4011941200#1%E3%80%81%E4%BA%A4%E6%98%93%E9%87%91%E9%A2%9D) |
| 申请退款金额| refund_fee| 是 | Int| 100| 退款总金额，单位为分，只能为整数，可部分退款。详见[支付金额](https://pay.weixin.qq.com/doc/v2/partner/4011941200#1%E3%80%81%E4%BA%A4%E6%98%93%E9%87%91%E9%A2%9D) |
| 货币种类| refund_fee_type | 否 | String(8)| CNY| 货币类型，符合 ISO 4217 标准的三位字母代码，默认人民币：CNY，其他值列表详见[货币类型](https://pay.weixin.qq.com/doc/v2/partner/4011941200#3%E3%80%81%E8%B4%A7%E5%B8%81%E7%B1%BB%E5%9E%8B)|
| 退款原因| refund_desc | 否 | String(80) | 商品已售完 | 若商户传入，会在下发给用户的退款消息中体现退款原因
注意：若订单退款金额≤1 元，且属于部分退款，则不会在退款消息中体现退款原因 |
| 退款资金来源| refund_account| 否 | String(30) | REFUND_SOURCE_RECHARGE_FUNDS | 仅针对老资金流商户使用
REFUND_SOURCE_UNSETTLED_FUNDS---未结算资金退款（默认使用未结算资金退款）
REFUND_SOURCE_RECHARGE_FUNDS---可用余额退款|

**container 对象说明**

| 名称 | 变量名| 必填 | 类型 | 示例值 | 描述|
|-----|--|------|---|-------|---|
| 服务名 | service | 是 | string(64) | callback | 服务名称 |
| 路径 | path | 是 | string(64) | /test | 业务路径 |

## 返回值说明

| 字段名 | 变量名| 必填 | 类型| 示例值 | 描述 |
|---|---|------|---|----------|-----|
| 返回状态码 | returnCode | 是 | String(16)| SUCCESS| SUCCESS/FAIL|
| 返回信息 | returnMsg| 否 | String(128) | 签名失败 | 返回信息，如非空，为错误原因。如 签名失败、参数格式校验错误|

以下字段在 returnCode 为 SUCCESS 的时候有返回

| 字段名 | 变量名| 必填 | 类型| 示例值 | 描述 |
|---------|---|------|---|---|----|
| 业务结果 | result_code | 是 | String(16)| SUCCESS| SUCCESS/FAIL
SUCCESS 退款申请接收成功，结果通过退款查询接口查询
FAIL 提交业务失败 |
| 错误代码 | err_code| 否 | String(32)| SYSTEMERROR| 列表详见错误码列表 |
| 错误代码描述 | err_code_des| 否 | String(128) | 系统超时 | 结果信息描述 |
| 服务商的 APPID| AppID | 是 | String(32)| wxd678efh567hg6787 | 服务商商户的 APPID|
| 商户号 | mch_id| 是 | String(32)| 1230000109 | 微信支付分配的商户号 |
| 小程序的 APPID| sub_appid | 是 | String(32)| wx8888888888888888 | 微信分配的小程序 ID |
| 子商户号 | sub_mch_id| 是 | String(32)| 1900000109 | 微信支付分配的子商户号 |
| 随机字符串 | nonce_str | 是 | String(32)| 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | 随机字符串，不长于 32 位 |
| 签名 | sign| 是 | String(32)| 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | 签名，详见签名算法 |
| 微信订单号 | transaction_id| 是 | String(32)| 1217752501201407033233368018 | 微信订单号 |
| 商户订单号 | out_trade_no| 是 | String(32)| 1217752501201407033233368018 | 商户系统内部订单号，要求 32 个字符内，只能是数字、大小写字母_-\|*@ ，且在同一个商户号下唯一。 |
| 商户退款单号 | out_refund_no | 是 | String(64)| 1217752501201407033233368018 | 商户系统内部的退款单号，商户系统内部唯一，只能是数字、大小写字母_-\|*@ ，同一退款单号多次请求只退一笔。 |
| 微信退款单号 | refund_id | 是 | String(32)| 1217752501201407033233368018 | 微信退款单号 |
| 申请退款金额 | refund_fee| 是 | Int | 100| 退款总金额,单位为分,可以做部分退款 |
| 退款金额 | settlement_refund_fee | 否 | Int | 100| 去掉非充值代金券退款金额后的退款金额，退款金额=申请退款金额-非充值代金券退款金额，退款金额<=申请退款金额 |
| 订单金额 | total_fee | 是 | Int | 100| 订单总金额，单位为分，只能为整数，详见支付金额 |
| 应结订单金额 | settlement_total_fee| 否 | Int | 100| 应结订单金额=订单金额-免充值代金券金额，应结订单金额<=订单金额。 |
| 货币种类 | fee_type| 否 | String(8) | CNY| 订单金额货币类型，符合 ISO 4217 标准的三位字母代码，默认人民币：CNY，其他值列表详见货币类型|
| 现金支付金额 | cash_fee| 是 | Int | 100| 现金支付金额，单位为分，只能为整数，详见支付金额 |
| 现金退款金额 | cash_refund_fee | 否 | Int | 100| 现金退款金额，单位为分，只能为整数，详见支付金额 |
| 代金券退款总金额 | coupon_refund_fee | 否 | Int | 100| 代金券退款金额<=退款金额，退款金额-代金券或立减优惠退款金额为现金，说明详见代金券或立减优惠|
| 退款代金券使用数量 | coupon_refund_count | 否 | Int | 1| 退款代金券使用数量 |
| 代金券类型 | coupon_type_$n| 否 | String(8) | CASH | CASH--充值代金券
NO_CASH---非充值代金券
订单使用代金券时有返回（取值：CASH、NO_CASH）。$n 为下标,从 0 开始编号，举例：coupon_type_0 |

## 错误码

| 名称| 描述 | 原因 | 解决方案 |
|-|---------|------|---------|
| SYSTEMERROR | 接口返回错误 | 系统超时 | 请不要更换商户退款单号，请使用相同参数再次调用 API。|
| BIZERR_NEED_RETRY | 退款业务流程错误，需要商户触发重试来解决 | 并发情况下，业务被拒绝，商户重试即可解决 | 请不要更换商户退款单号，请使用相同参数再次调用 API。|
| TRADE_OVERDUE | 订单已经超过退款期限 | 订单已经超过可退款的最大期限(支付后一年内可退款) | 请选择其他方式自行退款 |
| ERROR | 业务错误 | 申请退款业务发生错误 | 该错误都会返回具体的错误原因，请根据实际返回做相应处理。 |
| USER_ACCOUNT_ABNORMAL | 退款请求失败 | 用户账号注销 | 此状态代表退款申请失败，商户可自行处理退款。 |
| INVALID_REQ_TOO_MUCH| 无效请求过多 | 连续错误请求数过多被系统短暂屏蔽 | 请检查业务是否正常，确认业务正常后请在 1 分钟后再来重试|
| NOTENOUGH | 余额不足 | 商户可用退款余额不足 | 此状态代表退款申请失败，商户可根据具体的错误提示做相应的处理。 |
| INVALID_TRANSACTIONID | 无效 transaction_id | 请求参数未按指引进行填写 | 请求参数错误，检查原交易号是否存在或发起支付交易接口返回失败 |
| PARAM_ERROR | 参数错误 | 请求参数未按指引进行填写 | 请求参数错误，请重新检查再调用退款申请 |
| APPID_NOT_EXIST | APPID 不存在| 参数中缺少 APPID| 请检查 APPID 是否正确|
| MCHID_NOT_EXIST | MCHID 不存在| 参数中缺少 MCHID| 请检查 MCHID 是否正确|
| REQUIRE_POST_METHOD | 请使用 post 方法 | 未使用 post 传递参数 | 请检查请求参数是否通过 post 方法提交 |
| SIGNERROR | 签名错误 | 参数签名结果不正确 | 请检查签名参数和方法是否都符合签名算法要求 |
| XML_FORMAT_ERROR| XML 格式错误| XML 格式错误| 请检查 XML 参数格式是否正确|
| FREQUENCY_LIMITED | 频率限制 | 2 个月之前的订单申请退款有频率限制| 该笔退款未受理，请降低频率后重试 |
| NOAUTH| 异常 IP 请求不予受理 | 请求 IP 异常 | 如果是动态 IP，请登录商户平台后台关闭 IP 安全配置；
如果是静态 IP，请确认商户平台配置的请求 IP 在不在配的 IP 列表里 |
