錯誤與重試
依 「PAYMENT 應如何重試」 分組,而非只列 HTTP 數字。
原 request/原 key 可安全重送
| 情況 |
HTTP/狀態 |
動作 |
| Submit 超時、未確定是否入列 |
(無回應) |
同一 idempotency_key 重送;或 GET ?idempotency_key= |
| 同 key 同指紋 |
200 replayed |
使用 task 內原單;不要換 key |
| 裝置暫時 503 queue |
503 task queue unavailable |
可短暫重試原 request(若已帶 key,注意是否已建 failed enqueue 單) |
| Unlock 重送(意圖已未鎖) |
200 was_locked=false |
成功,無需再送 |
transfer_verify 失敗(無金流) |
task failed |
可用新或同策略再送 verify(無 money_moved 風險) |
需先 GET 權威狀態
| 情況 |
訊號 |
動作 |
| Callback 遺失 |
無 webhook |
GET enrollment / GET task / GET device |
| Unlock 409 |
stale_lock_generation |
重新 GET locked_at,再決定是否 unlock |
| 冪等 409 conflict |
idempotency_key_conflict |
讀 task;不要當「可換 key 重出款」 |
| 跨 tenant/未知 id |
404 |
確認 id 與 tenant;不洩漏存在性 |
必須使用新 key(非 transfer 出款路徑,或已證明錢未動)
| 情況 |
說明 |
| 非 transfer 任務要重做 |
新業務意圖 → 新 key(若使用 key) |
enqueue_failed/明確 Confirm 前失敗 |
原 key 已綁 failed 單且無 money_moved/needs_reconciliation → 新 key 評估重試 |
| transfer 且 Confirm 前失敗 |
如 review_mismatch;確認 result 無 money-path 禁旗後用新 key |
禁止自動重送/人工對帳
| 條件 |
動作 |
money_moved=true |
禁止重送 transfer |
needs_reconciliation=true |
人工對帳 |
error=interrupted_needs_reconciliation |
人工對帳 |
slip_account_mismatch / slip_account_unreadable 且 money_moved=true |
禁止當成功;禁止重出款 |
ambiguous_match / needs_manual_verification |
人工;勿盲目重出款 |
修正 PIN/解鎖後再試
| 訊號 |
動作 |
423 device_locked |
GET device → 修正 PIN → unlock(正確 generation)→ 再派新任務(注意 transfer key 規則) |
終態 pin_not_configured / pin_locked |
PUT secret;必要時 unlock |
Worker 對已鎖裝置終結 device_locked |
同上;callback 仍可能到達 |
HTTP 速查
| HTTP |
典型 detail/語意 |
粗分 |
| 400 |
ttl_seconds 範圍、enqueue/callback origin 等 |
修正 request |
| 401 |
missing/invalid bearer |
修正 API key |
| 404 |
device/task/enrollment/bank binding 不存在或跨 tenant |
確認 id;勿掃號 |
| 409 |
idempotency_key_conflict、stale_lock_generation、wda_target_conflict、redeem 衝突 |
見上表 GET/決策 |
| 422 |
PIN 格式、payload 驗證、device_code 缺失、idem key 格式 |
修正欄位後可重送(transfer 注意 key) |
| 423 |
device_locked |
解鎖流程 |
| 429 |
redeem 猜測過頻 |
現場/Field 退避;PAYMENT 不直接 redeem |
| 503 |
queue/secrets/script catalog/ready 依賴 |
退避重試;ready 用 /ready |
Money-path 決策(再強調)
money_moved=true → 禁止重送 transfer
needs_reconciliation=true → 禁止重送,人工對帳
interrupted_needs_reconciliation → 禁止重送,人工對帳
verification.deferred=true → 不重送出款,只送 transfer_verify
明確 Confirm 前失敗 → 才能用新 key 評估重試