支付系統防重複支付

方案一(不允許多次支付):

  1. 針對一筆商品訂單,在支付時,根據客戶選定的支付落地的支付方式和、真正的支付渠道、訂單創建時間等等信息產生一個唯一的支付訂單號,支付系統對這個支付訂單號做交易的冪等。
  2. 如果不存在該支付訂單號,則寫入數據庫,並標記狀態爲支付中,然後調用支付接口。
  3. 收到支付接口回調的通知或者查詢到支付狀態時,更新支付訂單狀態。
  4. 如果客戶再次發起支付,先用該筆支付訂單號調用支付系統,支付系統會判斷訂單號冪等性,如果已支付,則報錯告訴客戶已支付成功,請勿重複支付;如果支付失敗,則產生新流水調用支付接口;如果支付狀態未知,則告訴客戶,交易狀態未知,如果支持衝正交易和關閉訂單則最好,如果不行,只能讓客戶發起查詢。
  5. 如果客戶等不及,重新下一單商品訂單,重新支付,根據業務邏輯判斷是否需要退款(可以兩個訂單同時成功,讓客戶判斷是否申請退款,若是一次支付商品如某考試報名費用,這種情況下需提示客戶確認未發起前一筆支付,再新創建,否則前一筆需要等幾個工作日狀態確認後進行退款處理)。

方案二(不允許多次支付):

  1. 系統生成商品訂單前,由系統生成token指令存放在session或者其他緩存中,然後生成訂單時隱藏在訂單表單中。
  2. 客戶提交訂單支付請求時,將token與session中的token比較,一致則調用支付接口,並在調用後移除session中的token。
  3. 收到支付接口回調的通知或者查詢到支付狀態時,更新支付訂單狀態。
  4. 客戶再次支付時,此時由於session中的token已經移除,token比對不上,則根據token查詢支付結果,如果支付成功則禁止支付,支付不成功則允許重新支付。
  5. 如果客戶重新下商品訂單,重新支付,這種情況下如果前一訂單已經支付,需要客戶自己對前一訂單進行退款申請(對於一次支付商品,如某某考試報名費用,可寫定時任務做查重後主動退款)。

方案三(允許多次支付):

  1. 針對一筆商品訂單(商品訂單號唯一),發起支付,後臺調用第三方支付接口。
  2. 加入消息中間件ActiveMQ,當第三方支付回調網站接口,網站接口收到消息直接插入消息中間件同時返回給第三方支付接口結果。
  3. 消息持久化並判斷消息冪等性(即保證消息不重複使用),更新數據庫,若消息中間件一定時間未收到消息時,則需查詢支付狀態,將查詢結果生成消息,對消息處理更新數據庫。
  4. 如果客服再次支付,仍然走正常支付流程。
  5. 加入定時任務,負責調用第三方支付查詢接口,驗證未支付的訂單是否支付成功、是否有訂單重複支付的,以更新訂單支付狀態或退款。
  6. 增加調用及接收第三方支付的消息日誌功能(主要爲了出問題時候的分析排查),有時候也有可能第三方支付服務器掛掉了就真的沒回調接口。

以上方法均是後端防重複支付方法,前端可以寫js代碼,當支付界面打開後,訂單的支付按鈕就失效,但是前端很容易被繞過,所以僅能當作防重複支付的一個補充使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章