在網際網路行業中只要涉及到支付,必然就會有對賬的需求,幾乎所有網際網路公司的業務中多多少少的都會涉及到支付,大一點的公司甚至都標配有了自己的第三方支付公司,因此對賬具有普遍性。對賬系統是支付體系中最重要的一環,也是保證交易、資金安全的最後一道防線。在大多數的網際網路公司中,一般都會有獨立的對賬系統來處理,比如:電商平臺、網際網路金融、第三方支付公司等。
對賬是支付系統中的一環,因此在對賬前我們先了解一下相關的業務知識
業務知識
什麼是對賬
傳統的對賬就是核對賬目,是指在會計核算中,為保證賬簿記錄正確可靠,對賬簿中的有關資料進行檢查和核對的工作。在銀行或者第三方支付中,對賬其實是對一定週期內的交易進行雙方確認的過程,一般都是在第二天銀行或者第三方支付公司對前一日交易進行清分,生成對賬單供平臺商戶下載,並將應結算款結算給平臺商戶。在往下一層,在網際網路金融行業或者電商行業中,對賬其實就是確認在固定週期內和支付提供方(銀行和第反方支付)的交易、資金的正確性,保證雙方的交易、資金一致正確。
廣義的對賬,所有跨應用的資料互動,理論上都應該進行對賬。所以對賬也可以分為資訊流對賬,資金流對賬。資訊流對賬也一般用在自己內部系統的對賬,比如支付系統的支付資料和業務系統的業務資料進行對賬,保證資金交易和業務交易的一致性。資金流對賬也就是支付系統和銀行或者第三方支付系統之間的資金交易對賬。
對賬方式
- 單向對賬:一般拿第三方支付機構或銀行流水,與自己系統進行對賬,防止出現掉單問題;
- 雙向對賬:兩個應用間的流水進行雙向核對,如訂單與財務系統,既要保證財務系統支付成功的記錄,訂單系統也是成功的;也要確保訂單系統記錄成功的記錄,財務系統也成功。
我們一般採用雙向對賬的方式進行對賬
對賬相關的問題
不同系統日切點不一致問題:滾動對賬
差錯處理:補賬,補償(退款)
相關概念
軋帳和平帳
每一筆交易,都要做到各參與者的記錄能夠吻合,沒有偏差。對賬系統的工作,是發現有差異的記錄,即軋帳;然後通過人工或者自動的方式,解決這些差異,即平帳。
長款和漏單
在以平臺交易為基準的情況下和銀行對賬,發現週期內的交易,平臺有此訂單而第三方支付中沒有訂單,成為平臺長款。平臺長款一般是由於使用者在支付的時候跨天的情況,比如使用者在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、差錯處理
在一般系統中,差錯處理分為兩種,一種人工來處理,一種系統自動來處理。
主要有如下情況:
- 本地未支付,支付渠道已支付。這主要是本地未正確接收到渠道下發的非同步通知導致。 一般處理是將本地狀態修改為已支付,並做響應的後續處理,比如通知業務方等。
- 本地已支付,支付渠道已支付,但是金額不同,這個需要人工核查。
- 本地已支付,但是支付渠道中無記錄;或者本地無記錄,支付渠道有記錄。在排除跨日因素外,這種情況非常少見,需要了解具體原因後做處理。