Day 9 把單聚合成了三層、昨天拔掉了狀態機,現在要收錢了。金流是這個系統第一次把「正確」交到別人手上——付款發生在銀行那邊,你只能透過不可靠的網路得知結果。教科書會警告你三個坑:通知會重複、會亂序、會根本不來。這章要講的是:當年這三個坑,我們一個都沒踩——不是運氣好,是設計選了一個沒有坑的地形。
付款方式四種:兩家銀行,提供智慧轉帳和信用卡,外加一個自訂的現金付款(營運線下收款後入帳)。而且有個一開始就存在的硬需求:部分付款——轉帳單筆上限 30,000,一筆 150,000 的結帳,客人要拆五張轉帳付完。
這個需求宣判了「is_paid 布林」的死刑:錢是分批、分渠道、非同步到的。當年的資料模型是:

三個設計決定,注意它們環環相扣:
先把坑講清楚,因為它們是真的,業界天天在踩。在「回調更新狀態」的世界裡:
三個坑,三套防禦,每套都是額外的程式碼和額外的測試面——這是多數金流整合的日常。
金流整合的文章多半在教你怎麼把三個坑守好:冪等鍵怎麼設計、亂序怎麼緩衝、補償查詢多久跑一次。這些都對,但它們是在錯的地形上打仗的技巧。當年的系統沒有這些防禦,卻也沒有這些傷——因為「事實只進不改、狀態讀時派生」讓坑本身不存在。這給我的長期教訓是:遇到一類反覆出現的 bug,先別急著加防禦,問一句:有沒有一種資料模型,讓這類 bug 沒有立足點? 防禦是利息,地形是本金。
而當年的系統,這三個坑的體感是:「好像沒遇到什麼問題」。明天把原因攤開:為什麼這是一個沒有坑的地形。
本文改寫自我的部落格系列《Re:從零開始做直播代購電商平台》,本篇完整版:https://blog.aidan.tw/blog/rezero-payment/