串金流不難,對帳才難。 大部分電商團隊在選型時都低估這件事——你以為金流是一個 API call,回傳成功就結束了;實際上,真正的成本要等你開始處理退款、分期、跨境、優惠券退單、第三方支付對帳檔之後才會浮現。
為什麼金流會在上線三個月後爆炸
剛上線時,訂單量小、退款少、客服還能用人工核對 Excel。問題出在規模長起來之後。
想像一個典型情境:一家中型電商同時接了信用卡、超商代收、行動支付、分期付款,外加跨境用的另一組金流。每一家的對帳檔格式、入帳時間、手續費計算邏輯都不一樣。信用卡可能 T+2 入帳,超商代收 T+7,跨境的還要扣匯差和當地稅。
當你開出一張退款,這張退款可能:
- 在金流商那邊已經處理,但對帳檔還沒更新
- 部分退款(例如三件退兩件),手續費怎麼算各家規則不同
- 牽涉到分期,要拆回每一期的應退金額
- 用了優惠券、紅利、運費補貼,實際金流和訂單金額對不起來
這時候如果你的訂單系統只有一個 status 欄位在 paid / refunded 之間切換,後面的會計、客服、財報全部會出問題。
系統設計要把「帳」當成一等公民
我們在報價時通常會這樣建議客戶:金流不是一個模組,是兩個——交易流和對帳流要分開設計。
交易流負責和金流商互動、處理付款與退款請求;對帳流負責定期拉對帳檔、和內部交易紀錄逐筆比對、把差異標記出來給人工處理。兩者透過一個統一的「交易事件表」連起來。
一個最小骨架大概像這樣:
# 示意:實際欄位請依業務需求設計
class TransactionEvent:
order_id: str
provider: str # 哪一家金流
provider_txn_id: str # 對方的單號
event_type: str # auth / capture / refund / chargeback
amount: int # 以最小單位儲存,避免浮點
currency: str
fee: int # 手續費,可能稍後才知道
occurred_at: datetime # 對方時間
recorded_at: datetime # 我方時間
raw_payload: dict # 原始回應,務必保留
幾個重點:
- 永遠保留原始 payload。出事時要回溯,沒這個就只能猜。
- 金額用整數最小單位(分、cent),不要用 float。
- 每一筆事件 append-only,不要 update 舊紀錄。退款是新事件,不是改舊狀態。
- 訂單狀態由事件推導出來,不是直接寫死。這樣對帳差異才追得回來。
至於要不要自建?如果你的金流組合單純、量也不大,Shopify 或現成 SaaS 的內建對帳通常夠用。一旦你開始接多家金流、跨境、或有複雜的促銷折讓邏輯,自建一層交易事件中間層幾乎是遲早的事。
我們的觀察
金流串接的工時,真正燒在「成功路徑」的可能不到三分之一,其餘都在處理各種失敗、延遲、不一致。團隊在做電商選型時,與其問「這個平台支不支援某某金流」,不如問「它的對帳資料能不能匯出、能不能 webhook、能不能讓我自己存一份」。能拿到原始資料的系統,後面才有救;拿不到的,三個月後你會很痛苦。
