設計支付系統 (Payment System)

Hard★★★★★Draft

FromSystem Design Interview

Concepts practiced🛡️ 冪等設計 (Idempotency)🤝 分散式交易與兩階段提交 (Distributed Transactions & 2PC)🛡️ 重試與退避 (Retries & Backoff)📨 訊息佇列 (Message Queue)

Convention: read the requirements & constraints first, sketch your own design, then expand the reference to compare.

📚 From the Books

設計支付系統 (Payment System)ProblemHardFintech

電商下單背後的資金流:代賣家收款、再匯款給賣家。難點不在吞吐量,而在正確處理每一筆交易——失敗、重試、重複扣款與跨系統一致性。

📋 Requirements

🧠 Core Ideas

TIP

支付流程串起 payment service(協調+風險檢查)、payment executor(執行單筆 payment order)、PSP(實際搬錢)。核心是保證每筆訂單恰好一次 (exactly-once) 執行,並用對帳當最後一道防線。

金額欄位用 string 而非 double,避免序列化的捨入誤差;只在顯示或計算時才解析成數字。

⚖️ Reference Design

收款流程 (Pay-in)
  • Payment service 收下支付事件、先做風險檢查(AML/CFT),存 DB,再為每筆 payment order 呼叫 executor。
  • Payment executor 透過 PSP 執行單筆訂單;PSP 把錢從買家卡片移到電商銀行帳戶。
  • 成功後依序更新 wallet(賣家餘額)與 ledger(帳本)。
  • 帳本採複式記帳 (double-entry):每筆交易同額借記一方、貸記另一方,總和為 0,提供端對端可追溯性。
PSP 整合與託管頁面
  • 多數公司用 PSP 託管支付頁面 (hosted page / iframe / SDK),敏感卡資訊直接進 PSP,不經過自家系統。
  • 註冊時送一個 UUID (nonce,通常即 payment order ID) 確保「恰好一次」註冊;PSP 回傳 token 存 DB。
  • 付款完成後前端導向 redirect URL,PSP 另以 webhook 非同步通知支付狀態。
失敗處理與內部溝通
  • 支付狀態存 append-only 表,任何階段都能判斷當前狀態、決定重試或退款。
  • 可重試錯誤進重試佇列;反覆失敗落入死信佇列待調查。
  • 內部服務偏好非同步溝通:單一接收者用共享訊息佇列,多接收者(通知、分析、帳單)用 Kafka——以一致性換取擴展性與失敗韌性。

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading