Appearance
错误码
错误响应格式见 通用约定 · 错误响应:
json
{ "error": { "code": "INSUFFICIENT_BALANCE", "message": "insufficient available balance", "retryable": false, "requestId": "…" } }- 程序判断请使用
code;message仅供排查,可能变化。 retryable = true的错误只有 4 个:RATE_LIMITED、PROVIDER_UNAVAILABLE、SIGNER_UNAVAILABLE、INTERNAL。重试时每次重新签名,资金类请求保持相同的externalTxId/Idempotency-Key与请求体,并使用指数退避(例如 1s、2s、4s… 上限 60s)。- 其他错误重试不会成功,需要修改请求或等待业务条件变化。
- 下表的 HTTP 状态码是该错误码的默认值;框架层错误(路径/查询参数解析失败
400、方法不支持405、请求体超过 1 MiB413、处理超时408)保留各自的 HTTP 状态码,见 通用约定。
完整列表
请求类
| code | HTTP | retryable | 含义 | 处理建议 |
|---|---|---|---|---|
BAD_REQUEST | 422 | 否 | 请求格式或参数不合法:JSON 解析失败、缺少字段、字段取值非法、缺少/非法 Idempotency-Key、金额为 0、请求体过大等 | 根据 message 修正请求。注意本错误码默认 HTTP 为 422,参数解析类为 400 |
UNAUTHORIZED | 401 | 否 | 认证失败:缺少头、Key 不存在或已吊销、JWT 无效或过期、uri/bodyHash 不匹配、nonce reused | 按 签名排查表 检查;重试必须重新签名 |
FORBIDDEN | 403 | 否 | 无权限:租户已暂停(tenant suspended)、租户订阅已到期(tenant subscription expired,/v1 所有接口,无 GET 例外)、IP 不在白名单、用户已冻结(user is frozen / user is not active) | 检查白名单与用户状态;租户暂停或到期请联系平台续期/恢复 |
NOT_FOUND | 404 | 否 | 资源不存在或不属于本租户(用户、钱包、交易、回调端点、事件),或路由不存在 | 检查 ID 与路径 |
RATE_LIMITED | 429 | 是 | 超过 API Key 每秒上限;用户 24 小时新建钱包过多;两步验证码校验过于频繁 | 退避后重试;钱包创建类需等待 24 小时窗口 |
IDEMPOTENCY_CONFLICT | 409 | 否 | 幂等键被用于不同请求体;同一键的请求仍在处理;externalTxId 已被使用 | 处理中:稍后用同样的请求重试;冲突:检查是否误复用了单号,或用 GET /v1/transactions/external_tx_id/{id} 查询已有交易 |
INVALID_STATE | 409 | 否 | 当前状态不允许该操作,例如取消非提现交易、提现已无法取消 | 查询最新状态后决定 |
INTERNAL | 500 | 是 | 服务器内部错误 | 使用相同请求(幂等键不变)退避重试;持续出现请提供 requestId 联系平台 |
地址与资产
| code | HTTP | retryable | 含义 | 处理建议 |
|---|---|---|---|---|
INVALID_ADDRESS | 422 | 否 | 地址格式错误:EVM 缺少 0x/长度不对/EIP-55 校验失败/零地址,TRON/BTC 校验失败,BTC 网络不符,SOL 不是钱包地址 | 提示用户检查地址;可先调用地址校验接口 |
ASSET_NOT_SUPPORTED | 422 | 否 | 未知 assetId | 以 GET /v1/supported_assets 为准 |
ASSET_DISABLED | 422 | 否 | 资产或网络当前不允许链上提现 | 暂停该资产的提现入口,稍后再试 |
NETWORK_DISABLED | 422 | 否 | 网络未对本租户开通,或该链族暂不允许新建钱包 | 以 GET /v1/networks 为准;需要开通请联系平台 |
ASSET_MISMATCH | 422 | 否 | 资产与钱包链族不一致;收付双方钱包链族不同;资产当前不可用于该钱包 | 选择与资产同链族的钱包 |
钱包与收款人
| code | HTTP | retryable | 含义 | 处理建议 |
|---|---|---|---|---|
WALLET_LIMIT_REACHED | 422 | 否 | 用户在该链族下的钱包数已达上限(默认 10) | 复用已有钱包 |
WALLET_NOT_ACTIVE | 422 | 否 | 付款钱包不是 ACTIVE(创建中、冻结、关闭等),或收款钱包不能收款 | 查询钱包状态;创建中的钱包稍后再试 |
RECIPIENT_NOT_FOUND | 404 | 否 | END_USER 收款人(uid / customerRefId)不存在,或已被冻结 | 检查收款人 |
RECIPIENT_NO_WALLET | 422 | 否 | 收款人在该链族下没有默认钱包 | 先为收款人调用 deposit_address 创建钱包 |
SAME_WALLET_TRANSFER | 422 | 否 | 收款方就是付款钱包本身(含地址相同) | 修改收款方 |
SAME_USER_USE_WALLET_TRANSFER | 422 | 否 | END_USER 指向付款用户自己 | 本人钱包之间请用 destination.type = WALLET |
金额与限额
| code | HTTP | retryable | 含义 | 处理建议 |
|---|---|---|---|---|
BELOW_MIN_WITHDRAWAL | 422 | 否 | 链上提现金额低于资产 minWithdraw | 提示最小提现额 |
QUOTE_EXPIRED | 422 | 否 | 报价已过期(内部报价在提交前过期,极少出现) | 重新提交(可复用同一 externalTxId,该错误会释放幂等键) |
INSUFFICIENT_BALANCE | 422 | 否 | 可用余额不足以支付金额 + 手续费 | 提示余额不足;先用 estimate_fee 计算 totalRaw |
LIMIT_EXCEEDED | 422 | 否 | 超过单笔或每日限额;回调端点数超过 10 个 | 降低金额或次日再试;停用不需要的回调端点 |
安全
| code | HTTP | retryable | 含义 | 处理建议 |
|---|---|---|---|---|
TWO_FACTOR_REQUIRED | 403 | 否 | 租户要求终端用户两步验证,但缺少 X-User-2FA-Code,或用户未绑定 TOTP | 引导用户输入/绑定 TOTP,见 X-User-2FA-Code |
TWO_FACTOR_INVALID | 403 | 否 | 验证码错误或已被使用过 | 让用户输入新的验证码 |
COOLDOWN_ACTIVE | 403 | 否 | 用户处于安全冷静期 | 等待冷静期结束(用户对象 cooldownUntil) |
BLOCKED_BY_POLICY | 403 | 否 | 被租户交易策略拦截(同步返回于站内转账;链上提现被拦截时体现为 REJECTED 状态) | 检查租户策略配置 |
EMAIL_TAKEN | 409 | 否 | 邮箱已被本租户其他用户使用 | 不传邮箱或换一个邮箱 |
INVALID_CREDENTIALS | 401 | 否 | 登录凭据错误(用于控制台与 C 端登录,B 端接口不会返回) | — |
管理员控制台(非 B 端
/v1):平台与租户管理员统一使用本地加密 Ed25519 凭证 + 强制 TOTP。 固定密码管理员登录已永久停用(POST /admin/v1/auth/login、POST /tenant-admin/v1/auth/login一律403 FORBIDDEN);首次凭证签名验证只返回 TOTP 待绑定、不返回会话,绑定成功才发会话;已绑定必须提供 未使用过的验证码(缺失/未绑定 →403 TWO_FACTOR_REQUIRED,错误或重复 →403 TWO_FACTOR_INVALID)。 这些路径不属于 B 端对接场景。
处理类
| code | HTTP | retryable | 含义 | 处理建议 |
|---|---|---|---|---|
INTERNAL_DESTINATION_NOT_ALLOWED | 422 | 否 | 收款地址是平台运营地址(热钱包、归集、Gas 等) | 拒绝该地址 |
PROVIDER_UNAVAILABLE | 503 | 是 | 依赖的外部服务(如反洗钱、链节点)暂不可用;或请求处理超时(HTTP 408) | 退避重试;资金类请求保持幂等键不变,超时后先按 externalTxId 查询 |
MANUAL_REVIEW_REQUIRED | 422 | 否 | 预留:需要人工审核。当前版本不会返回(人工审核体现为交易状态) | — |
SIGNER_UNAVAILABLE | 503 | 是 | 签名服务暂不可用(如分配钱包地址时) | 退避重试 |
按 HTTP 状态码索引
| HTTP | 错误码 |
|---|---|
| 400 | BAD_REQUEST(路径/查询参数解析失败) |
| 401 | UNAUTHORIZED、INVALID_CREDENTIALS |
| 403 | FORBIDDEN、TWO_FACTOR_REQUIRED、TWO_FACTOR_INVALID、COOLDOWN_ACTIVE、BLOCKED_BY_POLICY |
| 404 | NOT_FOUND、RECIPIENT_NOT_FOUND |
| 405 | BAD_REQUEST(方法不支持) |
| 408 | PROVIDER_UNAVAILABLE(处理超时) |
| 409 | IDEMPOTENCY_CONFLICT、EMAIL_TAKEN、INVALID_STATE |
| 413 | BAD_REQUEST(请求体超过 1 MiB) |
| 422 | BAD_REQUEST 以及其余所有业务错误码 |
| 429 | RATE_LIMITED |
| 500 | INTERNAL |
| 503 | PROVIDER_UNAVAILABLE、SIGNER_UNAVAILABLE |