通知系統(回調)設計

一, 背景的提出

        任何有接入第三方支付(如微信支付,支付寶等)經驗的商戶IT人員,基本都瞭解在調用第三方支付的統一下單接口的時候,需要傳遞一個後臺回調的參數,如notify_url,要求該參數是一個外網的可訪問地址,用於後臺接收第三方支付的支付結果回調,一般第三方支付會通過兩個方向通知商戶用戶在他們系統的支付情況,一個是及時的前端回調,還有一個異步的後臺回調,兩者的機制和目的都不同,其中前端回調是用於告知和處理前端的業務跳轉,JSAPI回調等前端用戶交互方面的體驗;而後臺的異步回調是更加安全的可靠的接收第三方支付結構的方式,基於安全的原因,商戶需要在後臺回調處理邏輯裏面對第三方支付的灰度進行簽名驗證,同時,爲了防止簽名被破解導致的風險,兜底處理邏輯上,建議在驗證完成後,還需要調用第三方支付的查單接口進行反查驗證,從而確保支付回調結果是一個真實的結果。

         前面是從商戶接入第三方支付的角度對需要做的事情和需要關注的點進行闡述,從第三方支付架構設計來看,商戶回調通知系統是一個必備的關鍵系統,作爲第三方支付,它的職責是負責資金流的扭轉,確保安全和可靠,及時的把資金從用戶的賬戶扣除和轉移到商戶在第三方支付的結算賬戶的職責,這是核心交易系統需要做的事情,在完成這些事情後,還需要及時和安全的把支付結果通知給商戶的後臺系統,以告知商戶進行訂單狀態的扭轉和發貨處理等,商戶通知系統是連接第三方核心支付系統和外部商戶的橋樑。我們很多的業務模式,就是通過第三方支付系統和商戶業務系統進行合作,有序有步驟,安全的實現資金流,信息流和物流等統一協調和扭轉,從而保障了整個互聯網交易生態的有序運轉。

         因此,對第三方支付來說,商戶回調通知系統是一個非常重要的必備系統,通知的安全性,健壯性和及時性非常重要。

1, 安全性:通知系統必須確保安全的把支付結果通知給商戶,防止中間被非法篡改和劫持,因此,在設計上,必須要求第三方支付系統和商戶後臺系統按約定的API KEY進行簽名和驗籤;通知系統需要對通知的參數進行全簽名,而商戶後臺系統必須進行驗簽名。

2, 健壯性:有人說,核心支付系統的健壯性非常重要,商戶通知系統健壯性要求沒那麼高,其實,在移動支付中,用戶的體驗要求越來越高,如果核心支付系統雖然很健壯,但如果商戶通知系統關鍵時候掉鏈子,那麼及時支付成功,也無法安全和及時的把支付結果送到商戶後臺系統,因此,商戶後臺系統就無法進行訂單狀態的扭轉和後續發貨等處理,用戶就無法及時的購物,有人說,如果商戶通知系統掛了,商戶後臺可以主動去第三方支付系統查詢,理論上沒錯,只是在實際實現中,很多商戶的查單補單可能是沒有實現或者是T+1,或者是延遲較久的時間才進行調度,因此及時性上是打了折扣,體驗就上不去。

3, 及時性:第三方支付商戶通知系統,既然選擇是主動通知模式,那麼及時性就是其中一個關鍵的考慮因素,支付成功後能否及時的通知到商戶,對商戶的發貨和訂單扭轉至關重要。

  

二,商戶回調通知系統

 

支付的操作步驟如下:

1,  商戶通過後臺調用第三方支付的接入層進行下單,第三方支付返回預下單id給到商戶後臺系統,商戶後臺系統在前端調起支付收銀臺,用戶輸入授權信息後,調用核心支付系統。

2,   核心支付系統根據用戶選擇的支付方式(支付賬戶或者銀行卡)選擇不同的支付路徑。

3,   如果是選擇支付賬戶支付,則調用支付賬戶系統對用戶的賬戶進行扣款。

4,   如果是銀行卡支付,則調用銀行前置系統,通過專線連接接入銀行的快捷支付前置進行扣款;

5,   無論是3或者4,成功完成用戶扣款後,對商戶結算賬戶進行入賬操作。

6,   核心支付系統根據商戶下單傳遞的notify_url地址,調用商戶通知系統;

7,   商戶通知系統對支付結果進行簽名,調用notify_url地址進行回調通知商戶,若商戶返回失敗或者超時,則商戶通知系統會按照一定的時間節奏進行後續補償通知。

 

在具體進行如何通知商戶的策略上,有兩種基本的策略,分別是悲觀和樂觀策略,兩者的實現方式和試用的場景不同。

 

三,悲觀的調度策略

          我們知道,在覈心支付系統第一次支付成功返回的時候,會同步通過前端和後臺進行商戶通知,如果這個時候商戶的後臺通知,商戶後臺返回可能三種情況:成功,失敗或者超時,針對這三種情況,商戶通知系統的補償系統的後續處理步驟是怎樣的呢?

         在悲觀的調度策略中,商戶補償系統認爲前端的商戶通知失敗的情況下,有義務進行盡最大能力進行補償通知,千方百計的進行補救通知,寧願多通知一次商戶也不願意放棄,類似TCP協議的失敗重傳機制,是一種可靠的通知模型。

          那麼爲了實現這種機制,前端在同步通知商戶後臺系統成功後,會往MQ寫入成功通知的消息,而商戶補償系統會在覈心繫統支付成功後,自動啓動定時補償通知機制,直到收到前端的MQ通知已經成功了才放棄補償或者自身補償通知得到商戶的成功響應。

仔細分析一下上述的過程,前端通知商戶後臺系統:

(1)如果這個時候通知失敗或者超時,則不會往MQ寫成功消息告訴補償系統,那麼補償系統肯定收不到該消息,因此,補償系統在間隔一定的時間如10s後自動發起補償通知;

(2)如果這個時候通知成功,則往MQ寫入成功消息,補償系統在自己的補償間隔時間內收到了該成功MQ消息,則放棄補償操作。

(3)如果這個時候通知成功,但往MQ寫成功消息失敗,MQ堵塞,MQ消息丟失等導致補償服務無法在自己的間隔時間內收到了該成功MQ,則會自動進行補償通知。

   綜上分享,悲觀的回調策略不信任前端,如果前端無法在指定的時間內告訴補償服務已經成功通知,無法什麼原因,補償服務一定會按照自己的調度節奏重新發起通知。

   這種策略對商戶的後臺系統來說,有可能出現前面已經成功收到過第三方支付的成功支付回調並且返回成功了,但後續還收到第二次甚至第三次的回調通知,它的優點就是:商戶系統可以得到多次的補償通知,在比較及時的情況下實現訂單的狀態扭轉,不足是如果支付量很大,在一定的極端情況下,商戶回調處理服務可能收到大量的重複請求,給系統帶來壓力,浪費了計算資源,甚至處理不好導致雪崩。

 

四,樂觀的調度策略

         前面分享了悲觀的調度策略,那麼如果對應支付頻度非常高的場景下,如春節紅包,在每秒達到幾萬甚至幾十萬的支付峯值下,如果出現MQ隊列阻塞(高峯情況下,發生的可能性極大),補償服務的自動補償功能,不但不能提升支付的穩定性,反而成爲最後壓垮商戶後臺系統的罪魁惡首,因爲,這個時候,商戶的接受支付通知系統的支持的併發請求數需要至少double了一倍,對計算資源和成本是一個極大的挑戰;另外一個方面,悲觀的調度策略,每次通知成功後都會往MQ寫一個消息,由於成功通知的概率是更大的,正常的是90%以上,意味着對MQ資源無論是存儲量和MQ的消費者處理性能均有更高的要求,一旦出現堵塞,和處理不及時,那麼補償服務就會double後臺通知請求,商戶系統如果處理不當,雪崩就馬上出現。

         那麼,針對這種場景,有沒更優的策略呢?筆記在實際的項目實戰中,對類似紅包這種高併發的支付商戶通知模型,悲觀的調度策略存在較多的風險,因此,提出一種樂觀的調度策略,在樂觀的調度策略中,我們樂觀的認爲前端首次通知商戶的成功率是比較高的,對首次通知已經成功的,補償服務就無需進行再次補償,那麼,爲了實現這種模型:

         前端首次進行商戶通知後,若商戶返回成功,則無需做任何事情,如果商戶返回失敗或者超時,則往MQ隊列寫入一個通知失敗的消息(注意:悲觀的策略是每次成功都寫MQ消息,這裏是失敗才寫消息),由於前端首次通知成功的概率在99%以上(實踐的真實數據已經驗證),那麼只針對失敗才寫MQ消息,意味着對MQ的存儲量和請求量相比悲觀策略降低了99倍,這個時候MQ發生阻塞和雪崩的可能性會大大的降低,而補償服務不會定時進行補償,只有收到了MQ的通知失敗消息,才進行補償操作。

         非常明顯,該策略對商戶系統來說,成功通知最多是一次,在高併發情況下,商戶回調系統不會出現double的情況,但該策略,如果出現了MQ消息丟失,由於補償服務這個時候不會自動進行補償,商戶是無法收到主動的回調通知的,對這種情況,商戶可以選擇主動反查訂單進行補償,由於量比較少,因此,對及時性的影響沒那麼大,當然,這裏可以進行優化成由前端用戶的行爲觸發查單行爲,使得結果的通知符合用戶的預期,從而提升了體驗。

 

五,總結

         當然,以上兩種策略沒有好壞,只有根據不同的場景:併發數,可靠性,機器資源,及時性等要求選擇不同的策略,我們認爲在商業支付中,悲觀的回調策略可能更合適,一個是併發數突發性較少,另外對支付的可靠性和及時性也有更多的及時補償;而對類紅包的社交支付等突發性很高的情況,樂觀的回調策略可能是更好的選擇。
————————————————
版權聲明:本文爲CSDN博主「tenfyguo」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/tenfyguo/article/details/73441592

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