鄭昀編纂 基於網路資料 建立於2015/9/9 最後更新於2015/10/16
輕點
提綱:交易中的異常處理
何謂沖正
重複支付
電商核心交易流程中,由於涉及的物件較多,如自家的訂單中心、資金帳戶中心、庫存中心、支付中心,第三方支付的介面,銀行,自家的支付閘道器等等,每個物件都可能處於不可知狀態,網路訊息的投遞也不能保證先後順序,還可能丟包,所以有大量的異常分支需要處理。
0x00,交易中的異常處理
1.1.何謂沖正
一筆交易在終端已經置為成功標誌,但是傳送到主機的帳務交易包沒有得到響應,即終端交易超時,所以不確定該筆交易是否在主機端也成功完成。為了確保使用者的利益,終端重新向主機傳送請求,請求取消該筆交易的流水,如果主機端已經交易成功,則回滾交易,否則不處理,然後將處理結果返回給終端。學術上這麼解釋也許夠了,但還是不夠嚴謹的,因為沖正交易不光要求對已有交易進行回滾,語義上他還要求應答系統對該交易流水進行冪等控制——沖正,就為系統認為可能交易失敗時採取的補救手法。
將該交易流水插入冪等表,即便後續該交易報文再抵達,也予以拒絕交易。
如果沒有上面我補充的這段,沖正交易的實現是有邏輯漏洞的。
雖然概率極低,但由於各鏈路節點處理資訊的效率不一致,所以也有可能出現沖正交易先抵達目標系統,正常交易晚抵達的情況。如果該目標系統的沖正交易並未作以上邏輯判斷,那就會引起使用者糾紛。
最後,我們來看看沖正交易的使用場景。
例如,你去商場購買了乙個包包,價值5萬元,刷信用卡消費。
pos機在傳送交易報文的時候……不幸掉單了,嗯,就是那麼不幸,pos機無論如何收不到來自於收單系統的回執單據。經過漫長的等待,pos機忍不住了,自動給收單系統發了一筆沖正交易……收單行回執,沖正交易處理成功,事件完畢。
這個時候,你會發現服務員又笑眯眯地找你,要你重新刷一下卡……
或許有同學會問,那萬一的沖正交易也掉單了呢……
是的,會有這種奇葩情況,通常系統會對沖正交易重發n次,n次後如果還沒應答就算了,概率太低了,等使用者來投訴吧——
很多時候人工保障比你動腦筋想異常中的異常如何系統自動處理來得反而高效和低成本。
或許還有同學會問,那pos機上的撤銷交易和衝正是什麼關係呢?
其實兩個介面的內部實現可以說是類似的,業務場景上,撤銷交易更偏向於由人工發起對原單據的撤銷,可以理解為業務行為;
沖正更類似於系統保障機制,可以不由業務人員感知到,僅此而已。
(出處1)
1.2.重複支付
1)支付介面判重
第三方支付在接收到支付請求後,根據與商家約定的判定重複支付的引數組合對支付請求進行校驗及判重,如果為重複訂單,則不繼續後續流程。
由於涉及每一次支付請求都需要查詢交易資料,影響系統效能;且由於不同商家的判重標準不盡相同,一般都需要對介面做定製,因此除非是大商戶,一般都不提供此功能。
而且此種方案,並不能杜絕重複支付的問題,例如:使用者開了兩個視窗,都已經跳轉到銀行網銀頁面上,此時侯第三方支付已經無法控制使用者支付行為了。
(鄭昀注:
1. 從電商平台的角度,我們傳給支付寶的
商戶唯一訂單號 out_trade_no,這是第三方支付判重的唯一依據。
2. 使用者可能會連續變更
支付成功通知 對應於使用者的同乙個訂單的哪一次支付行為,我們的 out_trade_no 引數裡會包含乙個序列號。
我2023年寫的《
電商課題:支付交易一般性準則》裡曾經給出過乙個例子:
例一:修改訂單,訂單應付金額或支付方式發生變化背景:訂單在沒有支付成功之前,顧客都是可以修改的。做了以下修改後,可能會引起訂單應付金額或支付方式發生變化:
而支付寶等第三方支付,對於乙個用商戶唯一訂單號標識的交易,禁止變更 total_fee(交易總金額)字段!)所以,我們的同乙個訂單,發起不同應付金額的支付請求時,必須更換 out_trade_no ,流程如下圖4.2所示:
圖4.2 訂單應付金額變化,out_trade_no 必須變化
2)重複支付+退款介面
如果重複支付的訂單尚未與第三方支付平台結算,則:
在使用者支付成功後,商戶系統是可以判斷是否為重複支付,商戶系統可以自動呼叫退款介面,對判定為重複支付的訂單發起退款請求(商戶平台訂單號+支付平台支付流水號)。
也可以由商戶運營人員在運營後台發起退款請求(本質上也是呼叫退款介面)。
(鄭昀注:電商平台的支付中心必須能夠判定重複支付,並自動發起原路退返。
舉個例子,
10點01分:訂單001,應付金額10元,使用者選擇支付寶發起支付,out_trade_no=xx_001_0001,使用者登入支付寶後產生了應付賬單,但未付款;
10點02分:訂單001,使用者修改購買份數,應付金額變更為5元,使用者選擇支付寶發起支付,out_trade_no=xx_001_0002;
10點03分:使用者把xx_001_0001和xx_001_0002都付款成功了;
10點03分10秒:xx_001_0001的支付成功通知到達。電商平台的支付中心標記該交易支付成功,但因該交易關閉而不再路由給訂單中心,訂單狀態不會發生變化。有專門的定時任務處理這種異常交易,t+n 天後如果使用者仍沒有處理,那麼系統會自動發起原路退返,退到使用者支付寶賬戶10元;
10點03分20秒:xx_002_0002的支付成功通知到達。電商平台標記訂單為已付款狀態,同時標記該訂單有重複支付,使用者如果登入到**,會收到站內訊息通知,個人中心頁面也有提示。
)3)批量代付退款
如果重複支付的訂單已經與第三方支付平台已經結算(第三方支付與銀行也完成對賬、結算),則:
另外在商戶端,為避免重複支付,在業務邏輯上也可以做一些處理,包括:
1、保證交易訂單號的唯一性。很多商戶系統開發能力有限,經常出現交易訂單號不唯一的情況。
2、在發起支付請求後,更改訂單狀態,避免使用者再次發起支付請求。(慎用,只不過在一些業務場合會也會採用此種方案)。
3、對因掉單等原因引起的訂單狀態未知的情況,先呼叫第三方支付介面的查詢介面確認訂單的支付狀態。
(出處2)
1,2014,知乎天順的專欄文章,
2,2015,知乎梁川的回答,
-eof-
電商交易背景知識合集第一季 (2015-09-08 17:42)
Java 基礎(第二季)
public class helloworld public class helloworld int num1 int num2 初始化塊 static public static void main string args 結果如下 通過靜態初始化塊為靜態變數num3賦值 通過初始化塊為變數nu...
X A B (第二季水)
description give you two numbers a and b,if a is equal to b,you should print yes or print no input each test case contains two numbers a and b.output ...
遷移填坑第二季
之前說到,配置了遷移環境碰到了各種坑,然後終於解決掉了,終於能夠nova live migration kobe compute5了。然後就開始批量生產遷移環境,然後。之前是只用了compute3和compute5,然後把compute6和compute7也配置好nfs和libvirt,然後嘗試把k...