錯誤與狀態碼

這個 API 的錯誤回應固定是 { error, code }:error 給人看,code 給程式判斷。下面把每個狀態碼「什麼情況會拿到、你的程式該做什麼、能不能重試」寫清楚,每一支端點頁的「可能錯誤」也都連回這裡。

01回應格式

所有錯誤都長這樣。

HTTP 狀態碼決定「成功或失敗」,code 決定「為什麼」。請用 code 寫分支,不要用中文 error 字串比對。

一般錯誤

{
  "error": "給人看的中文說明",
  "code": "machine_readable_code"
}

429 會多這兩個欄位

{
  "error": "請求過於頻繁",
  "code": "rate_limited",
  "dimension": "rpm",
  "limit": 60
}

02狀態碼

每個狀態碼的處理方式。

每一列都可以直接分享(例如 /errors#status-429)。

200OK重試: 不需要

請求成功。回應內容就是這支端點定義的資料。

  • GET/PATCH 成功
  • POST 成功但不建立新資源(例如驗證碼核對)

直接解析 JSON。文件頁的「回應」區塊就是這個形狀。

201Created重試: 不要重試(會建出第二筆)

已建立資源,而且回應會帶新資源的 id。

  • 註冊、建立商品、建立 webhook、建立收款意圖/結帳

把回應裡的 id 存起來(user_id/intentId/orderId),後續呼叫要用。

400Bad Request重試: 修正後才送

請求本身有問題:JSON 壞掉、必填缺漏、金額或狀態不合法。

  • body 不是合法 JSON → code: "invalid_json"
  • 必填欄位缺漏或型別錯
  • 金額為負、超過上限,或退款金額大於可退餘額(pay_refund_amount_invalid)
  • 意圖狀態不允許這個動作(pay_bad_status)

不要盲目重試。先看 code 與 error,修正請求後再送。

401Unauthorized重試: 重新取得憑證後

沒有帶憑證,或憑證無效/過期。

  • 缺少 X-HSystem-Token 或 Authorization
  • access_token 過期
  • refresh_token 已撤銷 → 重新登入
  • code: "login_required"(需要先走登入頁)
  • code: "mfa_invalid"(MFA 驗證碼錯誤)

先用 refresh_token 換新 token;換不到就重新走登入流程。不要用同一組憑證重試。

403Forbidden重試: 不要重試

已通過認證,但這個身分不能做這件事。

  • 服務未在 App 啟用(pay_service_disabled、email_not_registered)
  • 需要 App Secret 但你只帶了使用者 token(pay_refund_app_secret_required、pay_order_app_only)
  • 這不是你的資源(pay_intent_forbidden、pay_order_forbidden)
  • scope/權限不足(Agent Token 少 pay:live 等)
  • 功能未開放(mfa_unavailable)

這是設定問題,不是重試問題。引導使用者回開發者控制台啟用服務或補 scope。

404Not Found重試: 不要重試

路徑不存在,或路徑/資源 id 找不到對應資料。

  • 打錯網址(error: "找不到這個接口")
  • pay_intent_not_found/pay_order_not_found/pay_price_not_found
  • path 參數用了不存在的 id

檢查 base URL 與 path 參數。文件頁的 Playground 有一樣的網址可以對照。

409Conflict重試: 重讀狀態後

請求合法,但與目前狀態衝突:重複建立、併發,或餘額不足。

  • email_already_registered:這個 Email 已經註冊
  • pay_race:同一筆意圖/訂單被別人搶先改狀態
  • pay_refund_conflict:同時兩筆退款搶同一筆餘額
  • hcoin_insufficient:HCoin 餘額不足(開發者操作)
  • already_published/already_friends/already_unlocked

重新讀取最新狀態再決定。退款請重讀 refundableCents;HCoin 不足要先去控制台加值。

429Too Many Requests重試: 退避重試

被限流或超出方案配額。回應會帶 code、dimension、limit。

  • code: "rate_limited"、dimension: "rpm" → 每分鐘請求數超限
  • dimension: "daily" → 當日請求數超限
  • dimension: "ip_rpm" → 同一 IP 太密集
  • error: "超出方案配額" → 該服務維度的免費額+加購用完

指數退避重試(建議 1s → 2s → 4s,最多 3 次);持續 429 就去看控制台的用量與方案,不要縮短間隔硬撞。

500Internal Server Error重試: 退避重試

伺服器端錯誤,不是你的請求格式問題。

  • 未預期的例外(error: "伺服器錯誤")

退避重試 1–2 次;仍失敗請把當下時間、端點、請求 body 與回應貼到開發者控制台回報。

501Not Implemented重試: 不要重試

這支端點是骨架,功能還沒實作。文件頁會標 BETA。

  • google_oauth_not_configured:平台尚未配置 Google 憑證
  • mfa_unavailable:開了 MFA 但沒有可用的驗證管道

不要接進正式流程。改看文件上標示 ga 的替代端點。

03常見錯誤碼

看到 code,就知道要改哪裡。

這裡只列文件讀者最常撞到的;API 內部的完整清單會隨功能增加。

invalid_json400

body 不是合法 JSON

用 JSON.stringify() 組 body,不要在字串裡手動拼引號。

login_required401

需要先登入(或半登錄流程未完成)

把使用者導到登入頁;完成後再呼叫原本的端點。

mfa_invalid401

MFA 驗證碼錯誤或過期

讓使用者重新輸入;連續失敗請重開 MFA 流程。

mfa_unavailable403

這個 App 沒有開放該 MFA 方法

回控制台檢查 MFA 設定;或改用其他已開放的方法。

mfa_not_needed400

目前這個 session 不需要 MFA

不要主動呼叫;先看 login 回應的 gate.requires。

email_already_registered409

Email 已被註冊

改走登入或忘記密碼,不要重送註冊。

email_not_registered403

此用途只接受已註冊信箱

確認 purpose 與使用情境相符。

email_session_mismatch400

Email 與目前 session 的帳號不符

用登入中的帳號自己的 Email。

google_oauth_not_configured501

平台尚未配置 Google 憑證

暫時改用 Email 登入,或等平台配置完成。

pay_service_disabled403

支付服務未在 App 啟用

到開發者控制台勾選支付服務。

pay_user_required400

這支端點需要終端用戶憑證

改帶使用者的 access_token,而不是只有 App Secret。

pay_bad_status400

目前狀態不允許這個動作

先 GET 最新狀態;例如只有 succeeded 的意圖可以退款。

pay_race409

狀態被其他請求搶先改掉

重讀最新狀態後再試一次;不要假設第一次一定成功。

pay_refund_conflict409

同時有另一筆退款在退同一筆餘額

重讀 refundableCents,用較小的金額重試。

pay_refund_amount_invalid400

退款金額 ≤ 0 或大於可退餘額

用 GET /v1/pay/intents/{id}/refunds 取得可退餘額。

pay_intent_not_found404

收款意圖不存在或不屬於這個 App

確認 intentId;跨 App 的意圖一律視為不存在。

pay_order_not_found404

訂單不存在或不屬於這個 App

確認 orderId 與 App。

pay_order_app_only403

更新履約狀態只能用 App Secret

在後端呼叫,不要把 secret 放前端。

hcoin_insufficient409

HCoin 餘額不足

到控制台查看餘額與用量;這是開發者帳務,不是使用者付款。

rate_limited429

超出 RPM/每日/IP 限流

指數退避;同時檢查回應的 dimension 與 limit。

already_friends409

已經是好友

不要重送邀請,改成讀好友名單。

already_published409

文件已上線,請用「發布更新」

走發布流程,不要重複建立。

04三條原則

接進程式碼之前,先記這三條。

會用這三條,就能處理九成的失敗情境。

01

401 → 先換 token,不要重試

同一個過期的 token 打十次還是 401。用 refresh_token 換新的;換不到就重新走登入。

02

429 → 退避,不要硬撞

回應會告訴你是 rpm、daily 還是 ip_rpm。1s → 2s → 4s 退避;持續 429 請去看方案與用量。

03

5xx → 可以重試,但要能回報

退避重試 1–2 次。仍失敗請留下端點、時間、請求 body 與回應,貼到開發者控制台。

找不到你的錯誤碼?先到 API 參考 打開那支端點看「可能錯誤」,或直接在 Playground 用同一組參數重打一次。