解密轉轉收銀臺背後的路由系統
1 引言
在電商交易場景中,支付環節是整個用戶購物環節中的關鍵節點。用戶從搜索、推薦、瀏覽、比較、加購、下單,到最終的支付環節,每一步都經歷了層層漏斗的篩選。當用戶到達支付環節時,已經展現出強烈的購買意向,這時的流量價值已經遠超最初環節。支付環節的體驗直接關係到最終的成交轉化,因此收銀臺不僅要確保支付流程的順暢,更要保證支付的安全性和可靠性。隨着業務規模的不斷擴大,支付場景的日益複雜,如何構建一個高效、穩定、智能的支付路由系統,成爲了我們面臨的重要挑戰。
本文將深入解析轉轉收銀臺支付路由系統的設計與實現,從系統架構、規則引擎、異常處理等多個維度,分享我們在支付路由系統演進過程中的實踐經驗和技術心得。通過這篇文章,你將瞭解到:
-
轉轉收銀臺支付路由系統是如何從簡單的規則配置,演進到模塊構建模式路由
-
規則引擎如何支持靈活的業務配置,實現支付渠道的智能調度
-
系統如何通過完善的監控和自動化機制,保證支付服務的穩定性
無論你是支付領域的從業者,還是對系統架構感興趣的技術人,相信這篇文章都能給你帶來一些啓發和思考。讓我們一起走進轉轉收銀臺支付路由系統的技術世界。
2 背景知識介紹
2.1 名詞解釋
2.2 邏輯解釋
上面的名詞概念非常重要,此處着重介紹部分概念。
1:爲什麼需要終端和版本?
不同的終端版本支持的支付方式和產品不一樣,比如:假設某個支付方式需要集成某個 SDK,而這個 SDK 是從 x.x.x 之後的版本纔開始集成的,那麼低於這個版本的就不能透出這個支付方式。
2:展示渠道和支付機構概念是否衝突?
不衝突,有些展示渠道是抽象出來的,沒有實際的映射,比如分筆支付、組合支付。而有些情況是多個展示渠道對應一個支付機構,比如花唄和支付寶,都是屬於同一種支付機構。
3:爲什麼在商戶號之外設計支付渠道的概念?
支付渠道是商戶號更精細化控制的維度,假設在某間聯通道註冊了商戶號 B,同時 B 是支持微信(B1)和支付寶(B2)的,爲了分別精準控制 B1、B2 的可用狀態、分流比例、權重等因素,需要設計支付渠道的維度。
3 支付路由系統歷史演進
要真正理解一個系統,我們必須追溯它的發展歷程,瞭解它的來龍去脈。每一個決策、每一個設計,都是特定條件下的產物。它們或許不是最優的選擇,甚至可能不是最合適的方案,但每一個環節的設置都承載着當時的考量與權衡。這些決策背後,往往有着複雜的技術背景、業務需求、現實約束和歷史原因。系統演進每一步都是在前人的基礎上不斷積累和創新的結果。瞭解這個過程,不僅能夠幫助我們更好地理解系統的現狀,更能爲未來的優化和演進提供寶貴的參考,只有理解了 "爲什麼是這樣",才能更好地思考 "應該是什麼樣"。
階段 1:基礎配置模式
基礎配置模式是符合支付路由系統目標的最簡單實現方式,它採用簡單直接的配置規則,通過幾個核心條件就能完成支付渠道的路由選擇。這種模式就像是一個簡單的導航系統,只需要輸入目的地,就能給出明確的路線指引。
在這種模式下,系統主要通過業務場景和公司主體等基礎維度,精準匹配到對應的收單商戶號。比如,當用戶選擇微信支付時,系統會根據當前業務場景(如換新等)和公司主體信息,直接返回預設的商戶號配置。
基礎配置模式特別適合業務規則相對固定、支付需求穩定的場景。它的優勢在於:
-
配置簡單直觀,易於維護
-
執行效率高,響應速度快
-
代碼結構清晰,易於理解
雖然隨着業務的發展,系統已經演進到了更復雜的階段,但基礎配置模式並未被完全淘汰。恰恰相反,由於其簡單高效的特點,在一些業務場景簡單、對響應速度要求高的場景中,這種模式仍然有一席之地。這就像是在現代交通工具中,自行車依然因其簡單便捷而不可或缺一樣。
這種模式的存在,體現了系統設計中的一個重要原則:不是所有場景都需要最複雜的解決方案,有時候簡單直接的方案反而是最優的選擇。
階段 2:規則引擎模式
規則引擎模式引入了業務匹配規則和規則引擎的概念。系統通過買家、賣家、業務線等維度定義業務場景,將每個商戶號的每種支付產品作爲獨立的支付方式,並定義了不同終端、不同版本下的可用支付方式列表。
系統處理流程示意如下:
這種模式特別適合業務線衆多、支付方式多樣、業務規則相對穩定的場景。然而,隨着業務發展,其侷限性也逐漸顯現:
1:配置維護成本高:每次增加商戶號或業務場景,需要修改大量配置數據,耗時較長。
2:商戶號使用受限:不支持同一業務場景下同一種支付方式使用多個商戶號,限制了業務擴展的靈活性。
3:維度擴展困難:業務場景維度擴充不夠便捷,難以快速響應新的業務需求。
階段 3:模塊構建模式
模塊構建模式引入了 Aviator 表達式引擎,使得規則維度的擴展更爲便捷。系統對原有的終端環境和版本進行了結構拆解,使業務場景不再與具體的環境和支付產品深度綁定。
同時,系統對文案、排序等配置項進行了解耦,不再要求每個支付方式都綁定固定文案,這大大方便了活動文案的配置和複用。此外,系統還豐富了對同一場景多商戶號的支持,並引入了異常渠道自動上下線機制,顯著提高了服務的穩定性。
這種模式的出現,使支付路由系統具備了更強的靈活性和穩定性。
4 路由系統解密
4.1 整體架構
支付系統作爲轉轉平臺的核心基礎設施,不僅需要支撐內部運營人員的路由管理需求,更要承擔全平臺用戶的支付請求處理。系統需要適配多樣化的環境(包括各版本 APP、小程序等)和不同用戶角色(如普通買家、普通賣家、商家、回收個人等)。
在架構設計上,支付系統直接承接 C 端流量,同時與各業務部門緊密協作。基礎能力和底層服務則由公司架構團隊提供支持。
整體架構如下:
獲取可用支付方式的邏輯示意圖如下:
其中提交收銀臺在支付路由的邏輯部分和獲取可用支付方式邏輯類似,不再贅述。
4.2 路由模塊構成
思考心路:
在規則引擎模式中有一些很明顯的痛點
1:業務場景和終端環境以及版本高度綁定
這個特點在後續版本升級繼承不同渠道的時候就會存在一個業務線,在同一個 APP 要配置 N 套支付方式,繼承微信 SDK 版本的一套;繼承微信 SDK 且支付寶 SDK 的一套;繼承微信 SDK 且支付寶 SDK 且京東 SDK 的一套....
2:業務場景和支付配置高度綁定
原來的配置方式上,直接決定了某個業務場景在具體終端環境和版本下的支付渠道,是指明瞭支付產品、支付圖標、支付標題、支付文案等配置。這一設計導致每新增一個支付渠道都需要把對應的圖標、文案、標題等信息重複配置一遍。
基於上述痛點,我們在設計新的結構的時候,把整個路由系統進行了模塊拆分,使得模塊之間不再深度綁定,這樣既可以輕鬆擴展,也方便模塊的複用,同時在管理方面也不需要關注太多的因素。
支付路由內部可以劃分爲如下模塊
1:業務場景管理
核心模塊之一,根據業務線和收款賬戶定義業務場景,後續引導路由是基於業務場景再次進行匹配。可以抽象的理解爲定製好的一個規則組。
業務場景目前後臺限制了只配置業務線和收款賬戶,但是系統本身是支持更多維度的。
2:商戶號管理
維護系統中的商戶號信息,包括商戶號、收單機構、是否支持降級、登錄賬戶、支持的支付方式和支付產品、手續費信息和對賬信息等。
3:支付渠道管理
基於商戶號的擴展,配置對應的密鑰信息、渠道參數。一個商戶號可以對應多個支付渠道。系統異常上下線和分流比例都是基於支付渠道配置的。
4:路由策略管理
路由策略分爲兩種
分流:配置同一種支付方式下不同支付渠道的比值關係。
不可用:限制某支付渠道不可用。
5:基礎因素管理
配置不同環境本身支持的支付方式上限
6:可用支付方式
可用支付方式限制了業務場景使用的支付方式上限,和基礎因素共同約束了用戶的可用支付方式。
整體模塊一覽如下圖:
4.3 表達式引擎
業務場景是支付路由的核心概念,可用支付方式、分流比例、顯示文案和排序規則都是在業務場景的基礎上配置的。因此,如何定義業務場景至關重要。
儘管我們可以窮舉所有能用到的維度,但如果將來出現新的維度需要劃分,我們的設計如何支持後續的擴展(比如,根據所在城市顯示不同的支付方式)?基於上述考量,我們將業務場景設計成腳本語言表達式。這種腳本語言表達式不僅應用於業務場景模塊,還貫穿整個支付路由系統。
下面我們使用具體的例子來理解表達式引擎,同時對比一下和硬編碼實現的特點。
假設業務的訴求是,業務線等於 1001 或者 1002,並且終端環境等於找靚機安卓,並且版本在 3.1.2 和 6.3.8 之間,並且支付金額小於 6 萬,那麼可以使用的支付方式爲:微信、支付寶、京東。
使用硬編碼實現:
if("業務線樹".contains("1001")||"業務線樹".contains("1002")){
if("終端環境".equals("找靚機安卓")){
if("版本判斷"("版本","3.1.2","6.3.8")){//版本判斷爲自定義的函數
if("金額"<6萬){
return "微信、支付寶、京東";
}
}
}
}
可以預見到,如果使用硬編碼實現,當面對規則變動和規則及維度變多的時候,將面對災難級的現場。
使用表達式引擎的實現:
//加載自定義函數
AviatorEvaluator.addFunction(new BusinessFunction());
AviatorEvaluator.addFunction(new VersionFunction());
//當前請求的變量
Map<String, Object> env = new HashMap<>();
env.put("fl_business_line", [1001,10011000]);
env.put("f_t", "找靚機安卓");
env.put("f_v", "5.7.2");
env.put("f_m", "4000.00");
//當前規則的表達式展開
String expression="func_business(fl_business_line,seq.set('1001','1002'))&&include(seq.set('找靚機安卓'),f_t)&&func_version(f_v,'3.1.2','6.3.8')&&f_m<60000";
boolean match=AviatorEvaluator.getInstance().execute(expression, env, true);
if(match){
return"微信、支付寶、京東";
}
通過表達式引擎的示例代碼,我們看到,當業務需要新增維度的時候,比如增加一個條件: 城市等於北京,注意:城市可以添加多個
因爲等值判斷和集合判斷是表達式本身就支持的,不需要自定義函數。所以改動如下
//新增維度值
env.put("f_c", "北京");
//擴充表達式
String expression="func_business(fl_business_line,seq.set('1001','1002'))&&include(seq.set('找靚機安卓'),f_t)&&func_version(f_v,'3.1.2','6.3.8')&&f_m<60000";
expression+="&&include(seq.set('北京'),f_c)";
通過這種方式,系統能夠靈活應對未來的變化和擴展需求。
表達式引擎邏輯如下:
在技術選型時,我們調研對比了 Aviator、Groovy、Drools 等方式。
最後我們選擇 Aviator 作爲表達式引擎,有如下原因,其輕量、依賴少,且高性能,所支持的運算操作符滿足我們的業務場景需求。
同時支付系統在設計上沒有與 Aviator 腳本深度綁定,而是預留了一個可以擴展的輸入輸出接口。
我們可以選擇 Aviator、Groovy、Drools、easy-rule、也可以自己基於 java 代碼實現一套數據匹配的邏輯。
這種可拔插的設計預留使我們系統在後續的發展中不會被某一種技術所鎖定。
附上部分數據
4.4 異常檢測、自動下線
雖然渠道異常是小概率事件,但隨着接入渠道的增多,異常發生的概率也會呈幾何級數增長。當系統檢測到某個渠道異常時,可以通過技術手段來確保用戶體驗不會顯著下降。
以下舉兩個例子來說明:
單一收單機構:假設京東支付方式背後只有京東一個收單機構,當京東收單機構異常時,可以將京東支付隱藏、置灰或增加風險提示,引導用戶使用其他支付方式。
多收單機構:假設支付寶支付方式背後有支付寶和易寶兩個收單機構,當易寶機構服務異常時,可以在支付時自動路由到支付寶的收單機構,用戶感知不到異常的發生。
異常檢測自動下線和自動恢復整體架構如下:
異常檢測自動下線的邏輯如下:
通過異常檢查、異常渠道自動下線的方式,系統能夠在渠道異常時保持服務的穩定性和用戶體驗。
4.5 自動恢復
自動恢復的邏輯比自動下線簡單,但需要考慮一種場景:爲了減少短暫恢復再陷入異常情況對用戶的影響,恢復過程中若有其他可用渠道,那麼恢復渠道應採用逐步放量恢復的方法。
邏輯流程圖如下:
5 總結與展望
5.1 系統演進總結
隨着業務的發展,轉轉收銀臺支付路由系統也一直在持續演進,在基礎配置模式階段,系統通過簡單的配置規則實現了基本的支付路由功能,爲後續發展奠定了基礎。規則引擎模式的引入,使系統具備了更強大的場景適配能力,能夠更好地滿足多樣化的業務需求。而模塊構建模式的出現,則標誌着系統在靈活性和可擴展性方面達到了新的高度。
多渠道適配模式的引入,爲支付渠道費用的優化提供了更多可能性,而渠道異常自動上下線能力的實現,則有效降低了第三方渠道波動對用戶體驗的影響,顯著提升了系統的穩定性和可靠性。
5.2 未來展望
-
體驗優化
基於渠道支付成功率和響應時間動態調整渠道權重,保障用戶體驗
滿足用戶個性化定製收銀臺需求
提升內部產研團隊使用體驗 -
AI 助力
探索 AI 在路由系統的應用
5.3 結語
物有本末,事有終始。知所先後,則近道矣。
至此,整個收銀臺路由系統中核心部分已經介紹完畢,文中所列數據、舉例都非真實數據,是僅供學習交流的示例數據,可能缺失了真實樣例的更多細節,不過整體結構和邏輯是完整的。
關於作者
張一鳴 轉轉支付後端研發
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/ALlRJFoOZw-3uekp8trIFA