阅读主题
错误码与故障处理
平台失败响应为 {"error":{"code":"INVALID_AUTH_CODE","message":"登录凭证无效、已使用或不属于当前游戏"}}。用 HTTP 状态判断类别,用 error.code 决定操作;不要依赖提示文字保持不变。requestId 在共享类型中可选,当前实现没有保证每个错误都携带它。
登录核心接口
| HTTP | 错误码 | 含义与处理 |
|---|---|---|
| 400 | VALIDATION_ERROR | 字段缺失、格式或长度不符;检查接口契约,多余兑换字段也会被拒绝 |
| 400 | INVALID_JSON | JSON 无法解析;检查请求编码及序列化 |
| 401 | INVALID_GAME_KEY | 服务端密钥缺失、错误、过长或不属于该游戏;仅由游戏服务端排查 |
| 401 | INVALID_AUTH_CODE | 授权码过期、已使用、App ID 或 PKCE 不匹配;重新登录 |
| 401 | UNAUTHENTICATED | Bearer 请求头缺失或格式无效;恢复有效会话或重新登录 |
| 401 | SESSION_EXPIRED | 玩家会话不存在、过期或凭据类型不对;清理本地会话并重新登录 |
| 403 | ACCOUNT_RESTRICTED | 玩家账号受限;停止自动重试并展示客服入口 |
| 403 | APP_UNAVAILABLE | 应用待审、停用或所属开发者受限;检查控制台状态 |
| 403 | ORIGIN_FORBIDDEN | 浏览器来源不在允许列表;核对协议、主机、端口与 CORS 配置 |
| 404 | APP_NOT_FOUND | App ID 不存在;以控制台值为准 |
| 413 | PAYLOAD_TOO_LARGE | JSON 超过 32 KB;只提交接口需要的字段 |
| 429 | RATE_LIMITED | 请求过于频繁;退避,不立即循环重试 |
| 500 | INTERNAL_ERROR | 服务端未预期错误;保留操作时间、路径与脱敏日志进行排查 |
HTTP 状态不唯一对应某一个原因。例如登录兑换中,应用检查在密钥检查之前,错误密钥配上待审 App ID 可能先返回 APP_UNAVAILABLE。应以实际 error.code 为准。
玩家业务补充
以下错误涉及当前实现的登录、订单、钱包和权益。公开 OpenAPI 已扩展到 SDK 与游戏服操作;管理后台并非全部覆盖。
| 错误码 | 恢复方式 |
|---|---|
INVALID_CREDENTIALS / INVALID_SMS_CODE | 让用户重新输入或完成新的验证,不泄露账号是否存在 |
ACCOUNT_NOT_REGISTERED | 短信验证后未找到已注册身份,引导显式注册;不会自动创建账号 |
USERNAME_EXISTS | 用户名已注册,使用原账号登录或选择其他用户名 |
PHONE_ALREADY_BOUND / PHONE_CHANGE_NOT_SUPPORTED | 不自动合并账号或换绑;当前绑定只用于补充可验证的手机号 |
TEST_PLAYER_PHONE_DISABLED | 本地测试身份不允许绑定真实手机 |
MAINTENANCE | 维护期停止下单与登录重试,刷新配置后展示提示 |
FEATURE_DISABLED | 当前应用功能已关闭,刷新玩家中心并隐藏相应入口 |
GAME_BACKEND_REQUIRED | 新应用不能用内置演示免密兑换,配置自己的可信游戏服务器 |
IDEMPOTENCY_CONFLICT | 同一请求 ID 被用于不同内容;新业务动作生成新 ID,原请求重试保持原内容 |
INSUFFICIENT_BALANCE | 刷新余额、显示不足并让用户选择下一步 |
ORDER_NOT_FOUND | 订单不存在或不属于当前账号/游戏;检查当前会话,不暴露他人订单 |
ORDER_NOT_PAYABLE / ORDER_NOT_CLOSABLE | 先查询订单状态,按当前状态更新按钮 |
ASSET_CONSUMED / BENEFIT_CONSUMED | 本地退款条件不满足,展示原因及客服路径 |
完整购买与退款排错见 订单指南。
正式配置与开发者错误
| HTTP | 错误码 | 处理 |
|---|---|---|
| 503 | REGISTRATION_UNAVAILABLE | 当前环境协议配置不可用或临时暂停,读取实时 reason 并停止重试;正式自助注册正常时已开放 |
| 400 | TERMS_REQUIRED / TERMS_VERSION_MISMATCH | 重新获取当前协议,由用户主动阅读同意后提交;不自动替用户勾选 |
| 409 | SERVICE_REQUEST_LIMIT | 已有20条待处理开发者请求,查看已有回复,不重复创建 |
| 409 | SERVICE_REQUEST_VERSION_CONFLICT | 服务请求已被其他操作更新,重新读取版本并核对回复 |
| 404 | SERVICE_REQUEST_NOT_FOUND | 服务请求不存在,检查标识与当前身份 |
| 503 | SMS_NOT_CONFIGURED | 真实短信未接通,关闭短信登录/注册/找回入口 |
| 503 | PAYMENT_NOT_CONFIGURED / REFUND_NOT_CONFIGURED | 收款或退款通道未配置,不循环重试 |
| 503 | WALLET_NOT_CONFIGURED | 禁止模拟钱包资产变动 |
| 503 | FULFILLMENT_NOT_CONFIGURED | 正式禁止本地模拟发货,需可信外部履约 |
| 403 | DEMO_DISABLED | 演示快捷兑换已禁用;公网 API 域会先拦截成 404 |
| 403 | LOCAL_FULFILLMENT_DISABLED | 正式禁止切换到 local 模拟资产模式 |
| 401 | DEVELOPER_REQUIRED / ADMIN_REQUIRED | 使用对应域名和对应类型账号会话 |
| 403 | DEVELOPER_RESTRICTED | 开发者停用,联系平台处理 |
| 400 | TERMS_REQUIRED / TERMS_VERSION_MISMATCH | 重新加载当前条款并确认同意 |
这些配置错误不应清除仍有效的玩家会话。
网络错误与状态不确定
浏览器 CORS 拦截、连接失败和超时可能让客户端拿不到平台 JSON,此时不要伪造业务错误码。记录本地故障类别并给出可恢复提示。兑换超时重新发起登录;支付超时先查询原订单,不能直接显示支付失败并重复创建新订单。
联调日志记录时间、方法、路径、App ID、HTTP 状态与业务码即可。不要记录服务端密钥、授权码、verifier、密码、完整 token 或完整手机号。报告问题时可附脱敏请求字段及复现步骤。
启动错误不属于 HTTP 错误
PRODUCTION_NOT_READY 是正式配置、管理员初始化或数据库身份不符合要求时的启动保护,不是 HTTP 业务码。显式 restricted 配置和独立空库可启动正式基础服务;正式库禁止作为演示库启动,演示库也不能直接提升为正式库。真实支付与短信仍关闭,详见正式环境指南。
实现依据
packages/server/src/app.ts:错误处理中间件、请求校验、鉴权与限流。packages/server/src/platform.ts:订单、钱包、权益和幂等错误。packages/contracts/src/index.ts:ApiErrorBody。