小結:前端
一、安全
前端回調是用於告知和處理前端的業務跳轉/前端用戶交互方面的體驗微信
後臺的異步回調是更加安全的可靠的接收第三方支付結構的方式,基於安全的緣由,
1商戶須要在後臺回調處理邏輯裏面對第三方支付的灰度進行簽名驗證
2在驗證完成後,還須要調用第三方支付的查單接口進行反查驗證架構
二、
在實際實現中,不少商戶的查單補單多是沒有實現或者是T+1,或者是延遲較久的時間才進行調度,所以及時性上是打了折扣,體驗就上不去。併發
第三方支付架構設計之:商戶回調通知系統的悲觀和樂觀策略 - tenfyguo的技術專欄 - CSDN博客 https://blog.csdn.net/tenfyguo/article/details/73441592異步
一, 背景的提出高併發
任何有接入第三方支付(如微信支付,支付寶等)經驗的商戶IT人員,基本都瞭解在調用第三方支付的統一下單接口的時候,須要傳遞一個後臺回調的參數,如notify_url,要求該參數是一個外網的可訪問地址,用於後臺接收第三方支付的支付結果回調,通常第三方支付會經過兩個方向通知商戶用戶在他們系統的支付狀況,一個是及時的前端回調,還有一個異步的後臺回調,二者的機制和目的都不一樣,其中前端回調是用於告知和處理前端的業務跳轉,JSAPI回調等前端用戶交互方面的體驗;然後臺的異步回調是更加安全的可靠的接收第三方支付結構的方式,基於安全的緣由,商戶須要在後臺回調處理邏輯裏面對第三方支付的灰度進行簽名驗證,同時,爲了防止簽名被破解致使的風險,兜底處理邏輯上,建議在驗證完成後,還須要調用第三方支付的查單接口進行反查驗證,從而確保支付回調結果是一個真實的結果。性能
前面是從商戶接入第三方支付的角度對須要作的事情和須要關注的點進行闡述,從第三方支付架構設計來看,商戶回調通知系統是一個必備的關鍵系統,做爲第三方支付,它的職責是負責資金流的扭轉,確保安全和可靠,及時的把資金從用戶的帳戶扣除和轉移到商戶在第三方支付的結算帳戶的職責,這是核心交易系統須要作的事情,在完成這些事情後,還須要及時和安全的把支付結果通知給商戶的後臺系統,以告知商戶進行訂單狀態的扭轉和發貨處理等,商戶通知系統是鏈接第三方核心支付系統和外部商戶的橋樑。咱們不少的業務模式,就是經過第三方支付系統和商戶業務系統進行合做,有序有步驟,安全的實現資金流,信息流和物流等統一協調和扭轉,從而保障了整個互聯網交易生態的有序運轉。微信支付
所以,對第三方支付來講,商戶回調通知系統是一個很是重要的必備系統,通知的安全性,健壯性和及時性很是重要。優化
1, 安全性:通知系統必須確保安全的把支付結果通知給商戶,防止中間被非法篡改和劫持,所以,在設計上,必需要求第三方支付系統和商戶後臺系統按約定的API KEY進行簽名和驗籤;通知系統須要對通知的參數進行全簽名,而商戶後臺系統必須進行驗簽名。
2, 健壯性:有人說,核心支付系統的健壯性很是重要,商戶通知系統健壯性要求沒那麼高,其實,在移動支付中,用戶的體驗要求愈來愈高,若是核心支付系統雖然很健壯,但若是商戶通知系統關鍵時候掉鏈子,那麼及時支付成功,也沒法安全和及時的把支付結果送到商戶後臺系統,所以,商戶後臺系統就沒法進行訂單狀態的扭轉和後續發貨等處理,用戶就沒法及時的購物,有人說,若是商戶通知系統掛了,商戶後臺能夠主動去第三方支付系統查詢,理論上沒錯,只是在實際實現中,不少商戶的查單補單多是沒有實現或者是T+1,或者是延遲較久的時間才進行調度,所以及時性上是打了折扣,體驗就上不去。
3, 及時性:第三方支付商戶通知系統,既然選擇是主動通知模式,那麼及時性就是其中一個關鍵的考慮因素,支付成功後可否及時的通知到商戶,對商戶的發貨和訂單扭轉相當重要。
二,商戶回調通知系統
圖1-1
支付的操做步驟以下:
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消息丟失,因爲補償服務這個時候不會自動進行補償,商戶是沒法收到主動的回調通知的,對這種狀況,商戶能夠選擇主動反查訂單進行補償,因爲量比較少,所以,對及時性的影響沒那麼大,固然,這裏能夠進行優化成由前端用戶的行爲觸發查單行爲,使得結果的通知符合用戶的預期,從而提高了體驗。
五,總結
固然,以上兩種策略沒有好壞,只有根據不一樣的場景:併發數,可靠性,機器資源,及時性等要求選擇不一樣的策略,咱們認爲在商業支付中,悲觀的回調策略可能更合適,一個是併發數突發性較少,另外對支付的可靠性和及時性也有更多的及時補償;而對類紅包的社交支付等突發性很高的狀況,樂觀的回調策略多是更好的選擇。