馬蜂窩支付中心架構演進

来源:https://www.cnblogs.com/mfwtech/archive/2019/07/05/11138011.html
-Advertisement-
Play Games

為了更好地支持交易業務的快速發展,馬蜂窩支付中心從最初只支持基礎支付和退款的「刀耕火種」階段,經歷了架構調整的「刮骨療傷」階段,完成了到實現綜合產品平臺形態的「沉澱蓄力」階段的演進。 目前,馬蜂窩支付中心集成了包括基礎訂單、收銀台、路由管理、支付通道、清算核對、報表統計等多種能力,為馬蜂窩度假(平臺 ...


為了更好地支持交易業務的快速發展,馬蜂窩支付中心從最初只支持基礎支付和退款的「刀耕火種」階段,經歷了架構調整的「刮骨療傷」階段,完成了到實現綜合產品平臺形態的「沉澱蓄力」階段的演進。

目前,馬蜂窩支付中心集成了包括基礎訂單、收銀台、路由管理、支付通道、清算核對、報表統計等多種能力,為馬蜂窩度假(平臺、定製)、交通(機票、火車票、用車)、酒店(開放平臺、代理商)等近 20 條業務線提供服務。本文將圍繞支付中心整體演變過程中不同階段的核心部分進行簡要介紹。

一、支付中心 1.0

初期為快速響應業務的支付、退款以及一些基礎需求,支付中心主要負責接入支付通道(支付寶、微信、連連等),由各業務線分別實現收銀台,然後調用支付中心進行支付。業務系統、支付中心和第三方通道的交互流程圖如下:

各系統交互流程為:

  1. 業務線將訂單信息封裝後請求到支付中心
  2. 支付中心對訂單信息簡要處理後增加支付信息請求到第三方支付通道
  3. 第三方支付通道將支付結果非同步回調到支付中心
  4. 支付中心將第三方響應的數據簡易處理後同步通知到各業務系統
  5. 業務系統進行邏輯處理、用戶通知及頁面跳轉等

業務發展初期,業務量較小,交易場景也比較單一,這樣的設計可以快速響應業務需求,實現功能。但當業務複雜性不斷提高,接入的業務也越來越多時,該架構就顯得力不從心了。各業務線需要重覆開發一些功能,並且支付中心不具備整體管控能力,開發維護成本越來越大。主要的問題包括:

  • 維護成本高:各業務線需單獨維護收銀台,調用支付系統完成支付,需分別保證冪等、安全等問題
  • 容災能力差:所有功能集中在一個大模塊里,某個功能出問題,直接影響全部
  • 結構不合理:架構單一,不能滿足複雜業務場景
  • 系統職責亂:收銀台維護了收款方式及部分業務路由,缺乏統一的管控

為了兼顧對快速發展中的業務的需求響應和系統的高可用性,保證線上服務的質量,我們快速進行了架構調整,開始了向支付中心 2.0 的演進。

二、支付中心 2.0

2.0 架構將各業務的公共交易、支付、財務等沉澱到支付中心,並主要解決了以下三個主要問題:

  • 建立基礎訂單、支付、財務統一體系,抽象和封裝公共處理邏輯,形成統一的基礎服務,降低業務的接入成本及重覆研發成本;
  • 構建安全、穩定、可擴展的系統,為業務的快速發展和創新需求提供基礎支撐,解決業務「快」和支付「穩」之間的矛盾;
  • 沉澱核心交易數據,同時為用戶、商家、財務提供大數據支撐。

2.1 核心能力

支付中心 2.0 是整個交易系統快速發展的重要時段。在此過程中,不僅要進行架構的升級,還要保證服務的穩定。

目前支付中心對業務提供的主要能力包括:

  • 平臺支付:用戶可以使用微信、支付寶等第三方平臺來完成支付
  • 快捷支付:用戶提供銀行卡信息,進行便捷支付
  • 協議支付:用戶完成授權後,可以在不打斷用戶體驗的場景下進行便捷支付
  • 信用支付:用戶可以選擇花唄等分期產品進行透支支付
  • 境外支付:用戶可以選擇境外支付通道完成境外產品的購買
  • 線下支付:用戶可以選擇 ToB 通道完成特定場景的支付

針對馬蜂窩業務的特點,目前支持的核心交易場景包括:

  • 支付和退款:適用於普通商品的購買及退款
  • 拆分支付:適用於限額或金額較大場景
  • 合單支付:適用於保險等分賬到不同收款賬號的場景

2.2 架構設計

演進過程中,首先是對相對獨立,同時作為統一體系基礎的網關進行模塊化。支付網關對外抽象出支付、退款、查詢這些標準請求,然後在網關基礎上逐步梳理各支付通道,並逐步抽取出基礎訂單模塊,解耦業務功能與支付功能,同時可支持複雜的業務場景。目前的系統功能整體架構如下:

如圖所示,從架構上主要分為三個層次:

  • **產品層:**組合核心層提供的支付能力,對終端用戶提供收銀台、對運營財務人員提供運營財務系統
  • **核心層:**支付中心核心模塊,包括基礎訂單、支付路由、支付通道等
  • **支撐層:**用來支撐整個系統的基礎設施,包括監控報警、日誌、消息隊列等

2.2.1 產品層

產品層主要包含消費者可見的收銀台、支付管理後臺和財務核算、對賬的財會系統。本文重點介紹收銀台的設計思路。

收銀台

收銀台包含 H5 收銀台和 PC 收銀台兩部分:

移動端:

PC端:

如上圖所示,收銀台主要由三部分組成:訂單基本信息(含訂單號及支付金額)、訂單詳情(含日期信息、商品信息及基礎信息)、支付方式(平臺支付、信用支付等)。

由於收銀台是整個支付中心面向用戶的唯一入口,用戶體驗及安全性至關重要。為同時支持業務個性化和用戶的一致性體驗,收銀台主要是通過定製化和配置化的方式實現。對業務同學來講接入也非常簡單,僅需通過訂單號跳轉至收銀台頁面,後續流程均由支付中心完成。

用戶下單後到達收銀台頁面,收銀台通過訂單所屬業務線、支付金額、是否合單等信息,展示可用的支付通道。同時風控系統會從商品、訂單、用戶行為等維度進行監控,屏蔽高風險的支付渠道。支付渠道出現故障時可在收銀台暫停展示。

(1)定製化

  • 為支持統一收銀臺下各業務線不同模式、不同展示的特性,使用工廠類繼承的模式實現各業務數據及展示樣式。
  • 收銀台主要屬性分為展示模塊和通道路由,其中重覆及預設功能的模塊由抽象類用模板的方式實現,子類使用預設方法或者重寫父類方法即可達到自定義的實現。
  • 收銀台展示實現類已經實現了一套預設的收銀台,其中包含大多數必須的組件(如倒計時,頭部定製,訂單詳情等)。
  • 一般情況下,各個業務線僅需簡單添加特定的實現類,即可生成一個清晰又豐富的頁面

(2)配置化

收銀台的配置化主要根據各業務的屬性(業務類型、品類等)對後續操作做一定的流程處理配置化,比如:

  • 基於後端路由對收銀台展示層做不同的處理,用戶看到的可支持的通道列表(微信、支付寶等),以及排序置頂打標記等
  • 滿足不同場景、不同業務在同一種支付方式下收款到不同的收款賬號
  • 根據場景不同,走不同的結算方式,以及結算渠道等

2.2.2 核心層

支付中心中的核心模塊,包括基礎訂單、支付路由、支付通道等。

基礎訂單

基礎訂單系統是連接交易業務線、支付中心和結算系統的橋梁,實現了業務和支付結算解耦。主要涵蓋了業務創建訂單、關單、支付、退款、回調通知等 API 模塊。基礎數據支持普通支付、合單支付、拆分支付、保險支付等多種場景的支付功能,各個系統的交互流程如下:

目前基礎訂單系統可支持如下兩種特殊場景:

(1)一訂單 VS 多商品

創建一個基礎訂單可以包含 N 個商品(商品信息包含商品名稱、商品 ID、單價、數量、折扣等,訂單信息包含用戶 UID、手機號、支付金額、訂單折扣等彙總基礎信息),N 個商品對應 M 個業務子訂單 (M≦N),所有業務子訂單的業務類型若一樣則為普通模式,否則為搭售模式;每個業務訂單對應一個對賬單元(支付成功後會將支付信息同步給對賬系統),一訂單 VS 多商品的創單模式基本支持目前所有場景,包括未來可能的購物車模式。

(2)一訂單 VS 多支付單

普通訂單用戶選擇支付寶、微信等渠道會生成一個支付單;當金額超過 5000 元時可以選擇拆分訂單金額支付,此時會生成多個支付單;如果下單勾選保險就會走第三方合單支付,會生成兩個支付單;同時拆分支付也會導致用戶部分支付或者超額支付,監控會針對異常支付情況進行自動退款;大金額訂單有 10% 以上的轉換率提升, 一訂單 VS 多支付單模型更好的支持了馬蜂窩的支付場景。

通道路由管理

通道路由主要包含兩方面,一個是業務側需要控制支付通道,一個是支付側需要選擇支付賬戶。

(1)支付賬戶管理

支付創建訂單和處理回調等流程中,需要根據業務類型、支付方式和支付通道確定支付賬號,早期版本這個對應關係是通過配置文件維護的。一個業務類型對應多個配置項,每新增一個業務需要增加多個配置,而且隨著更多支付通道的接入,新增業務需要配置的信息也越來越多,不易維護。

經過優化,把現有的配置對應關係放到資料庫中,數據表由業務類型、支付方式、支付通道唯一確定一個收款賬號,支付賬號的具體參數信息還是放在文件配置中。創建訂單時根據業務類型、支付方式、支付通道查詢收款賬號,把賬號信息記錄到支付訂單數據表,回調時直接從訂單表查詢支付賬號。

(2)支付通道管理

目前對接了支付寶、支付寶國際、微信、京東支付、applepay、連連支付、銀聯 2B 等第三方通道,每一個通道下有多個支付產品。第三方通道的介面形式差異很大,但是都提供下單、退款、查詢、支付通知、賬單下載等標準功能。支付中心對這些支付通道做了一次封裝,用一個抽象類作為基類,使用模版方法設計模式,在基類中定義了一個標準流程,具體的實現在通道各自的實現類中。客戶類只需要關心基類的公共方法,和具體通道無關。

2.2.3 支撐層

支撐層包含監控報警、日誌管理、加簽驗簽、配置管理、消息匯流排等模塊。其中日誌使用 ELK 進行收集管理,系統配置採用公司自研的分散式配置中心進行管理,消息匯流排也是使用公司二次封裝的 RabbitMQ 進行消息分發及消費。

由於支付系統對可用性有極高要求以及支付數據的敏感性,支付中心獨立實現了監控報警系統,下麵將詳細描述該監控報警系統的功能及設計思路。

監控系統

為保證監控的實時性及有效性,監控依賴的資源如資料庫必須和業務庫要進行隔離(避免雞蛋放在同一個籃子里)。支付監控系統涵蓋了 API 監控、 服務性能監控、資料庫監控等,能夠提供統一的報警、分析和故障排除能力。從異常數據採集到故障問題主動發現及穩定性趨勢分析,為支付體系優化提供數據支撐。

(1)監控後臺

後臺主要包含監控用戶管理以及監控項創建管理,用戶可以根據需求對應的監控項目,可配置的參數涵蓋 API 請求地址、請求方式、可用性、正確性、 響應時間等性能數據以及報警方式和策略;詳細配置如下圖:

介面監控可以針對固定 host IP 綁定以及設置超時時間,監控請求支持 GET、POST 兩種方式,POST 方式可以設置固定請求參數輔助,監控頻率支持分鐘、秒兩種級別配置;響應數據模塊可以校驗 HTTP code 是否異常,配置響應數據類型,比較檢測返回 key 值,針對 DB 監控還可以設置 DB 查詢超時時間;報警模塊目前支持簡訊和郵件兩種方式,可以設置最小、最大報警閾值,超過最大閾值每隔最大報警數會觸發一次報警,規避了故障期間簡訊轟炸問題。

(2)監控核心

為了實現最快監控頻率 10 秒,同時可以支持成千上萬的監控項並行運行,支付監控採用了多進程管理的方式。父進程創建指定數量的子進程,每個子進程完成固定數量的監控任務退出任務,此時父進程實時監控子進程狀態並創建新的子進程執行任務;父進程還可以接受外部信號完成服務重啟以及停止,流程如下:

(3)監控報警

執行監控項會根據監控配置進行介面請求以及返回數據分析處理,然後通過 Redis 計數方式按報警策略進行報警通知。日常監控簡訊示例:

2.3 實踐經驗

(1)數據一致性

上文提到,我們採用模塊化的方式來解耦業務功能與支付功能。在這個過程中,每引入一個模塊就會涉及到系統交互問題,因此最核心的便是數據一致性問題。針對數據一致性問題需要引入事務,實時、延遲校驗以及補償機制保證數據的最終一致性。從架構看是很清晰的,但是對於整個改造過程是艱難的,猶如給飛行的飛機更換髮動機,所以我們也把這個過程形容為一個刮骨療傷的階段。

(2)穩定性

支付服務都是由第三方支付通道提供的,支付通道存在不穩定性。比如用戶用支付寶支付了一筆訂單,由於各種原因,支付中心沒有收到支付成功的通知,用戶又用微信再次付款,導致重覆支付。

為瞭解決這個問題,支付中心採用定時掃描的策略,主動發現重覆支付單並自動執行退款,不需要人工參與。退款流程中,退款單需要經過申請、審核、調用退款介面等流程,在調介面環節,可能會發生失敗。調用失敗的退款單,會根據退避演算法發起重試,逐漸加大重試間隔,直到次數超過限制。失敗單數量超過閾值、或者有訂單處於失敗時間超過閾值時會觸發報警。自動處理不了的退款單可以人工檢測,或線下退款。

三、總結 & 展望

目前,馬蜂窩支付中心已經具備支持多業務、多場景、多支付方式的能力,但想要實現一個真正意義上「百花齊放」的平臺,還有很多地方需要改進和完善。

即將到來的支付中心 3.0 將以微服務的思想把單體應用按照業務進行解耦,會逐漸從一個高耦合的單一系統演變為眾多子系統組成的高併發、高可用、支持更多交易支付場景的分散式系統。微服務化拆分後,在系統結構上將更加清晰,但對於整體系統的開發管理和維護也將帶來更大的挑戰。

伴隨馬蜂窩「內容+交易」的戰略升級,支付中心也會探索更多的支付方式和能力,持續為各業務線賦能。

本文作者:馬蜂窩電商支付結算團隊。

(馬蜂窩技術原創內容,轉載務必註明出處保存文末二維碼圖片,謝謝配合。)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 寫了個評分組件,效果如下 組件Rate.js 組件樣式 Rate.less 背景圖 調用 <Rate number={10} def={5} /> number:為評分總數,預設為5 def:為評分數,預設為0 ...
  • 1. vue項目打包採坑 1.1. vue運行報錯error:Cannot assign to read only property 'exports' of object ' ' 這個錯誤我是在打包完部署到nginx上才會報的,在本地環境可以正常運行,真坑; 網上的資料說的報錯原因是export和 ...
  • 官網地址:http://www.bacubacu.com/colresizable/ 這裡值得註意的是,如果是動態加入的列,則需要先清理調用插件生成的class,id和div之後再重新調用才會有作用。 至於為何動態載入的列沒有效果呢。首先,我想到了可能是方法載入在了動態生成列之前,所以我便手動在生成 ...
  • 雙大括弧會將數據解釋為普通文本,而非 HTML 代碼。為了輸出真正的 HTML,你需要使用 v-html 指令,例如: 渲染結果為: <p>{{message}}</p>里的message被解釋為了普通文本,而不是輸出真正的 HTML,而<p v-html="message"></p>輸出了真正的h ...
  • 這12個問題,基本上就是HTML和CSS基礎中的重點難點了,也是必須要弄清楚的基本問題,其中定位的絕對定位和相對定位到底相對什麼定位?這個還是容易被忽視的,浮動也是一個大坑,有很多細節。 這12個知識點是我個人認為的,下麵我們就來看看這12個知識點。 1.怎麼讓一個不定寬高的 DIV,垂直水平居中? ...
  • SpringCloud系列教程 | 第六篇:Spring Cloud Config Github配置中心 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如無特殊說明,本系列教程全採用以上版本 隨著分散式項目越來越大,勤勞的程式猿們會開始面臨 ...
  • extern可置於變數或者函數前,以表示變數或者函數的定義在別的文件中,提示編譯器遇到此變數和函數時在其他模塊中尋找其定義。 另外,extern也可用來進行鏈接指定。用法分析: 在一個變數前加extern 比如:extern unsigned int Test;編譯器編譯的時候,會把Test當成是外 ...
  • 工廠模式的使用場景、讓自己的代碼解耦更優雅。包含簡單工廠、工廠方法、抽象工廠。一文就夠了 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...