1. Wechat application for refund
WeChat payment refund API address
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_4&index=6
Application Scenario
When a refund is required due to the buyer or seller within a certain period of time after the transaction, the seller can refund the payment to the buyer through the refund interface. According to the payment rules, the payment will be refunded to the buyer's account according to the original route.
Notice:
1. Orders that have been traded for more than one year cannot be refunded;
2. WeChat payment refund supports multiple refunds for a single transaction. For multiple refunds, you need to submit the merchant order number of the original payment order and set a different refund order number. The total amount applied for refund cannot exceed the order amount. Resubmit after a failed refund, please do not change the refund order number, please use the original merchant refund order number.
3. Request frequency limit: 150qps, that is, the number of normal refund requests per second does not exceed 150
Error or invalid request frequency limit: 6qps, that is, no more than 6 abnormal or wrong refund application requests per second
4. The number of partial refunds for each payment order cannot exceed 50 times
5. If the same user has multiple refunds, it is recommended to refund in different batches to avoid refund failure caused by concurrent refunds
6. The return of the refund application interface only represents the acceptance of the business. Whether the refund is successful or not, you need to obtain the result through the refund query interface.
7. The frequency limit for applying for refunds for orders made one month ago is: 5000/min
8. Multiple refund requests for the same order need to be separated by 1 minute
Refund status changes as follows:
The request requires a two-way certificate. See certificate use for details
field name | variable name | required | type | example value | describe |
---|---|---|---|---|---|
Public account ID | appid | yes | String(32) | wx8888888888888888 | The official account ID assigned by WeChat (corpid of the enterprise account is the appId) |
business number | mch_id | yes | String(32) | 1900000109 | Merchant ID assigned by WeChat Pay |
random string | nonce_str | yes | String(32) | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | Random string, no longer than 32 characters. Recommended random number generation algorithm |
sign | sign | yes | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | Signature, see Signature Generation Algorithm for details |
signature type | sign_type | no | String(32) | HMAC-SHA256 | Signature type, currently supports HMAC-SHA256 and MD5, the default is MD5 |
WeChat payment order number | transaction_id | pick one of two | String(32) | 1217752501201407033233368018 | The order number generated by WeChat is returned in the payment notification |
Merchant order number | out_trade_no | String(32) | 1217752501201407033233368018 | The internal order number of the merchant system must be within 32 characters (at least 6 characters). It can only be numbers, uppercase and lowercase letters _-|* and is unique under the same merchant number. See merchant order number for details Choose one of transaction_id and out_trade_no, if there is priority at the same time: transaction_id> out_trade_no |
|
Merchant refund order number | out_refund_no | yes | String(64) | 1217752501201407033233368018 | The refund order number inside the merchant system is unique within the merchant system, and can only be numbers, uppercase and lowercase letters _-|*@. Multiple requests for the same refund order number will only refund one sum. |
order amount | total_fee | yes | int | 100 | The total amount of the order, in cents, can only be an integer, see payment amount for details |
refund amount | refund_fee | yes | int | 100 | The total amount of the refund, the total amount of the order, the unit is cents, it can only be an integer, see the payment amount for details |
Refund Currency Type | refund_fee_type | no | String(8) | CNY | The refund currency type must be the same as the payment, or leave it blank. A three-digit letter code that complies with the ISO 4217 standard. The default is RMB: CNY. See Currency Type for a list of other values. |
reason for return | refund_desc | no | String(80) | Item sold out | If the merchant sends in, the reason for the refund will be reflected in the refund message sent to the user Note: If the order refund amount is ≤ 1 yuan, and it is a partial refund, the reason for the refund will not be reflected in the refund message |
Refund Funding Source | refund_account | no | String(30) | REFUND_SOURCE_RECHARGE_FUNDS | Only for old cash flow merchants REFUND_SOURCE_UNSETTLED_FUNDS --- unsettled funds refund (default use unsettled funds refund) REFUND_SOURCE_RECHARGE_FUNDS --- available balance refund |
Refund result notification url | notify_url | no | String(256) | https://weixin.qq.com/notify/ | The callback address for asynchronously receiving the WeChat payment refund result notification. The notification URL must be an URL accessible from the external network, and no parameters are allowed. The domain name of the public network must be https. If it is accessed through a dedicated line, you can use http if you use a dedicated line NAT IP or a private callback domain name. If notify_url is passed in the parameter, the callback address configured on the merchant platform will not take effect. |
Examples are as follows:
<xml>
<appid>wx2421b1c4370ec43b</appid>
<mch_id>10000100</mch_id>
<nonce_str>6cefdb308e1e2e8aabd48cf79e546a02</nonce_str>
<out_refund_no>1415701182</out_refund_no>
<out_trade_no>1415757673</out_trade_no>
<refund_fee>1</refund_fee>
<total_fee>1</total_fee>
<transaction_id>4006252001201705123297353072</transaction_id>
<sign>FE56DD4AA85C0EECA82C35595A69E153</sign>
</xml>
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
---|---|---|---|---|---|
返回状态码 | return_code | 是 | String(16) | SUCCESS | SUCCESS/FAIL |
返回信息 | return_msg | 否 | String(128) | 签名失败 | 返回信息,如非空,为错误原因 签名失败 参数格式校验错误 |
以下字段在return_code为SUCCESS的时候有返回
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
---|---|---|---|---|---|
业务结果 | result_code | 是 | String(16) | SUCCESS | SUCCESS/FAIL SUCCESS退款申请接收成功,结果通过退款查询接口查询 FAIL 提交业务失败 |
错误代码 | err_code | 否 | String(32) | SYSTEMERROR | 列表详见错误码列表 |
错误代码描述 | err_code_des | 否 | String(128) | 系统超时 | 结果信息描述 |
公众账号ID | appid | 是 | String(32) | wx8888888888888888 | 微信分配的公众账号ID |
商户号 | mch_id | 是 | String(32) | 1900000109 | 微信支付分配的商户号 |
随机字符串 | nonce_str | 是 | String(32) | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | 随机字符串,不长于32位 |
签名 | sign | 是 | String(32) | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | 签名,详见签名算法 |
微信支付订单号 | transaction_id | 是 | String(32) | 4007752501201407033233368018 | 微信订单号 |
商户订单号 | out_trade_no | 是 | String(32) | 33368018 | 商户系统内部订单号,要求32个字符内(最少6个字符),只能是数字、大小写字母_-|*且在同一个商户号下唯一。详见商户订单号 |
商户退款单号 | out_refund_no | 是 | String(64) | 121775250 | 商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。 |
微信退款单号 | refund_id | 是 | String(32) | 2007752501201407033233368018 | 微信退款单号 |
退款金额 | 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_fee_type | 否 | String(16) | CNY | 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型 |
现金退款金额 | cash_refund_fee | 否 | int | 100 | 现金退款金额,单位为分,只能为整数,详见支付金额 |
代金券类型 | coupon_type_$n | 否 | String(8) | CASH | CASH--充值代金券 NO_CASH---非充值代金券 订单使用代金券时有返回(取值:CASH、NO_CASH)。$n为下标,从0开始编号,举例:coupon_type_0 |
代金券退款总金额 | coupon_refund_fee | 否 | int | 100 | 代金券退款金额<=退款金额,退款金额-代金券或立减优惠退款金额为现金,说明详见代金券或立减优惠 |
单个代金券退款金额 | coupon_refund_fee_$n | 否 | int | 100 | 代金券退款金额<=退款金额,退款金额-代金券或立减优惠退款金额为现金,说明详见代金券或立减优惠 |
退款代金券使用数量 | coupon_refund_count | 否 | int | 1 | 退款代金券使用数量 |
退款代金券ID | coupon_refund_id_$n | 否 | String(20) | 10000 | 退款代金券ID, $n为下标,从0开始编号 |
举例如下:
<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[wx2421b1c4370ec43b]]></appid>
<mch_id><![CDATA[10000100]]></mch_id>
<nonce_str><![CDATA[NfsMFbUFpdbEhPXP]]></nonce_str>
<sign><![CDATA[B7274EB9F8925EB93100DD2085FA56C0]]></sign>
<result_code><![CDATA[SUCCESS]]></result_code>
<transaction_id><![CDATA[4008450740201411110005820873]]></transaction_id>
<out_trade_no><![CDATA[1415757673]]></out_trade_no>
<out_refund_no><![CDATA[1415701182]]></out_refund_no>
<refund_id><![CDATA[2008450740201411110000174436]]></refund_id>
<refund_fee>1</refund_fee>
</xml>
名称 | 描述 | 原因 | 解决方案 |
---|---|---|---|
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是否正确 |
ORDERNOTEXIST | 订单号不存在 | 缺少有效的订单号 | 请检查你的订单号是否正确且是否已支付,未支付的订单不能发起退款 |
REQUIRE_POST_METHOD | 请使用post方法 | 未使用post传递参数 | 请检查请求参数是否通过post方法提交 |
SIGNERROR | 签名错误 | 参数签名结果不正确 | 请检查签名参数和方法是否都符合签名算法要求 |
XML_FORMAT_ERROR | XML格式错误 | XML格式错误 | 请检查XML参数格式是否正确 |
FREQUENCY_LIMITED | 频率限制 | 1个月之前的订单申请退款有频率限制 | 该笔退款未受理,请降低频率后重试 |
NOAUTH | Abnormal IP requests will not be accepted | Abnormal request ip | If it is a dynamic ip, please log in to the background of the merchant platform to close the ip security configuration; if it is a static ip, please confirm that the requested ip configured by the merchant platform is not in the assigned ip list |
CERT_ERROR | Certificate verification error | Please check whether the certificate is correct, whether the certificate is expired or invalid. | Please check whether the certificate is correct, whether the certificate is expired or invalid. |
REFUND_FEE_MISMATCH | The order amount or refund amount is inconsistent with the previous request, please check and try again | The order amount or refund amount is inconsistent with the previous request, please check and try again | The order amount or refund amount is inconsistent with the previous request, please check and try again |
INVALID_REQUEST | The request parameter conforms to the parameter format, but does not conform to the business rules | This status means that the refund application has failed, and the merchant can deal with it according to the specific error prompt. | This status means that the refund application has failed, and the merchant can deal with it according to the specific error prompt. |
ORDER_NOT_READY | The order is being processed, and the refund is temporarily unavailable, please try again later | The order is being processed, and the refund is temporarily unavailable, please try again later | The order is being processed, and the refund is temporarily unavailable, please try again later |
2. Wechat payment refund error report
Precautions:
- total_fee: must be the payment amount of the order, unit: cents;
- refund_fee: less than the order payment amount, unit: cents;
- The same order can initiate multiple refunds, and the merchant's refund order number (out_refund_no) can be different;
- Use a merchant's refund order number (out_refund_no) to refund, if the refund fails for some reason, it will not affect the next time you use another merchant's refund order number to refund.
partial error message
- The total amount (total_fee) in the refund is inconsistent with the total amount of the WeChat payment order
退款请求
<xml>
<sign>464fd80d3822f288396c321501a06c29</sign>
<refund_fee>21500</refund_fee>
<mch_id>123</mch_id>
<op_user_id>1232846202</op_user_id>
<total_fee>21500</total_fee> --这里必须是支付时候的总就价格,特别是分批次退款的时候注意这里
<appid>123123123123</appid>
<out_refund_no>20160601195633930</out_refund_no>
<out_trade_no>2016053017063826030</out_trade_no>
<nonce_str>nNlsPAcmpP</nonce_str>
</xml>
退款响应
<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[123123123123]]></appid>
<mch_id><![CDATA[123]]></mch_id>
<nonce_str><![CDATA[F8bnSKUY7qvEpQtk]]></nonce_str>
<sign><![CDATA[908963603B666ECB7FC0F0AE1C1F22EA]]></sign>
<result_code><![CDATA[FAIL]]></result_code>
<err_code><![CDATA[REFUND_FEE_MISMATCH]]></err_code>
<err_code_des><![CDATA[同一个out_refund_no退款金额要一致]]></err_code_des>
</xml>
- The refund amount (refund_fee) is greater than the total amount (total_fee)
<xml><return_code><![CDATA[FAIL]]></return_code>
<return_msg><![CDATA[invalid refund_fee]]></return_msg>
</xml>
- The payment amount for the order has been refunded in full
<xml><return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[123123123123]]></appid>
<mch_id><![CDATA[123]]></mch_id>
<nonce_str><![CDATA[UdhYGRO1wLNkR0TR]]></nonce_str>
<sign><![CDATA[3FD2B2A28ECF24565CA35FCB76149431]]></sign>
<result_code><![CDATA[FAIL]]></result_code>
<err_code><![CDATA[TRADE_STATE_ERROR]]></err_code>
<err_code_des><![CDATA[订单状态错误]]></err_code_des>
</xml>
- missing certificate
wx sendpost exception
org.apache.http.NoHttpResponseException: api.mch.weixin.qq.com:443 failed to respond
WeChat payment signature verification failed:
1: Check whether the configuration information is correct
2: Check whether the parameters of the signature are complete
2: Check whether the signature is sorted according to the ASCII dictionary order of the parameter name
3: Reset the API key / merchant platform to reset the customer key
4: Body Chinese to English