Zise Developers

错误契约

统一信封。code 分支,不要按 message 分支 —— Accept-Language

会改变 message,不会改变 code


{
  "type": "invalid_request_error",
  "code": "insufficient_balance",
  "message": "The member's available balance is not enough.",
  "request_id": "01J8X4K9…"
}

每个响应都带 X-Request-Id,错误体里也带一份。工单第一句话就是它。

type → HTTP → 你该怎么办

| type | HTTP | 语义 | 处置 |

|---|---|---|---|

| invalid_request_error | 400 | 入参不合法或业务前置条件不满足 | 改正后重发,换新幂等键 |

| authentication_error | 401 | 令牌无效 / 过期 / 签名不符 | 重新换令牌;连续失败查签名串拼法 |

| permission_error | 403 | scope 不足 / IP 不在白名单 / 商户被停用 | 后台改配置,不要重试 |

| not_found | 404 | 对象不存在或不属于本商户 | 不要重试 |

| idempotency_error | 409 | 同键异体 / 首次仍在处理 | 见「幂等」 |

| rate_limit_error | 429 | 超配额 | 指数退避 + 随机 jitter |

| api_error | 500 | 我方内部错误 | 同键重试;持续则报工单带 request_id |

| upstream_error | 502 | 上游不可用 | 同键重试 |

| upstream_timeout | 504 | 结果不明(可能已执行) | 同键重试,或查单确认。绝不换新键 |

常见 code

| code | 含义 |

|---|---|

| member_not_found | 会员不存在不属于本商户已停用 —— 三种情况同一响应 |

| member_context_required | 会员作用域端点缺 x-on-behalf-of |

| kyc_required | 该业务要求的 KYC 层级未达到,附 required_level |

| insufficient_balance | 会员可用余额不足 |

| merchant_insufficient_funds | 你的资金账户余额不足 —— 去商户后台充值 |

| product_not_available | 产品未对本商户授权、已停售或不满足条件 |

| limit_exceeded | 附 limit_type(single/daily/monthly)与 limit_scope(member/merchant) |

| request_rejected | 风控拒绝的唯一对外码。 不带原因、不带规则名、不带评分 |

| step_up_required | 需强认证,附 hosted_urlchallenge_id |

| order_not_cancellable | 订单已进入不可撤销阶段 |

| asset_not_allowed | 该资产不在你的白名单内 |

| environment_mismatch | 沙盒凭据打了 live 域(或反过来) |

两件我方刻意不告诉你的事

风控判据永不出境。 命中原因、规则名、阈值、评分一律不下发。被风控拒绝

时你只会看到 request_rejected。人工申诉走商户后台工单。

跨商户信息不经由错误码泄露。 「该邮箱已注册」「该证件号已用于开卡」

这类响应会暴露另一个商户的会员存在性 —— 一律收敛成同一个不区分的响应。

所以你用一个已属于别处的邮箱建户时,拿到的不是 409。