天天看點

支付系統設計中,如何防止重複支付?

  在我們支付系統設計中,經常會遇到這樣一個問題,防止使用者重複支付。使用者明明隻想購買一次,卻因為系統問題,導緻重複支付,帶來額外的物流成本和扯皮退貨的營運成本,對商家的信譽和系統的體驗很不好。

  那麼實際我們在設計支付系統時,如何來避免這一問題呢。

為什麼會出現重複支付

 1.客戶誤操作點了兩次

  比如下單的按鍵在點按之後,在沒有收到後端傳回之前,按鍵的狀态沒有設為已禁用狀态,還可以被按。

 2.支付管道端傳回逾時

  使用者在收銀台頁面點選某個支付方式後,在支付管道(比如網銀或者微信支付寶)上完成付款,但是管道端傳回的異步通知逾時,導緻系統付款狀态尚未更新,使用者并不清楚到底訂單是否支付成功,而導緻再次支付。

如何防止重複支付送出

  在我們實際支付系統設計中,我們系統設計人員經常無法區分商品訂單和支付訂單之間的關系,經常混為一談。是以本文談論的是支付訂單的防重複,商品訂單的防重複需要另外讨論(包括使用者誤操作、用戶端和背景時延、以及支付和商品訂單狀态更新不同步等問題)。

  對于支付重複送出的處理,一般有兩種主流的辦法:一種是京東收銀台的,京東允許客戶對一筆商品訂單做多次支付,而對于第二筆以上的支付,走退款流程;另外一種是對訂單幂等要求比較高的銀行收銀台,往往是要求商品訂單狀态和支付訂單狀态強一緻性。

  這裡,我們重點讨論第二種方式,保持支付訂單的幂等性來防止重複支付。

  針對一筆商品訂單,在支付時,産生一個唯一的支付訂單号,這個支付訂單号包含了客戶標明的支付落地的支付方式和真正的支付管道。

 支付系統對這個支付訂單号做交易的幂等。

  1.如果不存在該支付訂單号,則記庫,并标記狀态為支付中,然後調用管道進行支付落地。

  2.收到管道異步通知或者通過查詢得到管道支付狀态時,更新該筆支付訂單狀态

  3.如果客戶再次發起支付,不給客戶産生新的支付訂單号,先用該筆支付訂單号調用支付系統,支付系統會判斷訂單号幂等性,如果已支付,則報錯告訴客戶已支付成功,請勿重複支付;如果支付失敗,則新産生流水調用管道進行支付落地;如果支付狀态未知,則告訴客戶,交易狀态未知,請發起查詢或者關單。

  4.針對狀态未知這種情況,如果支援沖正和關單則最好,如果不行,隻能讓客戶發起查詢。在這種情況下,如果客戶等不及,才流轉到最壞的可能,客戶重新下一單商品訂單,這單根據最終管道對賬情況,給客戶做退款。這種情況下需提示客戶确認未發起前一筆支付,再新建立,否則,前一筆需要等第二個工作日狀态确認後進行退款處理。

如果出現上述最壞情況怎麼辦

  如果出現上述4裡面最壞的情況,還是會有使用者誤操作,直到收到兩份商品才發現下重了。此時就得依靠營運/客服的支援了。提供使用者申訴的手段,讓使用者提出哪些訂單是重複的,并且由銷售系統店家、商品提供者和買家三方共同根據使用者操作的記錄來協商如何處理。我們需要讓技術幫助讓這種人工處理的幾率盡量小。因為每次處理都會耗費較大的人工成本,和一些營運費用(比如賠款、小禮品等等)。

結論

  在實際設計中,無論多麼好的技術,也不可能100%的攔截所有的可能性,必須依靠技術+産品設計+營運支援的綜合手段才能解決這類問題。是以即便京東這一類電商等也是配合營運手段進行處理。

  在實際業務場景中,可能還會有各種各樣複雜的情況,我們隻能以盡可能保護我們系統自己的方式,将重複下單可能性降到最小,并且即使發生,我們也不能出現短款,再結合營運手段進行差錯處理。

原文:https://blog.csdn.net/weixin_34223655/article/details/87647725