錯誤碼
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 影響,永遠穩定。