iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0
Software Development

Re:從零開始做直播代購電商平台系列 第 11 篇

Day 11|第三方金流(上):教科書的三個坑

  • 分享至 

  • xImage
  •  

Day 9 把單聚合成了三層、昨天拔掉了狀態機,現在要收錢了。金流是這個系統第一次把「正確」交到別人手上——付款發生在銀行那邊,你只能透過不可靠的網路得知結果。教科書會警告你三個坑:通知會重複、會亂序、會根本不來。這章要講的是:當年這三個坑,我們一個都沒踩——不是運氣好,是設計選了一個沒有坑的地形。

當年的付款版圖

付款方式四種:兩家銀行,提供智慧轉帳和信用卡,外加一個自訂的現金付款(營運線下收款後入帳)。而且有個一開始就存在的硬需求:部分付款——轉帳單筆上限 30,000,一筆 150,000 的結帳,客人要拆五張轉帳付完。

這個需求宣判了「is_paid 布林」的死刑:錢是分批、分渠道、非同步到的。當年的資料模型是:

每個 provider 一張事實表、只進不改;payment 的狀態是讀取時算出來的,不是被誰更新出來的。

三個設計決定,注意它們環環相扣:

  • 每個第三方一張事實表。 銀行 A 的轉帳、銀行 A 的信用卡、銀行 B、現金——各自的原始事實各自存,不揉進同一張「通用付款表」硬塞欄位。新增付款方式=新增一張事實表+一條聚合規則,「現金」就只是一個由營運標記入帳的 provider。
  • payment 的狀態是派生的,讀取時才算。 已付與否=入帳事實加總對應付金額,不存在一個被 UPDATE 的狀態欄位。
  • webhook 和 polling 都做,寫同一組事實表。 教科書要你在「即時但可能漏」和「可靠但慢」之間選——這裡全都要。

教科書的三個坑

先把坑講清楚,因為它們是真的,業界天天在踩。在「回調更新狀態」的世界裡:

  1. 重複通知:銀行重送一次「付款成功」,你的狀態就轉移兩次——輕則 log 髒掉,重則重複出貨、重複開發票。所以要設計冪等鍵。
  2. 亂序:「付款成功」比「訂單成立」的內部處理先到,或兩筆部分付款的通知顛倒——狀態機走錯方向,可能永遠回不來。所以要序號、要緩衝、要補償邏輯。
  3. 根本不來:網路丟了、銀行忘了,你的訂單卡在「等待付款」直到天荒地老。所以要主動查單兜底。

三個坑,三套防禦,每套都是額外的程式碼和額外的測試面——這是多數金流整合的日常。

反思

最好的防禦,是選地形

金流整合的文章多半在教你怎麼把三個坑守好:冪等鍵怎麼設計、亂序怎麼緩衝、補償查詢多久跑一次。這些都對,但它們是在錯的地形上打仗的技巧。當年的系統沒有這些防禦,卻也沒有這些傷——因為「事實只進不改、狀態讀時派生」讓坑本身不存在。這給我的長期教訓是:遇到一類反覆出現的 bug,先別急著加防禦,問一句:有沒有一種資料模型,讓這類 bug 沒有立足點? 防禦是利息,地形是本金。

而當年的系統,這三個坑的體感是:「好像沒遇到什麼問題」。明天把原因攤開:為什麼這是一個沒有坑的地形。


本文改寫自我的部落格系列《Re:從零開始做直播代購電商平台》,本篇完整版:https://blog.aidan.tw/blog/rezero-payment/


上一篇
Day 10|購物車到訂單(下):被主播拔掉的狀態機
系列文
Re:從零開始做直播代購電商平台 共 11 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言