支付流程設計常見問題及最佳實踐

0 評論 606 瀏覽 0 收藏 12 分鐘

在實際操作中,支付流程常常面臨諸多問題。本文將深入探討支付流程設計中的常見問題及其最佳實踐,供大家參考。

今天聊一下支付流程設計的一些常見總是及最佳實踐,包括:

組合支付要不要拆支付流水,前端輪詢查哪個域,查詢要不要穿透到外部渠道,為什么要做同步受理異步處理,支付補償怎么做,如何防重復支付,萬一重復支付了怎么做,支付成功后用戶關單了怎么做,返回碼怎么映射,支付要不要做系統自動重試,支付渠道如何做隔離。

一、組合支付要不要拆支付流水

當然拆。不拆能不能做?也是可以做,但是壞處很多。有更優解的情況下,我們要選擇更優解。

每一種支付方式都有自己的特性,包括但不限于支付金額、支付時間、狀態等,如果放在一筆支付單,如何表達得清楚?

這里還有一個分層的概念,就是面向商戶的是收單域,生成的是交易單,交易單下面可以掛一個主支付單,這個支付單是支付域的,一個支付單下面掛多個支付流水,一個支付方式就生成一筆支付流水。

由支付域來負責多個支付方式的組合,以及主支付單的推進。

二、前端輪詢查哪個域

有人查收單域,有人查支付域。

我的觀點是查收單域。因為收單是針對商戶的,商戶的訂單成功了,才算成功。有時候可能內部出現故障,導致支付域成功但收單域沒有成功,還有可能訂單因為超時或用戶主動操作已經關閉,這個時候支付域哪怕成功,也需要給用戶退回去。

如果是用戶充值,就以資金產品域為準。

為避免對收單域的數據庫造成過大壓力,建議加一層緩存。

標準收銀臺和前置收銀臺又有一點不一樣。上面說的是前置收銀臺的情況。

三、查詢要不要穿透到外部渠道

很多人喜歡直接把查詢穿透到外部渠道,比如用戶提交支付后,在收銀臺頁面轉菊花,收銀臺頁面會有一個定時任務高頻查詢后端的支付結果,這個查詢請求鏈路:收銀臺頁面->收銀臺后端->收單域->支付域->渠道網關域->外部渠道。

如果一旦網絡抖動或外部渠道抽風,返回耗時增加,就會快速把內部應用的線程全部耗盡,極易引發雪崩。有興趣的可以翻翻公眾號前段時間發布的關于雪崩的超級故障。

正確的做法:

收銀臺只查自己的緩存,支付域有新數據后,更新到緩存,比如支付成功,或者需要跳到核身驗證頁面。

四、為什么要做同步受理異步處理

原理和上面的查詢不要穿透到外部渠道是一個道理,如果一旦網絡抖動或外部渠道抽風,返回耗時增加,就會快速把內部應用的線程全部耗盡,極易引發雪崩。

正確的做法:同步受理商戶的請求后,馬上返回給商戶,然后再異步處理,發送給渠道。

是不是每個域都做同步受理異步處理?也不是,那樣就太復雜了。

可以選擇在收單域做,也可以選擇在渠道網關域做。推薦在渠道網關域做,因為外部渠道的耗時最不可控,大不了多部署幾臺網關,多開些線程。還有一個情況,比如只需要扣余額,那就直接毫秒級扣完返回給商戶,簡單實用。

如果一定要選擇所有域都做,那也是個人的自由。但強烈不建議全部同步調用出去。

五、支付狀態補償怎么做

支付發出后,有四種情況可以獲得支付的結果:

  1. 渠道接口實時返回渠道處理的結果。
  2. 渠道異步通知支付平臺。
  3. 支付平臺使用定時任務梯度時間查詢渠道支付結果。
  4. 拿到渠道對賬文件。

時效性而言,依次遞減,但也不是絕對的,有時候會出現渠道異步通知比接口實時返回還要快。這個時候一定要設計好狀態機,否則很容易出現異步結果已經推進成功,實時接口又推進到支付中。

定時查詢查詢一定要用梯度,一方面減少自己平臺和渠道壓力,同時又能獲得最好的時效性,比如間隔時間:1秒,2秒,5秒,10秒,20秒,40秒,100秒 … … 查到n次就不查了。再查下去也沒有意義,就等渠道文件對賬好了。如果渠道的對賬文件是支付成功,但是平臺支付已經關閉訂單,那就走差錯給用戶退回去就好。

六、如何防重復支付

重復支付在很多公司都出現過,強大如支付寶,也時不時爆出大批量的重復支付。

首先是接口要有冪等設計。冪等的設計也有很多種方式,有人喜歡使用redis分布式鎖,我個人是反對的,起碼也要使用數據庫唯一索引。單機房使用唯一索引就夠,如果全球多活怎么辦?還得有一個全局冪等組件。具體怎么設計,可以在公眾號里找下:支付冪等設計與最佳實踐。

但是,冪等設計是基于商戶不換號的情況下,如果商戶換號重發,就防不住,怎么辦?最好是基于用戶的維度做個判斷,比如同一個用戶,在短時間(比如1分鐘),已經存在相同金額的支付單,就給用戶提示:“當前已經有一筆xx金額的訂單,是否仍然支付?”。雖然不能完全避免,但是可以減少。

七、萬一重復支付了怎么做

前面有提出防重復支付,但是萬一真出現重復支付了怎么辦?

沒有什么好辦法,原路退回就是。

這也是我們為什么在前面把交易單和支付單區分出來的原因。各是各的單,出現問題好處理。

還有一個問題,如何發現內部有大批量的重復支付?總不能全部等客訴吧?后面有時間再聊聊支付平臺內部多域之間實時兩兩對賬。

八、支付成功后用戶關單了怎么做

不僅是重復支付后需要原路退回,如果渠道扣款成功,但是我們的訂單已經關閉(超期關閉,用戶主動關閉等),都需要做原路退回。

這里還可以引申出另外一個問題,為什么記賬的時候,有一個“商戶待結算戶:,還有一個“支付網關過渡戶”。如果沒有支付網關過渡戶,支付成功,錢直接到了商戶待結算戶,但是如果收單域的訂單已經關閉,這筆錢就不應該進入到商戶待結算戶里去,而是應該直接從支付網關過渡戶給用戶退回去。

九、返回碼怎么映射

對于支付來說,不要輕易推進到成功,只有渠道非常明確地說,某個返回碼代表成功,才能推進成功。否則很容易出現資損。

當然也不要輕易推進失敗,也只有明確失敗才能推進失敗,否則用戶支付成功被推進失敗,容易引起客訴。

尤其要注意的是,有很多渠道有兩級返回碼,要區分如何組合使用。還有,查詢接口一定要區分通信成功和業務成功,只能通過業務成功來推進狀態。

更詳細的說明,可以翻翻公眾號的文章;返回碼映射設計與最佳實踐。

十、支付要不要做系統自動重發

網絡經常超時,如果用戶發起支付,超時了,再次重試,就會成功,那到底要不要系統自動重試呢?建議根據自己的業務場景和團隊的技術實力選擇。

業務場景,比如代扣,一定要系統自動重試,包括余額不足,超時等場景都需要重試。余額不足再換個支付方式或換張卡再試,超時多次查詢都返回“訂單不存在”,那也需要系統自動重試。

如果是普通的支付,那看團隊是否能做到避免重復扣款,如果能,那就系統自動重試,提高成功率。給一個思路:特定的返回碼 + 指定時間內查詢都是返回“訂單不存在”。

十一、支付渠道如何做隔離

有人喜歡為每一個渠道都編寫獨立的代碼,美其名曰:“隔離性好”,一個渠道有問題不影響另外一個。

我卻覺得技術和架構能力需要提高。渠道接入四個層次:

  1. 為每個渠道寫獨立的代碼。
  2. 抽象出模板方式,每個渠道只需要寫特定的代碼,比如報文組裝、簽名驗簽。流程由模板方法驅動。
  3. 配置文件接入渠道。把渠道的處理分解成多個子能力,通過配置文件驅動。
  4. 直接在后臺頁面配置映射就能接入。

只要領域抽象能力強,技術過硬,哪怕做到第四層,仍然可以做到很好的隔離。比如通過外部渠道分配的商戶號,隔離出不同的配置,不同的渠道配置不同的參數,自動化測試回歸,保存歷史報文用于自動化MOCK測試等。質量仍然是上乘的,隔離性也完全沒問題。

本文由人人都是產品經理作者【隱墨星辰】,微信公眾號:【隱墨星辰】,原創/授權 發布于人人都是產品經理,未經許可,禁止轉載。

題圖來自Unsplash,基于 CC0 協議。

更多精彩內容,請關注人人都是產品經理微信公眾號或下載App
評論
評論請登錄
  1. 目前還沒評論,等你發揮!