错误码
Coinepay OpenAPI 错误响应同时包含:
code:与 HTTP 状态码相同(200/400/401/404/409/429/500)message:根据请求头Accept-Language返回中文或英文message_key:稳定的英文 key,程序判断用这个
json
{
"code": 400,
"message": "Idempotency-Key 冲突",
"message_key": "openapi_idempotency_key_conflict",
"data": null
}HTTP 状态码语义
| HTTP | 含义 |
|---|---|
| 200 | 成功(含"幂等返回"和"已入队") |
| 400 | 参数错 / 业务规则不满足(看 message_key 区分) |
| 401 | 鉴权失败(一律 openapi_invalid_credentials,不区分原因) |
| 403 | 鉴权通过但所请求的特性受限(如敏感卡信息的二次验证缺失/未通过、卡未激活) |
| 404 | 资源不存在 / 不属于当前账号 |
| 409 | 幂等键冲突(同 key 不同 body) |
| 429 | 限流 |
| 500 | 服务端异常 |
完整 message_key 字典
鉴权与凭证
| message_key | zh-CN | en-US | HTTP |
|---|---|---|---|
openapi_invalid_credentials | 无效的 OpenAPI 凭证 | Invalid OpenAPI credentials | 401 |
ID 校验
| message_key | zh-CN | en-US | HTTP |
|---|---|---|---|
openapi_invalid_header_id | header_id 不合法(缺前缀 / 错前缀 / 不存在) | Invalid header_id | 400 |
openapi_invalid_package_id | package_id 不合法 | Invalid package_id | 400 |
openapi_invalid_card_id | card_id 不合法 | Invalid card_id | 400 |
幂等
| message_key | zh-CN | en-US | HTTP |
|---|---|---|---|
openapi_idempotency_key_required | 缺少 Idempotency-Key 请求头 | Missing Idempotency-Key header | 400 |
openapi_idempotency_key_too_long | Idempotency-Key 超长(最大 128 字符) | Idempotency-Key too long | 400 |
openapi_idempotency_key_invalid_chars | Idempotency-Key 含非法字符 | Invalid characters | 400 |
openapi_idempotency_key_conflict | Idempotency-Key 冲突 | Idempotency-Key conflict | 409 |
业务规则
| message_key | zh-CN | en-US | HTTP |
|---|---|---|---|
openapi_card_type_not_supported | 暂不支持该卡类型,仅虚拟卡 | Not supported (virtual cards only) | 400 |
account_manager_bind_required | 该卡头需绑定客户经理后才能开通 | Account-manager-controlled header; bind an account manager first | 400 |
account_manager_unavailable | 绑定的客户经理已失效,请联系客服 | Your account manager is no longer active; contact support | 400 |
account_manager_open_disabled | 您的客户经理尚未对该账号开放此卡头 / 套餐 | Header / package not opened for your account by your account manager | 400 |
amount_required | amount 为必填 | amount is required | 400 |
card_not_found | 卡片不存在 / 不属于当前账号 | Card not found | 404 |
insufficient_balance | 余额不足 | Insufficient balance | 400 |
kyc_required | 请先完成实名认证 | Please complete identity verification first | 400 |
kyc_not_approved | KYC 未通过 | KYC not approved | 400 |
virtual_g_name_invalid | (G 卡)持卡人姓名不满足 ASCII 字母 / 单空格 / ≤40 字符规则 | (G card) cardholder name fails the rule | 400 |
virtual_g_required_fields_missing | (G 卡)开卡资料不完整 | (G card) apply payload incomplete | 400 |
virtual_a_required_fields_missing | (A 卡)first_name / last_name 缺失或为空白,或开卡资料不完整 | (A card) name missing/blank or apply payload incomplete | 400 |
首充(自定义金额)
由 /card/apply(作为 message_key,HTTP 400)与 /card/first_deposit/preview(作为 200 响应体内的 invalid_reason)返回,表示自定义 first_deposit_amount 不可受理。
| message_key | zh-CN | en-US | HTTP |
|---|---|---|---|
invalid_first_deposit_amount | first_deposit_amount 必须是非负整数 | first_deposit_amount must be a non-negative integer | 400 |
first_recharge_below_base | 首充低于配置底额 | First deposit below the config base | 400 |
first_recharge_exceeds_max | 超额超过最大充值 | Excess exceeds max recharge | 400 |
first_recharge_limit_exceeded | 超额超过充值限额 | Excess exceeds the recharge limit | 400 |
first_recharge_asset_mismatch | 开卡费资产与充值资产不一致 | Open-fee asset differs from recharge asset | 400 |
first_recharge_excess_too_small | 超额扣费取整后过小 | Excess too small after fee + rounding | 400 |
敏感卡片信息
下列错误码由 /openapi/card/info(with_sensitive=true 前提不满足时)与 /openapi/card/sensitive/send_code 返回。敏感字段要求卡处于 status=2 (active),并通过用户二次验证或凭证免验证特权二者之一。
| message_key | zh-CN | en-US | HTTP |
|---|---|---|---|
email_code_required | 请输入邮箱验证码 | Please enter email verification code | 403 |
sms_code_required | 请输入短信验证码 | Please enter SMS verification code | 403 |
pin_required | 请输入 PIN 码 | Please enter PIN | 403 |
2fa_code_required | 请输入 2FA 验证码 | Please enter 2FA code | 403 |
invalid_email_code | 邮箱验证码错误 | Invalid email verification code | 403 |
invalid_sms_code | 短信验证码错误 | Invalid SMS verification code | 403 |
invalid_pin | PIN 码错误 | Invalid PIN | 403 |
invalid_2fa_code | 2FA 验证码错误 | Invalid 2FA code | 403 |
email_not_verified | 邮箱未验证 | Email not verified | 403 |
phone_not_verified | 手机号未验证 | Phone not verified | 403 |
no_usable_auth_method | 无可用的认证方式 | No usable authentication method | 403 |
card_sensitive_access_banned | 通过 API 获取敏感卡片信息的权限已被管理员关闭 | Sensitive card info access via API has been disabled by the administrator | 403 |
openapi_sensitive_card_only_active | 仅激活状态的卡片可获取敏感信息 | Sensitive card info is only available for active cards. | 403 |
too_many_requests | 请求过于频繁(验证锁定 / 发码冷却,遵循 Retry-After) | Too many requests (verification locked / send cooldown; honor Retry-After) | 429 |
send_code_failed | 验证码发送失败(冷却已释放,可立即重试) | Failed to send verification code (cooldown released, retry allowed) | 500 |
openapi_sensitive_card_info_disabled(403)不再返回:未开通免验证特权的凭证现在会落入用户二次验证路径,而不是被直接拒绝。
卡列表过滤
| message_key | zh-CN | en-US | HTTP |
|---|---|---|---|
openapi_conflicting_card_filters | usable_only 与 statuses 不能同时传 | usable_only and statuses cannot be used together | 400 |
openapi_invalid_status_value | statuses 含非法状态值(仅允许 1-6) | statuses contains an invalid value (only 1-6 allowed) | 400 |
invalid_min_balance | 最小余额必须是合法非负数字(如 0 或 10.5) | min_balance must be a valid non-negative number | 400 |
invalid_max_balance | 最大余额必须是合法非负数字 | max_balance must be a valid non-negative number | 400 |
min_balance_exceeds_max_balance | 最小余额不能大于最大余额 | min_balance must not exceed max_balance | 400 |
invalid_date_format | 日期格式必须是 YYYY-MM-DD | date must be in YYYY-MM-DD format | 400 |
交易明细过滤
由 /transactions/list 与 /card/transactions/list 返回。
| message_key | zh-CN | en-US | HTTP |
|---|---|---|---|
invalid_date_format | 交易时间格式必须为 YYYY-MM-DD HH:MM:SS | transaction_time_from/to must be YYYY-MM-DD HH:MM:SS | 400 |
invalid_params | 参数无效(如金额格式错误) | Invalid parameters (e.g. bad amount format) | 400 |
冻结 / 解冻
由 /card/freeze 与 /card/unfreeze 返回。
| message_key | zh-CN | en-US | HTTP |
|---|---|---|---|
card_already_frozen | 卡片已被冻结 | Card is already frozen | 400 |
card_status_cannot_freeze | 当前卡状态不可冻结 | Current card status does not allow freezing | 400 |
card_not_frozen | 卡片未被冻结 | Card is not frozen | 400 |
card_type_mismatch | 卡类型与配置不匹配 | Card type does not match | 400 |
operation_not_supported | 该操作不支持 | Operation not supported for this card type | 400 |
recharge_unfreeze_disabled | 该卡不允许通过充值自动解冻 | Recharge-based unfreeze is not available | 400 |
unauthorized_unfreeze_admin | 该卡片被管理员冻结,用户无法自行解冻 | Frozen by admin — cannot self-unfreeze | 403 |
unauthorized_unfreeze_risk | 该卡片被风控冻结 | Frozen by risk control — cannot self-unfreeze | 403 |
unauthorized_unfreeze_system | 该卡片被系统冻结 | Frozen by system — cannot self-unfreeze | 403 |
销卡
由 /card/close 返回(v1.3 —— 端点自 v1.2 起已上线但此前未收录文档)。
| message_key | zh-CN | en-US | HTTP |
|---|---|---|---|
card_is_closing | 卡片正在注销中 | Card is being closed | 400 |
card_already_closed | 卡片已注销 | Card is already closed | 400 |
card_frozen_cannot_close | 卡片已冻结,无法注销 | Card is frozen and cannot be cancelled | 400 |
card_status_cannot_close | 当前卡状态不可注销 | Current card status does not allow cancellation | 400 |
close_not_accepted_by_upstream | 销卡未被上游受理,卡片已恢复为可用状态,请稍后重试 | Closure not accepted by the provider; card restored to active — retry later | 400 |
card_upstream_closed_pending_reconcile | 该卡已被上游直接注销,正在等待人工对账退款 | Card already closed by the provider; awaiting manual refund reconciliation | 400 |
card_config_not_found | 卡配置不存在 | Card configuration not found | 400 |
openapi_close_card_failed | 销卡失败 | Failed to close card | 500 |
服务端异常
| message_key | zh-CN | en-US | HTTP |
|---|---|---|---|
openapi_internal_error | OpenAPI 内部错误 | OpenAPI internal error | 500 |
openapi_list_card_headers_failed | 查询卡头列表失败 | Failed to list card headers | 500 |
openapi_list_card_configs_failed | 查询卡配置列表失败 | Failed to list card configs | 500 |
openapi_apply_card_failed | 申请虚拟卡失败 | Failed to apply virtual card | 500 |
openapi_first_deposit_preview_failed | 首充预览失败 | Failed to preview first deposit | 500 |
openapi_recharge_failed | 充值失败 | Failed to recharge | 500 |
openapi_get_card_info_failed | 获取卡片信息失败 | Failed to get card info | 500 |
openapi_list_cards_failed | 查询卡列表失败 | Failed to list cards | 500 |
openapi_list_webhook_events_failed | 查询 Webhook 事件历史失败 | Failed to list webhook events | 500 |
openapi_list_transactions_failed | 查询交易明细失败 | Failed to list transactions | 500 |
openapi_freeze_card_failed | 冻结卡片失败 | Failed to freeze card | 500 |
openapi_unfreeze_card_failed | 解冻卡片失败 | Failed to unfreeze card | 500 |
程序处理建议
python
def handle_response(resp):
code = resp.get('code', 500)
key = resp.get('message_key', '')
if code == 200:
return resp['data']
if code == 401:
# 永远是 openapi_invalid_credentials
raise AuthError("凭证无效或已过期,请检查 AppID/Secret/时钟")
if code == 403:
# 鉴权通过但所请求的特性受限
if key.endswith('_required'):
raise PermissionError(f"缺少二次验证凭据({key})—— "
"先调用 /openapi/card/sensitive/send_code 再重试")
if key.startswith('invalid_'):
raise PermissionError(f"二次验证未通过: {key}")
if key == 'openapi_sensitive_card_only_active':
raise RuntimeError("卡未激活,不能请求敏感字段")
raise PermissionError(f"特性受限: {key}")
if key == 'insufficient_balance':
raise BalanceError("余额不足")
if key == 'kyc_not_approved' or key == 'kyc_required':
raise KYCError("KYC 未通过")
if key.startswith('openapi_invalid_') and key.endswith('_id'):
raise ValueError(f"ID 格式错或不存在: {key}")
if key == 'openapi_idempotency_key_conflict':
# 不应自动重试 —— 业务侧需检查 body
raise IdempotencyConflict()
if code == 429:
raise RateLimited()
if code >= 500:
raise ServerError(resp.get('message', '内部错误'))
raise ApiError(code, key, resp.get('message'))多语言
通过请求头 Accept-Language 控制 message 的语言:
http
Accept-Language: en-US| 取值 | 行为 |
|---|---|
| 不传 | 默认中文 |
zh-CN / zh | 中文 |
en-US / en | 英文 |
| 其他 | 回退到默认 |
message_key 不受 Accept-Language 影响,永远稳定。