在我們支付系統設計中,經常會遇到這樣一個問題,防止用戶重復支付。用戶明明只想購買一次,卻因為系統問題,導致重復支付,帶來額外的物流成本和扯皮退貨的運營成本,對商家的信譽和系統的體驗很不好。
那么實際我們在設計支付系統時,如何來避免這一問題呢。
為什么會出現重復支付
1.客戶誤操作點了兩次
比如下單的按鍵在點按之后,在沒有收到后端返回之前,按鍵的狀態沒有設為已禁用狀態,還可以被按。
2.支付渠道端返回超時
用戶在收銀台頁面點擊某個支付方式后,在支付渠道(比如網銀或者微信支付寶)上完成付款,但是渠道端返回的異步通知超時,導致系統付款狀態尚未更新,用戶並不清楚到底訂單是否支付成功,而導致再次支付。
如何防止重復支付提交
在我們實際支付系統設計中,我們系統設計人員經常無法區分商品訂單和支付訂單之間的關系,經常混為一談。所以本文談論的是支付訂單的防重復,商品訂單的防重復需要另外討論(包括用戶誤操作、客戶端和后台時延、以及支付和商品訂單狀態更新不同步等問題)。
對於支付重復提交的處理,一般有兩種主流的辦法:一種是京東收銀台的,京東允許客戶對一筆商品訂單做多次支付,而對於第二筆以上的支付,走退款流程;另外一種是對訂單冪等要求比較高的銀行收銀台,往往是要求商品訂單狀態和支付訂單狀態強一致性。
這里,我們重點討論第二種方式,保持支付訂單的冪等性來防止重復支付。
針對一筆商品訂單,在支付時,產生一個唯一的支付訂單號,這個支付訂單號包含了客戶選定的支付落地的支付方式和真正的支付渠道。
支付系統對這個支付訂單號做交易的冪等。
1.如果不存在該支付訂單號,則記庫,並標記狀態為支付中,然后調用渠道進行支付落地。
2.收到渠道異步通知或者通過查詢得到渠道支付狀態時,更新該筆支付訂單狀態
3.如果客戶再次發起支付,不給客戶產生新的支付訂單號,先用該筆支付訂單號調用支付系統,支付系統會判斷訂單號冪等性,如果已支付,則報錯告訴客戶已支付成功,請勿重復支付;如果支付失敗,則新產生流水調用渠道進行支付落地;如果支付狀態未知,則告訴客戶,交易狀態未知,請發起查詢或者關單。
4.針對狀態未知這種情況,如果支持沖正和關單則最好,如果不行,只能讓客戶發起查詢。在這種情況下,如果客戶等不及,才流轉到最壞的可能,客戶重新下一單商品訂單,這單根據最終渠道對賬情況,給客戶做退款。這種情況下需提示客戶確認未發起前一筆支付,再新創建,否則,前一筆需要等第二個工作日狀態確認后進行退款處理。
如果出現上述最壞情況怎么辦
如果出現上述4里面最壞的情況,還是會有用戶誤操作,直到收到兩份商品才發現下重了。此時就得依靠運營/客服的支持了。提供用戶申訴的手段,讓用戶提出哪些訂單是重復的,並且由銷售系統店家、商品提供者和買家三方共同根據用戶操作的記錄來協商如何處理。我們需要讓技術幫助讓這種人工處理的幾率盡量小。因為每次處理都會耗費較大的人工成本,和一些運營費用(比如賠款、小禮品等等)。
結論
在實際設計中,無論多么好的技術,也不可能100%的攔截所有的可能性,必須依靠技術+產品設計+運營支持的綜合手段才能解決這類問題。所以即便京東這一類電商等也是配合運營手段進行處理。
在實際業務場景中,可能還會有各種各樣復雜的情況,我們只能以盡可能保護我們系統自己的方式,將重復下單可能性降到最小,並且即使發生,我們也不能出現短款,再結合運營手段進行差錯處理。
原文:https://blog.csdn.net/weixin_34223655/article/details/87647725