错误码
所有错误响应结构一致:HTTP 状态码 + 机器可读的 code + 可读的 error + request_id。
{
"ok": false,
"error": "余额不足:还差 $1.00",
"code": "INSUFFICIENT_MERCHANT_BALANCE",
"request_id": "req_9f8e7d6c5b4a3210",
"details": { "available_cents": 900 }
}
排查问题时请提供 request_id:它同时出现在服务端访问日志中,可以定位到具体请求。
鉴权与权限
| HTTP | code | 说明与处理 |
| 401 | INVALID_API_KEY | 缺少密钥、格式错误、Secret 不匹配或已吊销。检查 Authorization 头,确认密钥未被吊销 |
| 401 | UNAUTHENTICATED | 结账接口需要付款人登录;先完成登录再重试 |
| 403 | MERCHANT_INACTIVE | 商户未通过审核或已被暂停。联系运营,或检查商户后台状态 |
| 403 | CUSTOMER_MISMATCH | 支付单指定了其他付款人 |
| 403 | PIN_INCORRECT | 付款人支付 PIN 错误 |
| 423 | PIN_LOCKED | PIN 连续错误被锁定,等待锁定时间结束 |
请求与参数
| HTTP | code | 说明与处理 |
| 400 | AMOUNT_REQUIRED | 未传 amount |
| 400 | AMOUNT_INVALID | 金额不是合法十进制数,如 "12.3.4" |
| 400 | AMOUNT_PRECISION | 金额超过 2 位小数 |
| 400 | AMOUNT_ZERO | 金额必须大于 0 |
| 400 | AMOUNT_NEGATIVE | 金额为负数 |
| 400 | AMOUNT_TOO_LARGE | 金额超过上限($10,000,000.00) |
| 400 | FIELD_REQUIRED / FIELD_INVALID / FIELD_TOO_LONG | 字段缺失、格式或长度不符合要求,details.field 指明字段 |
| 400 | METADATA_INVALID | metadata 必须是对象 |
| 400 | METADATA_TOO_LARGE | metadata 序列化后超过 2KB |
| 400 | BAD_JSON | 请求体不是合法 JSON |
| 413 | PAYLOAD_TOO_LARGE | 请求体超过 100KB |
支付与退款
| HTTP | code | 说明与处理 |
| 404 | PAYMENT_NOT_FOUND | 支付单不存在或不属于当前商户 |
| 409 | REFERENCE_CONFLICT | 同一订单号已用于金额不同的支付;换一个 reference |
| 409 | PAYMENT_NOT_PAYABLE | 支付单已支付、已取消或状态不可支付 |
| 409 | PAYMENT_EXPIRED | 支付单超过 30 分钟有效期 |
| 409 | PAYMENT_NOT_CANCELABLE | 支付单当前状态不能取消 |
| 400 | PAYMENT_NOT_REFUNDABLE | 只有成功支付可以退款 |
| 400 | REFUND_EXCEEDS_REMAINING | 退款超过可退金额,details.refundable_cents 给出上限 |
| 400 | INSUFFICIENT_MERCHANT_BALANCE | 商户可结算余额不足,details.available_cents 给出当前值 |
| 409 | CONCURRENT_MODIFICATION | 并发修改冲突,刷新后重试 |
幂等与限流
| HTTP | code | 说明与处理 |
| 400 | IDEMPOTENCY_KEY_INVALID | 键格式不正确:8–255 位字母、数字或 - _ : . |
| 422 | IDEMPOTENCY_KEY_REUSED | 同一个键用于参数不同的请求;为新操作生成新键 |
| 409 | IDEMPOTENCY_IN_PROGRESS | 相同请求正在处理中,稍后用同一个键重试 |
| 429 | RATE_LIMITED | 超过每个 Key 每分钟的请求上限;退避后重试 |
服务端
| HTTP | code | 说明与处理 |
| 500 | INTERNAL | 未预期的服务端错误,响应包含 request_id;可安全重试(写请求带同一个幂等键) |
| 502/503/504 | — | 网关或上游不可用;按指数退避重试,写请求带同一个幂等键 |
什么时候可以重试
| 情况 | 建议 |
4xx(除 409 IDEMPOTENCY_IN_PROGRESS、429) | 不要重试,修正请求参数 |
409 IDEMPOTENCY_IN_PROGRESS | 等待 1–2 秒后用同一个幂等键重试 |
| 429 | 指数退避后重试 |
| 5xx / 网络超时 | 指数退避重试;写请求必须带同一个 Idempotency-Key |
✓失败的资金请求不会产生资金变动(服务端在事务内回滚),可以放心用同一个幂等键重试。