如何做一個對賬系統

在互聯網行業中只要涉及到支付,必然就會有對賬的需求,幾乎所有互聯網公司的業務中多多少少的都會涉及到支付,大一點的公司甚至都標配有了自己的第三方支付公司,因此對賬具有普遍性。對賬系統是支付體系中最重要的一環,也是保證交易、資金安全的最後一道防線。在大多數的互聯網公司中,一般都會有獨立的對賬系統來處理,比如:電商平臺、互聯網金融、第三方支付公司等。

對賬是支付系統中的一環,因此在對賬前我們先了解一下相關的業務知識

業務知識

什麼是對賬

傳統的對賬就是覈對賬目,是指在會計覈算中,爲保證賬簿記錄正確可靠,對賬簿中的有關數據進行檢查和核對的工作。在銀行或者第三方支付中,對賬其實是對一定週期內的交易進行雙方確認的過程,一般都是在第二天銀行或者第三方支付公司對前一日交易進行清分,生成對賬單供平臺商戶下載,並將應結算款結算給平臺商戶。在往下一層,在互聯網金融行業或者電商行業中,對賬其實就是確認在固定週期內和支付提供方(銀行和第反方支付)的交易、資金的正確性,保證雙方的交易、資金一致正確。

廣義的對賬,所有跨應用的數據交互,理論上都應該進行對賬。所以對賬也可以分爲信息流對賬,資金流對賬。信息流對賬也一般用在自己內部系統的對賬,比如支付系統的支付數據和業務系統的業務數據進行對賬,保證資金交易和業務交易的一致性。資金流對賬也就是支付系統和銀行或者第三方支付系統之間的資金交易對賬。

對賬方式

  • 單向對賬:一般拿第三方支付機構或銀行流水,與自己系統進行對賬,防止出現掉單問題;

  • 雙向對賬:兩個應用間的流水進行雙向覈對,如訂單與財務系統,既要保證財務系統支付成功的記錄,訂單系統也是成功的;也要確保訂單系統記錄成功的記錄,財務系統也成功。

我們一般採用雙向對賬的方式進行對賬

對賬相關的問題

不同系統日切點不一致問題:滾動對賬
差錯處理:補賬,補償(退款)

相關概念

軋帳和平帳

每一筆交易,都要做到各參與者的記錄能夠吻合,沒有偏差。對賬系統的工作,是發現有差異的記錄,即軋帳;然後通過人工或者自動的方式,解決這些差異,即平帳。

長款和漏單

在以平臺交易爲基準的情況下和銀行對賬,發現週期內的交易,平臺有此訂單而第三方支付中沒有訂單,成爲平臺長款。平臺長款一般是由於用戶在支付的時候跨天的情況,比如用戶在23:58分創建了訂單,在第二天的凌晨00:03分進行了支付。在以銀行交易爲基準的情況下對賬,銀行有此訂單而平臺無此訂單,即爲平臺漏單。平臺漏單很少見,一般直接轉人工處理。

賬戶體系

在一般的支付體系中會分爲登錄賬戶和支付賬戶,支付賬戶指用戶在支付系統中用於交易的資金所有者權益的憑證;登錄賬號指用戶在系統中登錄的憑證和個人信息。一個用戶可以有多個登錄賬戶,一個登錄賬戶可以有多個支付賬戶,比如零錢賬戶、儲值卡賬戶等。一般來說,支付賬戶不會在多個登錄賬戶之間共用。對賬的交易一般都是支付賬戶參與交易。

交易與賬戶

賬戶設置,一般是從交易開始的。 交易的實現必須有賬戶的支持,賬戶是交易的基本構成元素。 從支付系統的角度,交易中涉及到的資金流是資金從一個賬戶流向另一個賬戶。 發起交易的一方,被稱之爲交易主體,他可以是一個人,也可以是一個機構。

清算和結算

清算主要是指不同銀行間的貨幣收付,可以認爲是結算進行之前,發起行和接收行對支付指令的發送、接收、覈對確認,其結果是全面交換結算工具和支付信息,並建立最終結算頭寸。

結算是指將清算過程產生的待結算頭寸分別在發起行、接收行進行相應的會計處理,完成資金轉移,並通知收付雙方的過程。當前,大多數銀行結算業務的完成主要通過兩類賬戶:一是銀行間互相開立的代理賬戶,二是開立在央行、獨立金融機構如銀聯、或者第三方支付機構的賬戶。

清算:計算各方應收應付錢款的時間與金額。結算:根據清算的結果在指定的時間對各方進行實際的資金轉移操作

資金池

用戶備付資金(如充值)統一放在企業的銀行賬戶中,企業可以隨意支配這些資金,即爲資金池。與之對應的是第三方託管,用戶備付資金是放在企業在第三方支付機構爲用戶開設的虛擬賬戶中,企業無法隨意取出這些資金。現在互聯網金融全面要求接入銀行存管,就是銀行會爲每個用戶創建一個資金賬戶來保護用戶的資金,互聯金融公司不能隨意劃撥這些資金賬戶中的金額。

對賬系統

對賬設計

對賬系統的設計階段,將對賬系統分爲四個模塊,每個模塊的負責自己的職能。

  • 文件獲取模塊:下載或者讀取各渠道對賬文件

  • 文件解析模塊:創建不同的解析模板,根據渠道和文件類型獲取對應的解析模板進行解析

  • 對賬處理模塊:對賬的業務邏輯處理

  • 差錯處理模塊:處理差錯池中的訂單

一般會設計一個定時任務,每天固定的時間點觸發,定時驅動調度類分別調用四個模塊來處理對賬。也有的銀行會主動的推送對賬單,再通過http回調來觸發對賬流程。

對賬算法

一、流程:

1、從上游渠道(銀行、銀聯等金融機構)獲取對賬文件,程序逐行解析入庫;
2、在程序處理中,以上游對賬文件的表爲基準,程序逐行讀取並與我們系統的交易記錄對比賬務記錄(有賬務系統情況下,合理方案應該是於賬務記錄)對比,查找出差異記錄;
3、以我們系統的交易記錄對比賬務記錄爲基準,程序逐行讀取與上游對賬文件對比,查找出差異記錄。

二、缺陷:

1、對賬過程中查詢相關數據,如果數據量巨大,對數據庫性能影響較大,而且對賬邏輯擴展極爲麻煩;
2、逐行比對算法效率較低,但算法上並無好的優化餘地。如果採用數據庫INTERSECT、MINUS對數據庫壓力也高; 
3、在業務量大的情況下(例如有上百家上游渠道需要對,每一家都有幾十萬條交易記錄),對賬服務器及數據庫服務器負荷較高。即便採用讀寫分離,對賬時候使用讀庫,壓力一樣很大;
4、導入批量文件,逐行入庫效率較爲低下(每一次都需要建立網絡連接、關閉連接)。

三、改進:

1、涉及網絡傳輸的,儘量採用批量方式操作,減少網絡消耗及時間消耗;
2、使用Redis等NOSQL數據庫,降低數據庫服務器的壓力。同時在擴展上也容易,一臺Redis服務器不夠,可以無限制增加用於對賬用的服務器;
3、使用Redis的set集合的sdiff功能,利用Redis sdiff算法的高性能,比對上游記錄和我方記錄的差異。

對賬流程

1、下載對賬單

大多數銀行都要求接入方提供ftp服務,銀行定時將對賬單推送到接入方提供的ftp服務器上面;還有一部分銀行會提供對賬單的下載服務,通過ftp/http的都有,ftp方式居多;另外網銀的對賬單比較特殊,一般都需要結算登錄網銀的後臺管理系統中,手動下載,結算下載完對賬單後在導入到對賬系統。

技術實現上可以做成工廠模式,不同的支付渠道有不同的下載類,如果是http接口將文件寫入到對賬單,如果是ftp服務器,將服務器中的對賬單下載到本地帶解析的目錄中。主要涉及的代碼ftp工具類、http(s)工具類,相關IO讀寫。

技術選型上,HTTP(S)用apache httpclient即可實現鏈接池和斷點續傳, FTP也可以使用Apache Commons Net API。 但不管是哪一個,都需要設置重試次數和鏈接超時間。重試次數和間隔的設置需要小心,重試太頻繁,容易把服務器打死.;時間間隔太大,又會阻塞後續處理步驟。5~10分鐘是一個合適的重試間隔區間。

2、創建批次

創建批次一方面是爲了防止重複對賬,另一方面需要在對賬結束的時候將對賬的結果信息存儲到批次中。

3、解析文件

解析文件主要是將下載的對賬文件解析成我們可以對賬的數據類型並且入庫。解析的文件不同渠道有不同的類型,因此也可以設計成不同的解析模板,使用工廠模式將不同格式的文件解析成可以對賬的統一數據類型。解析的文件類型一般包括:json、text、cvs、excle等,另外部分銀行會對賬單做加密或者提供zip打包的格式,這裏就需要額外開發zip工具類和加解密工具類進行處理。

對賬文件中包含的主要信息有:商戶訂單號、交易流水號、交易時間、支付時間、付款方、交易金額、交易類型、交易狀態這些字段。

4、對賬處理

對賬處理也是對賬的核心邏輯,具體分爲以下的幾個步驟來實現:

  • 查詢平臺所有交易成功的訂單

  • 查詢平臺所有的交易訂單

  • 查詢平臺緩存池中的數據

  • 查詢銀行交易成功的訂單

  • 開始以平臺的數據爲準對賬,平臺長款記入緩衝池

  • 開始以銀行通道的數據爲準對賬

以平臺訂單爲基準對賬邏輯:以平臺所有交易成功的訂單爲基準,遍歷銀行訂單的所有數據,找出訂單號相同的訂單,對比訂單的金額、手續費是否一致。如果一致跳過;如果不一致,平臺訂單進入差錯池;如果在銀行訂單中沒有找到此筆交易,訂單進入緩存池,記錄平臺長款。同時統計對賬相關金額和訂單數。

以銀行訂單爲基準對賬邏輯:以銀行的交易數據爲基準,遍歷所有平臺的交易(包括未成功的訂單),找出訂單號相同但支付狀態不一致的訂單,在進行對比金額存入差錯池。如果沒有在平臺的交易中找到此訂單,再從緩存池中遍歷查找,找到對應的平臺訂單驗證金額是否一致,不一致進入差錯池。如果在緩存池匯中依然沒有找到對應的訂單,直接進入差錯池,記錄平臺漏單。同時統計對賬相關金額和訂單數。

5、對賬統計

根據對賬處理中,統計的相關信息包括:對賬完成時間、對賬是否成功、平賬的金額和訂單數、差錯的金額和訂單數、緩存池金額和訂單數等。

6、差錯處理

在一般系統中,差錯處理分爲兩種,一種人工來處理,一種系統自動來處理。

主要有如下情況:

  • 本地未支付,支付渠道已支付。這主要是本地未正確接收到渠道下發的異步通知導致。 一般處理是將本地狀態修改爲已支付,並做響應的後續處理,比如通知業務方等。

  • 本地已支付,支付渠道已支付,但是金額不同,這個需要人工覈查。

  • 本地已支付,但是支付渠道中無記錄;或者本地無記錄,支付渠道有記錄。在排除跨日因素外,這種情況非常少見,需要了解具體原因後做處理。

示例代碼

網上的對賬系統的開源代碼不是很多,但有一家還不錯:龍果支付。龍果支付中有比較完整的對賬流程,代碼中以微信、支付寶的對賬單爲例寫了對賬的流程,大家可以參考。

roncoo-pay

最後,你們公司的對賬系統是怎麼實現的,遇到了那些坑?歡迎和我討論。

參考:

支付系統的對賬處理

賬戶體系架構設計相關思路記錄

對賬系統–項目總覽

keeppuresmile.jpg 
掃描關注:純潔的微笑


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