支付中心-重復支付問題解決方案
一筆訂單,可以做多筆支付,怎么解決?
重復支付的異常背景
- 一筆訂單,在支付中心可以選擇多種支付方式。如支付寶掃碼,支付寶app,微信掃碼,微信小程序,銀聯....
- 用戶選擇支付方式后,系統需要和第三方進行交互,獲取到結果后,可能跳轉到第三方收銀台,也可能在當前頁面展示收款二維碼;
- 用戶打開一種支付方式,沒有完成付款的情況下,又選擇打開了其他支付方式。如准備用微信支付,打開收款二維碼后,發現微信余額不足,遂即打開支付寶支付,此時兩個支付方式都可以做支付操作。
- 由於產生待支付單后,支付狀態是不可控的,支付狀態由第三方回調信息中獲取。所以很難控制支付單的再次產生。
概念解釋:
- 支付單:具體的支付方式,如 支付寶的掃碼支付,微信小程序支付
- 一個訂單對應多個支付單,但一個訂單下 只允許出現 一筆成功的支付單
支付流程
支付流程是一套異步的操作。
- 用戶選擇支付方式
- 跳轉到對應的收銀台
- 用戶支付成功
- 第三方回調系統
- 修改訂單狀態
不可控的因素是在第三和第四步。
解決方案
第一步
用戶的一個訂單,選擇支付方式觸發第三方支付平台之前,先掃描該訂單下的待支付訂單,如果存在,調用其訂單關閉接口,使之前的待支付單立即失效。然后再創建新的支付單做支付。
理想狀態下,創建的支付單可以隨時關閉,這就可以完美解決重復支付問題。
不完美的情況:支付寶的掃碼支付可以隨時關閉支付訂單,但是支付寶的電腦網站支付,必須在用戶掃碼后才能關閉支付訂單。(這一點被坑了很久),應對此問題,解決方案還需要往下走。
第二步
用戶支付成功后,收到第三方的回調通知,修改訂單狀態后,再次掃描待支付的訂單,對其進行關閉訂單的操作。
這個步驟,不僅是對第一步的加強,也是可以適應不同的需求場景。如:一個業務方常用的是微信和支付寶兩種支付方式,為了減少和支付中心的交互次數,就在創建訂單的時候,替用戶創建了這兩種支付的二維碼,讓用戶選擇使用,這種情況下就不能對待支付單做立即關閉了,否則只有一個二維碼是生效的。
所以創建訂單時加了一個選擇策略來控制是否立即關閉歷史支付訂單。然后用第二步來兜底。
到此還是不能完全解決重復支付,原因如下:
- 支付寶的不能及時關閉,到此不一定能完全解決。
- 部分銀行的接口功能中,沒有提供及時關閉訂單的功能。
第三步
針對以上策略下的漏網之魚,還需采取補償策略:
定時任務:定時對賬,通過定時任務,掃描那些支付成功,且實際支付金額大於應收金額的支付單,或者說一個訂單號,存在多筆成功的支付訂單的數據。按時間順序,將后面支付的支付單做主動退款。
這一步還是不能完全解決問題。原因:部分支付平台不支持退款,這種情況下,無法做到主動退款,只能依賴人工操作。
第四步
最后的無奈之舉:發現重復支付的支付單數據,且沒有退款接口可用時。發起一條工單,通知到運營端,讓運營去人工處理。
CLC