Error codes
Payout API std1
Three kinds of result
First decide which kind a response is, then act:
| Kind | Meaning | What to do |
|---|---|---|
| A not processed | The request was not accepted and nothing was recorded; it does not indicate whether this merchant order number was accepted before | correct the request and resubmit with the same merchant order number |
| B rejected | The order is rejected (final) and this merchant order number is used up | to pay out, submit with a new merchant order number; resubmitting the original one returns the same rejection |
| C unknown | SYSTEM_BUSY, and also timeouts, broken connections, HTTP other than 200, a body that is not JSON, a signature that does not verify, a missing signature where one is expected | retry only with the same merchant order number and parameters, or query, until you get success or a B result |
Code table
| code | Class | Returned by | Signed | msg text | What to do |
|---|---|---|---|---|---|
SUCCESS | — | apply, query, balance | yes | — | Success (for apply: accepted, not paid yet) |
PARAM_ERROR | A not processed | apply, query, balance | some | 参数[…]不能指向内网地址参数[…]格式错误参数[…]缺失参数[…]重复请求体不能超过65536字节请求体必须是表单 | A parameter is missing or malformed, the body is not a form, or it is too large. Fix it per msg and resend with the same order number |
MERCHANT_NOT_FOUND | A not processed | apply, query, balance | no | 商户不存在 | Wrong merchant ID, or this API is not enabled for you. Check the merchant ID and the API address |
IP_NOT_ALLOWED | A not processed | apply, query, balance | yes | IP[…]未授权 | Your source IP is not on the payout IP list. Give the IP in msg to the operator |
SIGN_ERROR | A not processed | apply, query, balance | yes | 签名错误 | Bad signature. Check the string to sign and the key (use the key as text) |
RATE_LIMITED | A not processed | apply, query, balance | yes | 请求过于频繁,请稍后重试 | Too many requests. Wait and resend with the same order number |
CURRENCY_NOT_SUPPORTED | A not processed | apply, balance | yes | 不支持的币种 | This currency is not accepted here. Fix or omit it and resend with the same order number |
ORDER_CONFIRM_FAILED | A not processed | apply | yes | 反查订单确认失败 | Payout confirmation is on and the confirmation lookup to your confirmation URL did not return the success value (it returned the failure value, gave no valid answer or timed out). Not processed and the order number is not used up; check and resubmit with the same order number |
MERCHANT_DISABLED | B rejected | apply, query | yes | 商户不可用或未开通代付商户未开通代付接口 | Merchant disabled, payouts not enabled, or the productId you sent is not opened for you or switched off; for "商户未开通代付接口" (payout API not enabled) the order number is not used up and can be resubmitted once enabled |
PAYOUT_SUSPENDED | B rejected | apply, query | yes | 代付暂停受理 | Payouts are temporarily suspended |
PAYEE_BLOCKED | B rejected | apply, query | yes | 交易受限 | Payee restricted |
BANK_NOT_SUPPORTED | B rejected | apply, query | yes | 该银行暂不支持代付 | This bank is not supported for payouts |
ACCOUNT_NOT_SUPPORTED | B rejected | apply, query | yes | 收款账号类型或格式暂不支持代付 | This payee account type or format is not supported |
AMOUNT_OUT_OF_RANGE | B rejected | apply, query | yes | 单笔金额不在可代付范围内 | Amount outside the allowed range |
NO_AVAILABLE_CHANNEL | B rejected | apply, query | yes | 暂无可用代付通道 | No payout channel available right now |
INSUFFICIENT_BALANCE | B rejected | apply, query | yes | 可用余额不足 | Available balance too low |
ORDER_NO_CONFLICT | — | apply | yes | 商户单号已存在且参数不一致订单号重复 | This order number already exists; nothing was done and the original is unaffected: the parameters differ from the first request, or an existing order number was sent while the payout API is not enabled ("订单号重复"). Query it first; if it really is another payout, submit it with a new merchant order number |
ORDER_NOT_FOUND | — | query | yes | 订单不存在 | No such order. This does not prove it was never created: the application may still be on its way |
SYSTEM_BUSY | C unknown | apply, query, balance | some | 系统繁忙,结果以查单为准 | System busy, result unknown. Resend with the same order number and parameters, or query |
- Codes are strings with one meaning each.
msgis Chinese text for people; the part in brackets changes with the request (parameter name, IP), so never branch onmsg. - Only two codes are unsigned by design:
PARAM_ERROR(unreadable request, missing merchant ID, body too large) andMERCHANT_NOT_FOUND. Treat any other unsigned code as kind C. - B codes also appear on queries: querying a rejected order returns its original rejection code.
- Two cases do not use up the merchant order number:
MERCHANT_DISABLED"商户未开通代付接口" (payout API not enabled; once enabled, resubmit with the same merchant order number) andORDER_NO_CONFLICT"订单号重复" (duplicate order number while the payout API is not enabled; the original order is unaffected, query it by that number).
Collection API compat1 (legacy)
The legacy protocol has no error codes, only retCode=FAIL and a retMsg text, worded exactly as in the old system. Common ones:
| API | retMsg text | Reason |
|---|---|---|
| Create order | 请求参数[mchId]不能为空且为数值类型. | Merchant ID missing or not digits |
| Create order | 商户不存在[mchId=…]. | Merchant ID does not exist |
| Create order | 商户状态不可用[mchId=…]. | Merchant disabled |
| Create order | IP[…]不允许访问 | Source IP not on your collection IP allow-list |
| Create order | 参数中含有XSS符号! | A value contains characters such as &, < or > |
| Create order | 请求参数[…]不能为空. | A required parameter is missing |
| Create order | 请求参数[…]长度不得大于…位. | A parameter is too long |
| Create order | 请求参数[notifyUrl]格式错误. | The part of notifyUrl before the first ? is not an http or https address with a host (the old system did not check this; we do now) |
| Create order | 请求参数[notifyUrl]不能指向内网地址. | notifyUrl is an internal or local IP (127.0.0.1, 10.x, 192.168.x and the like); callbacks only go to public addresses |
| Create order | 请求参数[amount]必须大于0. | Amount is not greater than 0 |
| Create order | 该商户订单已存在[mchOrderNo=…] | Duplicate order number (the original order is not returned) |
| Create order | 验证签名不通过.正确签名结果:…,签名串参考:… | Bad signature; the message shows the correct signature and the string to sign (the key is replaced by a placeholder) |
| Create order | 交易受限 | Payer restricted |
| Create order | 商户没有该产品的支付通道[productId=…,mchId=…] | This product is not enabled for you |
| Create order | 暂无可用支付通道,请稍后重试 | No channel available right now |
| Create order | 下单金额暂无可用支付通道,请稍后重试 | No channel available for this amount right now |
| Create order | 系统错误 | System error, try again later |
| Query order | request params[mchId] error. | Merchant ID missing or wrong |
| Query order | request params[mchOrderNo or payOrderId] error. | Neither mchOrderNo nor payOrderId was sent |
| Query order | Verify XX pay sign failed. | Bad signature |
| Query order | 支付订单不存在 | Order not found (also for orders placed before you switched to this platform) |
| Query order | 支付中心系统异常 | System error, or a value contains characters such as &, < or > |
| Balance | 参数[mchId]必填,且为数值类型.mchId=… | Merchant ID missing or not digits |
| Balance | 验证签名不通过. | Bad signature |
| Balance | 商户账户不存在或冻结 | Merchant funds account missing or frozen |
| Balance | 支付网关系统异常 | System error |
- “…” marks the part that changes with the request (merchant ID, order number, parameter name, length).
- Most create-order failures are unsigned; query and balance failures are always unsigned.
- Balance failures also carry
errCode(always0010) anderrDes(normally the same asretMsg).