错误码
失败的响应一律是:
json
{ "ok": false, "error": { "code": "INSUFFICIENT_BALANCE", "message": "insufficient available balance" } }- 以
code判断,不要以message判断:message是给开发者看的说明(多为英文),之后可能调整。 - HTTP 状态码有意义:
400参数错误、401签名验证失败、403权限(IP、租户、玩家)、404找不到、409冲突、413正文过大、429限流、5xx服务器错误。 5xx的正文可能不是 JSON(例如在 Cloudflare 层就失败时),请一律视为暂时错误。
重试原则
| 状况 | 处理 |
|---|---|
429、5xx、超时、连接错误 | 退避后重试(例如 1、2、4、8 秒,加上随机延迟)。每次重试都产生新的 nonce 与时间戳 |
| 转入、转出的状态不明 | 以相同的 txnId 与内容重试,直到得到 2xx 或 4xx,见钱包:超时与重试 |
其他 4xx | 不要原样重试:依错误码修正请求 |
401(nonce already used) | 这个请求没有被处理;以新的 nonce 重新送出 |
下表由 OpenAPI 规格产生,列出实作可能返回的全部错误码。
共通错误(任何端点都可能返回)
| 错误码 | HTTP | 意义 | 处理方式 | 可重试 |
|---|---|---|---|---|
UNAUTHORIZED | 401 | 签名验证失败。invalid credentials:密钥 ID 格式错误、密钥不存在或已禁用(轮替中的旧密钥超过 24 小时也算)、nonce 格式错误,或签名不符。timestamp outside the ±300 s window:X-Timestamp 格式错误或与服务器时间差超过 300 秒。nonce already used:同一个 nonce 在 10 分钟内重复使用(这次请求没有被处理)。message:invalid credentials、timestamp outside the ±300 s window、nonce already used | 用〈签名调试器〉比对签名字符串;确认路径从 /api/tenant/v1 开始并含查询字符串、以实际送出的正文字节计算哈希;服务器校时(NTP);每个请求(含重试)都产生新的 nonce 与时间戳。 | 修正后再送 |
IP_NOT_ALLOWED | 403 | 你设置了 IP 白名单,而这个请求的来源 IP 不在名单内。message:source IP is not in the allowlist | 在 Console「上线与对接 → IP 白名单与 Webhook」加入服务器的对外 IP(IPv4/IPv6 或 CIDR)。 | 修正后再送 |
TENANT_SUSPENDED | 403 | 租户已禁用、停权或已关闭,所有 API 都暂停服务。message:tenant is suspended | 登录 Console 查看账户状态,或联系支持。 | 修正后再送 |
RATE_LIMITED | 429 | 超过每秒请求上限(付费方案 100 次/秒、沙箱 20 次/秒、免费方案 5 次/秒,可短暂突发到 2 倍)。message:too many requests | 退避后重试(例如 200 ms、400 ms、800 ms…,加随机延迟),并换新的 nonce 与时间戳;平时以批量与游标减少调用次数。 | 可以(换新的 nonce 与时间戳) |
PAYLOAD_TOO_LARGE | 413 | 请求体超过 64 KB。message:request body too large | 缩小正文;本 API 的正常请求都远小于这个上限。 | 修正后再送 |
INVALID_JSON | 400 | 正文不是合法的 JSON,或不是 JSON 对象。message:request body is not valid JSON、request body must be an object | 送出 Content-Type: application/json 与 JSON 对象({…})。 | 修正后再送 |
NOT_FOUND | 404 | unknown endpoint:方法与路径不存在(例如用 GET 调用 POST 端点,或局 ID 不是 26 字符大写 ULID)。table not found:激活或禁用的桌号不存在。message:unknown endpoint、table not found | 对照〈API 参考〉的方法与路径;桌号以 GET /tables 为准。 | 修正后再送 |
INTERNAL_ERROR | 500 | 服务器暂时错误。任何 5xx(包含正文不是 JSON 的情况)都视为这一类。message:internal error, please retry | 退避后重试。转账请以相同的 txnId 重试,或先以 GET /wallet/transfer 查询;持续发生请查看状态页或联系支持。 | 可以(换新的 nonce 与时间戳) |
端点相关错误
| 错误码 | HTTP | 意义 | 处理方式 | 可重试 |
|---|---|---|---|---|
INVALID_PARAMETER | 400 | 缺少必要字段,或字段格式、值不正确;message 会指出是哪个字段。message:<field> is required、<field> must be a string、unsupported lang、lobbyUrl must be an http(s) URL、status must be active, locked or no_bet、password must be 6–64 characters、limitProfileId must be a positive integer or null、limitProfileId not found、limitProfileId currency is <CUR>, player currency is <CUR>、txnId must be 1–64 characters of A-Z a-z 0-9 _ . : -、txnId is required、from must be an ISO time、date must be a valid YYYY-MM-DD、from and to must be YYYY-MM-DD | 依〈API 参考〉修正字段后重送。 | 修正后再送 |
INVALID_USERNAME | 400 | 玩家账号不符合规则(1–32 个字符,字母或数字与 _ . @ -),或查询时没有带 username。message:username must be 1–32 characters of A-Z a-z 0-9 _ . @ -、invalid username | 在你的系统把玩家账号对应成符合规则的字符串(例如以你的会员 ID 产生)。 | 修正后再送 |
INVALID_CURRENCY | 400 | 创建新玩家时指定的币种代码不合法(需要 3–5 个英文字母)。message:invalid currency | 使用正确的币种代码,或不带 currency 以使用租户默认币种。 | 修正后再送 |
CURRENCY_NOT_ENABLED | 400 | 创建新玩家时指定的币种,租户还没打开(多币种:Console「限红方案 → 币种」)。已存在的玩家不受影响。message:currency <CUR> is not enabled for this operator (enabled: <CUR>, <CUR>) | 在 Console 打开这个币种并设置该币种的限红方案后再创建玩家,或不带 currency 以使用主要币种。 | 修正后再送 |
INVALID_AMOUNT | 400 | 金额不是大于 0、最多 4 位小数的十进制字符串。message:amount must be a positive decimal string with at most 4 decimals、invalid amount | 以字符串发送金额(例如 "100.5"),不要用浮点数或科学记号。 | 修正后再送 |
INVALID_CURSOR | 400 | cursor 格式错误。message:cursor must come from a previous response | 原样带回上一页的 nextCursor;遗失时改用 from 从某个时间重新同步,并以 (slipId, rev) 去重。 | 修正后再送 |
CURRENCY_MISMATCH | 400 | 转账的 currency 与玩家的币种不同。玩家的币种在创建时决定,之后不能变更。message:player currency is <CUR> | 以玩家的币种转账(GET /player 可查);不同币种请使用不同的玩家账号。 | 修正后再送 |
PLAYER_NOT_FOUND | 404 | 这个账号的玩家不存在。message:player not found | 玩家会在第一次 launch 或第一次转入时自动创建;请先完成其中一个步骤。 | 修正后再送 |
PLAYER_LOCKED | 403 | 玩家已被锁定,不能启动游戏。message:player is locked | 需要时以 POST /player/update 把 status 改回 active。 | 修正后再送 |
PLAYER_LIMIT | 403 | 玩家账号数已达方案上限(免费展示方案默认 50、沙箱 500)。message:demo plan allows at most <N> players | 沿用既有的测试玩家,或升级付费方案。 | 修正后再送 |
TXN_CONFLICT | 409 | 这个 txnId 已经用在另一笔金额或方向不同的转账,或最近两个月内已用在另一位玩家。message:txnId was already used with different content、txnId was already used for another player | 这是你的系统的单号错误:每笔新的转账都要用新的 txnId(整个租户内唯一);重试时则必须和第一次内容完全相同。 | 修正后再送 |
INSUFFICIENT_BALANCE | 409 | 转出金额大于可用余额(未结算注单的本金不可转出)。message:insufficient available balance | 以 GET /wallet/balance 取得可用余额后再转出。 | 修正后再送 |
TXN_NOT_FOUND | 404 | 查不到这个 txnId 的转账:查询时有带 username 表示这笔转账没有执行(或仍在处理中);没带时只查租户流水(当月与前 3 个月)。message:transfer not found | 以相同的 txnId 与内容重送转账,直到得到明确的成功或 4xx 结果。不要当成失败而改用新的单号。 | 修正后再送 |
ROUND_NOT_FOUND | 404 | 这一局不存在,或尚未结算。message:round not found | 局在结算后才查得到;注单上的 roundId 一定查得到。 | 修正后再送 |
QUOTA_EXCEEDED | 409 | 已激活的桌数达到免费方案配额(默认 2 桌)。message:超过方案配额(<N> 桌) | 先禁用其他桌,或在 Console「方案与账单 → 方案」升级付费方案。 | 修正后再送 |
ACCOUNT_LOCKED | 409 | 账户已停权或关闭,不能激活桌台。message:account is suspended | 联系支持。 | 修正后再送 |