對帳系統做爲支付系統中的基石系統,處於整個支付環節中的最後一層,主要用來保證我方支付數據與第三方支付渠道或銀行的數據一致性。數據庫
在沒有對帳系統以前,財務在第二日手工覈對前一日的應收與實收。假若不一致,這就須要一一覈對數據,找出不一致的數據。對帳系統出現以後,就可減小以這種繁瑣手工操做,財務只須要天天關注系統的對帳記錄,釋放了生產力。微信
本文主要結合實際的項目經驗,聊聊對帳系統的設計方案。分佈式
對帳系統設計主要分爲如下四個模塊:post
模塊調用順序層次圖以下。測試
下面先來介紹渠道數據處理模塊。優化
這個模塊主要負責渠道對帳文件的下載,解析,以及數據落庫。網站
目前市面上第三方支付渠道對帳文件下載方式主要分爲如下幾類:設計
除了下載方式,對帳文件的格式也會存在一些區別。好比支付寶對帳文件格式爲 csv,而微信的對帳文件格式爲 txt,另外有些渠道爲 xml,xls。code
第三方渠道對帳文件裏面字段數量以及字段名稱也存在不一樣。xml
通常這一層每接入一個渠道須要專門根據這個渠道特性開發。這一層能夠抽象化接口,對外暴露下載與解析接口。每次接入渠道,實現該接口相應方法便可。
這一層開發難度不大,只要根據對帳文件格式相應解析文件便可。通常須要提取對帳文件裏面信息以下:
商戶號 商戶訂單號 渠道流水號 交易日期 交易金額 手續費 退款原訂單號
下面說一下開發這一層須要注意的一些細節。
一、同一渠道若申請了多個商戶號。這種狀況下,每一個商戶號若前一日都存在交易,第三方渠道會爲每一個商戶號都會產生一份對帳文件。因此這裏系統設計時候須要考慮到多份對帳文件處理的狀況。
二、對帳文件須要考慮重複下載的狀況。通常狀況下,渠道的對帳文件一旦生成,就不會改變。可是第三方渠道也可能發生異常,致使我方收到對帳文件數據不完整。這種狀況下,須要有機制從新下載解析入庫。
三、每一個第三方渠道下載文件時間都不同。
講完對帳文件處理模塊,咱們來看數據處理模塊。
這個模塊主要用來提取我方前一日全部支付成功的流水數據以及上一模塊入庫的前一日對帳單的流水數據。爲了減小數據庫的壓力,提取的數據只須要包括必要字段便可,無需將整行數據信息都提取出來。通常來講只要須要提取交易時間,金額,交易訂單號,渠道返回流水號。
這一層主要就是數據庫的查詢行爲。最好使用備庫進行數據查詢。由於這裏咱們須要提取前一日全量的支付成功的數據,數據量大的狀況下,可能會拖慢主庫,影響在線的支付交易。
這一個模塊咱們使用上一模塊提取出來的數據,覈對訂單號與金額是否徹底一致。覈對模塊僞代碼以下。
這個過程可能產生三類差別數據。
第一種狀況爲本端數據存在,對端數據不存在,咱們稱爲本端多帳。
第二種狀況爲對端數據存在,本端數據不存在,咱們稱爲對端多帳。
第三種狀況爲金額不一致。
三者如圖所示。
這裏產生的差別數據存入一張差別表中,以便下個模塊使用。
這個模塊主要用來處理上個模塊產生的差別數據。
上面三類差別數據中,金額不一致至關少見,這種狀況須要人工判斷。
咱們先討論本端多帳的狀況。
本端多帳是對帳系統最多見的一種狀況。這種狀況可能因爲交易的時候發生日切問題,致使雙方記帳日期不一致,從而發生不平帳。
咱們先解釋日切的概念。
日切,通俗的來講就是更換系統記帳的時間,系統從當前工做日切換到下一工做日。這個過程當中,若我方的交易訂單恰好發生在 T 日 23:59:59,那麼我方的記帳時間爲 T 日。第三方渠道接收到訂單的時間爲 T+1 日 00:00:01,這樣第三方渠道該筆的交易的對帳日期爲 T+1 日。
第三方渠道 T 日對帳文件將缺乏這筆,可是我方 T 日數據卻存在這筆,這就致使了覈對過程當中產生一筆本端多帳差別數據。
對於這類差別數據,咱們能夠選擇將這筆數據掛帳,等待 T+1 工做日對帳。T+1 日對帳的時候,對帳單會相應多出數據,這樣在覈對過程就會產生對端多帳的差別數據。
而後在 T+1 日差別處理模塊將前幾日差別數據都提取出來,逐筆覈對本端多帳數據與對端多帳數據。若覈對一致,將兩筆差別狀態都更新成處理完成。最後若無剩餘差別數據,當天帳單平帳。
僞代碼以下:
對端多帳的產生狀況可能可能有兩種狀況.
第一種狀況測試環境與生產環境共用一份第三方渠道參數,這就致使測試環境交易訂單也會出如今對帳單中。如果這種狀況,咱們確認測試環境存在這批數據以後,咱們忽略這批差別數據便可。
第二種狀況,本端交易訂單存在,可是狀態不是成功狀態。這種狀況下,須要調用第三方渠道提供的查詢接口,查詢訂單最終狀態。若查詢成功,更新訂單狀態,而後將差別數據狀態更改成處理成功。
若第三方渠道沒法查詢到訂單的狀態。這種若與渠道確認訂單最終支付成功,咱們須要將支付訂單改成支付成功,並修改差別帳的狀態。
最後咱們再次從新對帳,因爲對端多帳的數據會有對應的本端數據,將不會產生差別數據,此次對帳完成且平帳。
目前系統的對帳系統定時任務採用 Spring 定時功能。後期優化準備接入 elasticjob 這種分佈式定時調度程序,能夠作到快速修改定時任務的時間,而無需重啓程序。以及能夠快速觸發定時任務。
總之,對帳系統工做不難,就是細節比較繁瑣,前期很難將全部細節都考慮徹底,這個過程須要咱們不斷改進。