IOSOR 知識庫

傳送 API 冪等:重複、重試與金錢

預付傳送 API 導則——冪等鍵、安全重試、防重複與帳簿友善關聯,避免工程失誤成為財務事故。每個重複都會出現在錢包裡,必須以已驗證的呼叫與可對帳的扣款為基礎。

逾時會發生。負載平衡會重試。行動客戶端會連點兩下。沒有冪等,「只送一次」的產品會變成預付雙重扣款與重複 OTP 體驗。本指南為整合白標預付訊息 API 的工程與技術產品設計,確保重複事件與財務共用同一敘事。

為什麼重複會變成金錢問題

失敗模式 使用者看到 錢包看到
用戶端逾時 + 盲目重試 兩則 OTP / 兩則提醒 兩筆扣款
非冪等 webhook 處理 雙重副作用 成功狀態混亂
使用者重送到自動重試上 惱怒的使用者 計量累加
缺少關聯 「失敗了」工單 對不上的帳簿列 。

示範會原諒。生產財務不會。在預付強度下,週末的盲目重試會變成對帳專案,而不是日誌註腳。幸福路徑與逾時路徑必須遵守同一扣款規則。

扛得住重試的冪等鍵

認真的傳送路徑接受客戶端產生的鍵(或等效物),並需:

  1. 依業務意圖唯一(不是依 TCP 嘗試)
  2. 在明確 TTL 視窗內重播時回傳同一已接受結果
  3. 不會為同一意圖靜默建立第二筆扣款
  4. 與訊息 ID、預付參考一併記錄
  5. 涵蓋逾時、閘道重試與支援補推

若唯一建議是「加大逾時」,你還沒有冪等故事。鍵必須跨執行時與 worker 穩定,避免第二個行程為同一次點擊再發明新鍵。

重試預算 vs 使用者重送

自動重試需要預算:最大次數、退避,以及哪些錯誤類可重試。使用者發起的重送是另一產品動作,自帶預付成本。混在一起,會把不穩定網路變成週末錢包事件。

兩者都要搭配餘額不足即停與清楚拒絕原因,讓產品與財務共享同一真相。公布哪些 HTTP 狀態與平台碼可安全重試;其餘一律硬停,需要人工或新的業務意圖。

危險訊號

  • 沒有鍵卻「一直重試到 200」
  • Webhook 處理非冪等
  • 完整金鑰出現在日誌或工單
  • 把上游品牌原文貼給終端使用者
  • 無法向財務證明已阻止重複。

若銷售頁或維運貼文出現以上任一項,先停整合,直到工程用證據補上缺口。

從 IOSOR 開始

在發送主控台用用戶端冪等鍵發一則 OTP 或警示。強迫用戶端逾時,在鍵的 TTL 內重放同一請求。打開預付 ledger:這個意圖只能有一筆 debit、一則使用者看得到的訊息。出現兩列代表鍵沒撐過重試——先修 TTL 與處理函式,再讓走廊維持 Live。

IOSOR 要點

要做:每次發送先當 ledger 事件。冪等鍵對業務意圖唯一,不是對 TCP 嘗試。自動重試有預算;使用者再按一次是另一個產品動作,自帶預付成本。

不要:沒帶鍵一路打到 200,或讓非冪等 webhook 再做一次副作用。一次點擊兩則 OTP 是金錢缺陷,不是網路藉口。

實戰:建立安全的重試機制

以「預付交易」為核心設計重試邏輯,例如:

  • 使用 UUID 或業務唯一 ID 作為冪等鍵,確保其在指定 TTL 內對同一業務意圖保持穩定性。
  • 重試時保留原始交易 ID 並標記狀態,以便追蹤與對帳,避免重複處理。
  • 建立分級重試策略:例如,對暫時性網路錯誤(如 HTTP 5xx 狀態碼)進行有限次數的指數退避重試,但對明顯的客戶端錯誤(如 HTTP 4xx 狀態碼)或業務邏輯錯誤則應立即停止重試,並向用戶端回傳明確的拒絕原因。
  • 透過監控服務追蹤「未處理」與「已處理」的階段差,並設定告警,以便及時發現潛在的重複處理或遺漏。
  • 與財務系統同步確認付款狀態,確保在進行扣款或確認交易前,已檢查並確認該筆業務意圖尚未被處理,從而避免雙重扣款。
  • 保留詳盡的重試日誌供對帳,非生產環境需同步模擬,以驗證重試邏輯的正確性與安全性。
  • 實施「靜默期」或「安靜時間」(Quiet Hours)機制,在特定時段(如深夜)限制自動重試的頻率或次數,以減少對用戶的干擾並降低非預期扣款的風險。
  • 確保 DLR(Delivery Report)的處理也是冪等的,避免因重複的 DLR 回報而導致帳戶狀態異常。
  • 建立清晰的「走廊」(Corridor)機制,定義哪些錯誤狀態可以進入重試流程,哪些必須被終止,並確保所有進入重試流程的請求都必須通過冪等鍵的驗證。

設計時需以「避免資金損失」為優先,而非僅僅追求「網路穩定性」。即使遭遇重試,也必須讓財務資料保持唯一性與可追溯性,確保每一次扣款都有明確的業務關聯與授權。

這篇指南有幫助嗎?

相關指南