java怎么解决重复支付问题_支付系统设计中,如何防止重复支付?
wallet-2292428_1280.jpg
在我們支付系統(tǒng)設(shè)計中,經(jīng)常會遇到這樣一個問題,防止用戶重復(fù)支付。用戶明明只想購買一次,卻因為系統(tǒng)問題,導(dǎo)致重復(fù)支付,帶來額外的物流成本和扯皮退貨的運營成本,對商家的信譽和系統(tǒng)的體驗很不好。
那么實際我們在設(shè)計支付系統(tǒng)時,如何來避免這一問題呢。
為什么會出現(xiàn)重復(fù)支付
1.客戶誤操作點了兩次
比如下單的按鍵在點按之后,在沒有收到后端返回之前,按鍵的狀態(tài)沒有設(shè)為已禁用狀態(tài),還可以被按。
2.支付渠道端返回超時
用戶在收銀臺頁面點擊某個支付方式后,在支付渠道(比如網(wǎng)銀或者微信支付寶)上完成付款,但是渠道端返回的異步通知超時,導(dǎo)致系統(tǒng)付款狀態(tài)尚未更新,用戶并不清楚到底訂單是否支付成功,而導(dǎo)致再次支付。
如何防止重復(fù)支付提交
在我們實際支付系統(tǒng)設(shè)計中,我們系統(tǒng)設(shè)計人員經(jīng)常無法區(qū)分商品訂單和支付訂單之間的關(guān)系,經(jīng)常混為一談。所以本文談?wù)摰氖侵Ц队唵蔚姆乐貜?fù),商品訂單的防重復(fù)需要另外討論(包括用戶誤操作、客戶端和后臺時延、以及支付和商品訂單狀態(tài)更新不同步等問題)。
對于支付重復(fù)提交的處理,一般有兩種主流的辦法:一種是京東收銀臺的,京東允許客戶對一筆商品訂單做多次支付,而對于第二筆以上的支付,走退款流程;另外一種是對訂單冪等要求比較高的銀行收銀臺,往往是要求商品訂單狀態(tài)和支付訂單狀態(tài)強一致性。
這里,我們重點討論第二種方式,保持支付訂單的冪等性來防止重復(fù)支付。
針對一筆商品訂單,在支付時,產(chǎn)生一個唯一的支付訂單號,這個支付訂單號包含了客戶選定的支付落地的支付方式和真正的支付渠道。
支付系統(tǒng)對這個支付訂單號做交易的冪等。
1.如果不存在該支付訂單號,則記庫,并標(biāo)記狀態(tài)為支付中,然后調(diào)用渠道進行支付落地。
2.收到渠道異步通知或者通過查詢得到渠道支付狀態(tài)時,更新該筆支付訂單狀態(tài)
3.如果客戶再次發(fā)起支付,不給客戶產(chǎn)生新的支付訂單號,先用該筆支付訂單號調(diào)用支付系統(tǒng),支付系統(tǒng)會判斷訂單號冪等性,如果已支付,則報錯告訴客戶已支付成功,請勿重復(fù)支付;如果支付失敗,則新產(chǎn)生流水調(diào)用渠道進行支付落地;如果支付狀態(tài)未知,則告訴客戶,交易狀態(tài)未知,請發(fā)起查詢或者關(guān)單。
4.針對狀態(tài)未知這種情況,如果支持沖正和關(guān)單則最好,如果不行,只能讓客戶發(fā)起查詢。在這種情況下,如果客戶等不及,才流轉(zhuǎn)到最壞的可能,客戶重新下一單商品訂單,這單根據(jù)最終渠道對賬情況,給客戶做退款。這種情況下需提示客戶確認未發(fā)起前一筆支付,再新創(chuàng)建,否則,前一筆需要等第二個工作日狀態(tài)確認后進行退款處理。
如果出現(xiàn)上述最壞情況怎么辦
如果出現(xiàn)上述4里面最壞的情況,還是會有用戶誤操作,直到收到兩份商品才發(fā)現(xiàn)下重了。此時就得依靠運營/客服的支持了。提供用戶申訴的手段,讓用戶提出哪些訂單是重復(fù)的,并且由銷售系統(tǒng)店家、商品提供者和買家三方共同根據(jù)用戶操作的記錄來協(xié)商如何處理。我們需要讓技術(shù)幫助讓這種人工處理的幾率盡量小。因為每次處理都會耗費較大的人工成本,和一些運營費用(比如賠款、小禮品等等)。
結(jié)論
在實際設(shè)計中,無論多么好的技術(shù),也不可能100%的攔截所有的可能性,必須依靠技術(shù)+產(chǎn)品設(shè)計+運營支持的綜合手段才能解決這類問題。所以即便京東這一類電商等也是配合運營手段進行處理。
在實際業(yè)務(wù)場景中,可能還會有各種各樣復(fù)雜的情況,我們只能以盡可能保護我們系統(tǒng)自己的方式,將重復(fù)下單可能性降到最小,并且即使發(fā)生,我們也不能出現(xiàn)短款,再結(jié)合運營手段進行差錯處理。
總結(jié)
以上是生活随笔為你收集整理的java怎么解决重复支付问题_支付系统设计中,如何防止重复支付?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: base64码 java_工具类:Jav
- 下一篇: centos7 hive mysql_C