大廠是怎麼做支付系統的流程容錯的?

架構師修行手冊發表於2024-01-15

來源:JavaEdge

1 單據關聯

如某些訂單域內部的多種單據間存在關聯關係一樣,支付設計上也有單據間關聯設計。如所有逆向過程都須持有正向的單據,因此退款須關聯到原來的支付,退款支付單要關聯到原支付單。單據之間關聯只有以下用途:

狀態一致性

正如訂單域中的訂單單據如果成功,則訂單關聯的營銷單、支付單一定成功。支付場景各單據狀態也存在關聯關係,如建立退款支付單的前提是所關聯的原支付單須成功

金額一致性

金額控制是退款核心問題,易產生資損。由於支援多次部分退款,金額須防止超退:總金額不能退超,各維度的資金組成組成不能退超。

實現:每筆退款的金額,都在原單累加記錄到已退金額,記錄已退款的總金額,校驗不可超。

2 冪等

透過唯一鍵實現冪等。如:

  • 訂單側常見的重複支付退款以訂單號關聯 PaymentNo 做重複支付校驗唯一鍵
  • 支付側交易單以外部單號 + 商戶號為唯一鍵,支付單以交易單號 + 操作碼作為唯一鍵

冪等可重入問題:如對一筆整單退請求,上游請求退款 200 元,支付域已處理成功,上游由於超時基於同一筆支付單號進行退款重試,此時應返回成功而非業務校驗異常。

3 重試

最大努力通知,支付領域常見的流程容錯手段,分散式環境的網路抖動、服務暫時不可用都會造成業務流程處理異常。常見解決方案即將請求放入 MQ 非同步重試,重試間隔逐次拉長:

  • 重試成功,則回撥交易
  • 失敗或處理中,則繼續重試。所以介面冪等支援可重入很重要,才能支援重試!

如訂單收到支付成功回撥後,開始處理訂單流程。如果在下單階段僅鎖定庫存、營銷等資源,需要在支付回撥流程真正扣減資源的話,這裡需要對超時等場景進行重試(呼叫下游需要做好冪等),如資源扣減失敗則關單退款。

重試指定次數如業務單據仍未到達終態,則將訂單資訊持久到資料庫中,通知人工進行處理。如使用者卡登出,會員銷戶等問題導致退款退不出去,重試一定次數後支付單隻能置為失敗。等待產運聯絡使用者後,在支付層重新生成退款支付單進行退款。

來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70027824/viewspace-3003856/,如需轉載,請註明出處,否則將追究法律責任。

相關文章