支付系統(tǒng)設(shè)計(jì):對(duì)賬處理(二)

28 評(píng)論 133894 瀏覽 594 收藏 13 分鐘

可以說(shuō),對(duì)賬是支付系統(tǒng)最頭疼的事情。每一筆交易,都要做到各參與者的記錄能夠吻合,沒有偏差。對(duì)賬系統(tǒng)的工作,是發(fā)現(xiàn)有差異的記錄,即軋帳;然后通過(guò)人工或者自動(dòng)的方式,解決這些差異,即平帳。

對(duì)電商系統(tǒng)來(lái)說(shuō),每一筆交易,在所有相關(guān)主體側(cè)都要能對(duì)得上:

  • 交易主體,如果發(fā)起人是個(gè)人,必須能夠從個(gè)人交易歷史記錄中找到這筆交易。但大部分人不會(huì)保留電子記錄,所以一般是提供可以下載的賬單或交易記錄,讓用戶自己對(duì)去。
  • 交易對(duì)手,一般是商戶。商戶側(cè)對(duì)賬處理同用戶側(cè),也僅僅提供對(duì)賬單。
  • 交易渠道側(cè),這是對(duì)賬的重點(diǎn),一是核實(shí)交易流水,二是核實(shí)交易傭金,畢竟是租用人家通道做結(jié)算的。

那有哪些記錄需要對(duì)賬? 目前主要是兩個(gè):一個(gè)是交易記錄;一個(gè)是退款記錄。

對(duì)賬處理流程

一般來(lái)說(shuō),對(duì)賬流程涉及到如下步驟: 渠道對(duì)賬單下載、本地交易記錄準(zhǔn)備、軋賬、平賬。

渠道對(duì)賬單下載

銀行,第三方支付,銀聯(lián)等,基本都會(huì)提供對(duì)賬單下載的功能。不過(guò)也有少數(shù)工作做不到位或者太到位的銀行,只提供賬單查詢后臺(tái),不提供對(duì)賬單下載功能。

對(duì)開發(fā)人員來(lái)說(shuō),這里有幾個(gè)坑:

  • 對(duì)賬單格式不一。文本,XML,csv的都有。為了后續(xù)能夠統(tǒng)一處理,在賬單下載完成后,需要進(jìn)行標(biāo)準(zhǔn)化處理。
  • 下載方式不一,HTTP,HTTPS,F(xiàn)TP的,都有。下載程序需要按照渠道的協(xié)議來(lái)處理。
  • 下載時(shí)間不一,一般是凌晨1點(diǎn)后,到中午12才能用的也有。如果在預(yù)定的時(shí)間取不到數(shù)據(jù),需要注意重試讀取。
  • 穩(wěn)定性差。FTP服務(wù)器出問(wèn)題那是常有的事。渠道側(cè)解決方案往往就是重啟。所以重試機(jī)制是必要的。

看一下第三方支付的對(duì)賬單情況:

1

銀行直連的對(duì)賬情況:

2

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

鏈接超時(shí)指在服務(wù)器出現(xiàn)問(wèn)題時(shí),連接在指定時(shí)間內(nèi)獲取不到數(shù)據(jù)即自動(dòng)斷開。這個(gè)很容易被忽略。我們有一次系統(tǒng)出問(wèn)題,是渠道側(cè)的FTP假死后重啟,導(dǎo)致我們的客戶端掛住,一直在等待重新鏈接。

渠道對(duì)賬單標(biāo)準(zhǔn)化

找個(gè)例子大家看看, 比如微信的對(duì)賬單,他是csv格式的,包括如下信息:

  1. 交易時(shí)間:這是在微信側(cè)的支付完成的時(shí)間。 這個(gè)時(shí)間會(huì)成為一個(gè)陷阱。
  2. 公眾賬號(hào)ID,商戶號(hào),子商戶號(hào),設(shè)備號(hào): 這些信息需要做驗(yàn)證,確保是自己的單子,不要讓微信把老王家的單子也給發(fā)過(guò)來(lái)了;
  3. 微信訂單號(hào),商戶訂單號(hào): 這兩個(gè)是對(duì)單的核心。前者是微信側(cè)產(chǎn)生的訂單號(hào),在微信支付接口返回值中有。但是萬(wàn)一收不到這個(gè)返回值,那在本地記錄中可能就空了。 后者是我們發(fā)送給微信的訂單號(hào),一般用這個(gè)來(lái)做對(duì)單依據(jù)。兩邊的數(shù)據(jù)中都會(huì)有這個(gè)值。
  4. 用戶標(biāo)識(shí),交易類型,交易狀態(tài),付款銀行,貨幣種類,總金額,企業(yè)紅包金額: 這幾個(gè)就是對(duì)單的核心字段,必須確保雙方是一致的。
  5. 商品名稱,商戶數(shù)據(jù)包,手續(xù)費(fèi),費(fèi)率:這些是可選驗(yàn)證。

微信對(duì)賬單

而某寶的對(duì)賬單,是文本格式的,用空格隔開。他們家的就簡(jiǎn)單很多,只有商戶訂單號(hào),交易流水號(hào),交易時(shí)間,支付時(shí)間,付款方,交易金額,交易類型,交易狀態(tài)這些字段。

某寶對(duì)賬單

由于每個(gè)渠道的賬單格式都不盡相同, 在得到賬單后,下一步是對(duì)賬單做標(biāo)準(zhǔn)化處理,這樣軋帳以及后續(xù)工作就可以統(tǒng)一處理了。 標(biāo)準(zhǔn)化后的賬單數(shù)據(jù)可以放在文件系統(tǒng)或者數(shù)據(jù)庫(kù)中。這取決于交易數(shù)據(jù)量。每天百萬(wàn)以上的量,還是使用文件系統(tǒng),比較合適。數(shù)據(jù)庫(kù)操作相對(duì)比較慢,也浪費(fèi)資源。

基于文件系統(tǒng)的標(biāo)準(zhǔn)化涉及如下內(nèi)容:

  • 文件格式標(biāo)準(zhǔn)化:統(tǒng)一使用csv或者json或者xml格式。如果是使用hadoop或者spark來(lái)對(duì)賬,使用csv是個(gè)不錯(cuò)的選擇。
  • 文件存儲(chǔ)統(tǒng)一化:文件目錄,文件名都需要遵循統(tǒng)一命名規(guī)范。

為了加快處理速度,我們使用hdfs作為文件系統(tǒng),有利于后續(xù)的對(duì)賬的處理。

本地交易記錄準(zhǔn)備

本地交易記錄的準(zhǔn)備,總的來(lái)說(shuō)有如下方法: – 啥都不做,直接用原始數(shù)據(jù)。鑒于大部分系統(tǒng)使用的是mysql,這也意味著在MySQL上做對(duì)賬。對(duì)賬時(shí)需要大量的數(shù)據(jù)查找工作,必然會(huì)影響線上業(yè)務(wù)。在數(shù)據(jù)規(guī)模較大,比如超過(guò)100萬(wàn)時(shí),就不太合適了。

  • 當(dāng)然,還有一個(gè)選擇是使用備庫(kù)來(lái)執(zhí)行對(duì)賬,這樣既簡(jiǎn)單,也不影響線上業(yè)務(wù)。這是典型的空間換時(shí)間的做法。
  • 如果業(yè)務(wù)大到需要分表分庫(kù)才能處理,那對(duì)賬數(shù)據(jù)準(zhǔn)備也不一樣。使用分庫(kù)也不現(xiàn)實(shí),因?yàn)榉謳?kù)一般是按照主體id,而不是渠道id,來(lái)分庫(kù),這樣對(duì)賬就需要在多個(gè)庫(kù)上進(jìn)行,效率反而降低了。而對(duì)分表分庫(kù)建立從庫(kù)也非常耗費(fèi)資源。這種情況下,需要同步一份數(shù)據(jù)到(hdfs)文件系統(tǒng)中,或者NOSQL數(shù)據(jù)庫(kù)上。

由于交易記錄是支付系統(tǒng)核心數(shù)據(jù),有大量的應(yīng)用,如信用、風(fēng)控等,都需要交易記錄數(shù)據(jù)。這些應(yīng)用對(duì)交易記錄的需求還不完全一致,為了提升性能, 交易記錄會(huì)使用異步的方式來(lái)將數(shù)據(jù)投遞給使用方。 交易記錄在入庫(kù)時(shí),投遞消息到消息系統(tǒng)中。使用方監(jiān)聽這個(gè)消息,一旦收到新消息,則從交易記錄庫(kù)中查詢數(shù)據(jù),獲取數(shù)據(jù)并更新到庫(kù)中。關(guān)于此類數(shù)據(jù)同步的文章不少,這里就不詳細(xì)介紹。

軋帳

軋帳是按照客戶訂單號(hào)來(lái)比較本地交易記錄和渠道交易記錄是否一致。從算法角度,是計(jì)算兩個(gè)數(shù)組的差異。在單機(jī)運(yùn)行時(shí),可以采用的算法不少,這里不詳細(xì)介紹。 我們推薦采用mapreduce來(lái)軋帳,這有個(gè)優(yōu)勢(shì),可以按照訂單號(hào)將渠道提供的記錄和本地記錄shuffle到同一個(gè)reduce處理上,這樣就可以很容易進(jìn)行數(shù)據(jù)比對(duì)。 軋帳中最大的坑,莫過(guò)于切分點(diǎn)的問(wèn)題。

比如以整0點(diǎn)為切分點(diǎn),那存在一個(gè)問(wèn)題,本地23:59發(fā)起的交易,到了渠道側(cè),可能會(huì)在00:01處理,這一筆交易變成第二天的帳了。實(shí)際處理中,一筆交易在渠道側(cè)處理,花上幾分鐘都有可能。 對(duì)于切分點(diǎn)附近無(wú)法確認(rèn)的帳,做一個(gè)時(shí)間窗,在時(shí)間窗內(nèi)的數(shù)據(jù),留待第二天對(duì)賬時(shí)繼續(xù)處理。

平帳

發(fā)現(xiàn)兩邊不一致的數(shù)據(jù),那應(yīng)該如何處理?數(shù)據(jù)量不大時(shí),記錄起來(lái),人工甄別就行。但如果數(shù)據(jù)量很大,每天上千條,人工處理就成本太高了。這個(gè)沒有統(tǒng)一的處理方法,需要根據(jù)有問(wèn)題的數(shù)據(jù),做個(gè)分析,然后做自動(dòng)處理。 針對(duì)交易記錄的對(duì)賬的處理,主要有如下情況:

  • 本地未支付,支付渠道已支付。這主要是本地未正確接收到渠道下發(fā)的異步通知導(dǎo)致。 一般處理是將本地狀態(tài)修改為已支付,并做響應(yīng)的后續(xù)處理,比如通知業(yè)務(wù)方等。
  • 本地已支付,支付渠道已支付,但是金額不同,這個(gè)需要人工核查。
  • 本地已支付,但是支付渠道中無(wú)記錄;或者本地?zé)o記錄,支付渠道有記錄。在排除跨日因素外,這種情況非常少見,需要了解具體原因后做處理。

針對(duì)退款的對(duì)賬處理,主要有如下情況:

  • 本地未退款,支付渠道已退款,則以支付渠道為準(zhǔn),修改本地為已退款狀態(tài),并觸發(fā)后續(xù)處理。
  • 本地已退款、支付渠道已退款,但是金額不同,需要人工核查;
  • 本地已退款,但是支付渠道無(wú)記錄;或者支付渠道有記錄,但是本地沒有。 在排除跨日因素外, 這種情況非常少見,需要了解具體原因后做處理。

總之,對(duì)賬工作,即復(fù)雜也不復(fù)雜。需要細(xì)心,對(duì)業(yè)務(wù)要有深入的了解,并選擇合適的架構(gòu)。

相關(guān)閱讀

支付系統(tǒng)設(shè)計(jì):支付系統(tǒng)的賬戶模型(一)

 

作者:鳳凰牌老熊,程序員 & 架構(gòu)師,來(lái)自中科大的本科,研究生在軟件所學(xué)習(xí)。先后在中科輔龍、三星(中國(guó))研究院和國(guó)內(nèi)一些大型的互聯(lián)網(wǎng)公司呆過(guò)。在中科輔龍公司負(fù)責(zé)電子政務(wù)內(nèi)容管理系統(tǒng)建設(shè),負(fù)責(zé)研發(fā)龍馭系列產(chǎn)品的研發(fā),這款產(chǎn)品最終實(shí)施到2000多個(gè)電子政務(wù)網(wǎng)站上,期間也參與了一些支付反洗錢以及支付系統(tǒng)的建設(shè)。之后在三星中國(guó)研究院,負(fù)責(zé)自然語(yǔ)言處理(NLP)以及智能家居相關(guān)項(xiàng)目。智能家居項(xiàng)目在2014CES消費(fèi)電子展上作為三星重點(diǎn)項(xiàng)目推介。2014年開始加入愛奇藝公司,負(fù)責(zé)數(shù)據(jù)倉(cāng)庫(kù)和支付系統(tǒng)的建設(shè)。

本文由@鳳凰牌老熊(微信公眾號(hào):shamphone) 原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理 。未經(jīng)許可,禁止轉(zhuǎn)載。

更多精彩內(nèi)容,請(qǐng)關(guān)注人人都是產(chǎn)品經(jīng)理微信公眾號(hào)或下載App
評(píng)論
評(píng)論請(qǐng)登錄
  1. 消費(fèi)券的發(fā)放和使用

    來(lái)自北京 回復(fù)
  2. 1. 在收到支付成功回調(diào)后保留渠道支付成功時(shí)間,對(duì)賬時(shí)采用渠道時(shí)間來(lái)進(jìn)行對(duì)賬;
    2. 如果渠道側(cè)不提供成功時(shí)間,對(duì)賬時(shí)采用平臺(tái)時(shí)間與渠道時(shí)間進(jìn)行對(duì)賬,對(duì)賬時(shí)平臺(tái)長(zhǎng)款時(shí)間在接近日切點(diǎn)時(shí)可放到第二日進(jìn)行對(duì)賬,如渠道長(zhǎng)款可根據(jù)渠道ID到我平臺(tái)支付表中查詢,進(jìn)行差錯(cuò)狀態(tài)細(xì)化,有可能因?yàn)闀r(shí)間的差異此筆交易已成功;
    3. 如果交易數(shù)據(jù)量大,可采用分批對(duì)賬,MAPA – MAPB 流水排序交易,已10萬(wàn)數(shù)據(jù)分頁(yè)查詢?yōu)槔认耐甑臄?shù)據(jù)進(jìn)行下次分頁(yè)查詢,差異先統(tǒng)一存儲(chǔ),所有數(shù)據(jù)對(duì)賬后進(jìn)行整體處理;
    4. 對(duì)賬產(chǎn)生的差異應(yīng)針對(duì)渠道或平臺(tái)賬戶進(jìn)行資金凍結(jié),來(lái)保證對(duì)賬數(shù)據(jù)與賬戶數(shù)據(jù)一致性;

    來(lái)自北京 回復(fù)
  3. 很有條理 很有用!干活滿滿

    來(lái)自浙江 回復(fù)
  4. 請(qǐng)問(wèn)現(xiàn)在對(duì)賬思路都是 人工上傳賬單或者自動(dòng)獲取賬單,然后找到業(yè)務(wù)訂單去對(duì)賬(賬單-訂單對(duì)賬),是否還有別的對(duì)賬思路呢

    來(lái)自北京 回復(fù)
  5. 請(qǐng)問(wèn),現(xiàn)在第三方支付都要統(tǒng)一接入網(wǎng)聯(lián),這些功能是否還需要系統(tǒng)自己實(shí)現(xiàn)呢

    來(lái)自四川 回復(fù)
  6. 簡(jiǎn)書上有人轉(zhuǎn)載你的文章,有標(biāo)明轉(zhuǎn)載地址。是你自己么?還是朋友?http://www.jianshu.com/u/897526abf799

    來(lái)自浙江 回復(fù)
  7. 感謝 感謝,良心干貨篇,多謝

    來(lái)自上海 回復(fù)
  8. 對(duì)于一個(gè)即將轉(zhuǎn)入支付系統(tǒng)的程序猿, 看到你的文章如沐春風(fēng), 感覺業(yè)務(wù)思路上清楚多了,多謝講解

    來(lái)自上海 回復(fù)
  9. 我也是支付行業(yè),很是喜歡你的筆記和感悟,對(duì)一個(gè)踏入新行業(yè)不久的新人來(lái)說(shuō),是一件值得慶幸的事情。

    來(lái)自江蘇 回復(fù)
  10. 我想咨詢下,像這種交易單的下載通過(guò)支付寶,微信,銀聯(lián)借口就能直接下載獲取嗎?還是說(shuō)是需要財(cái)務(wù)人員到相關(guān)的平臺(tái)將相關(guān)的賬單導(dǎo)出放到FTP,程序再定時(shí)獲取與本地的訂單數(shù)據(jù)來(lái)做核對(duì)呢?

    來(lái)自北京 回復(fù)
  11. 請(qǐng)教一下:交易流水表,如何按照交易流水號(hào)來(lái)做分庫(kù)、分表的依據(jù)。這樣需要查詢某個(gè)用戶的所有交易流水,由于是按照交易流水切分,數(shù)據(jù)會(huì)分散在多個(gè)庫(kù)、多個(gè)表。展示起來(lái),就需要跨庫(kù)、跨表查詢了。尤其是,要分頁(yè)展示某個(gè)用戶所有的交易流水。在支付寶上有。求教作者這方面,怎么處理?

    來(lái)自湖南 回復(fù)
    1. 按照用戶來(lái)分表分庫(kù),流水號(hào)根據(jù)用戶ID來(lái)生成。

      來(lái)自北京 回復(fù)
  12. 對(duì)于切分點(diǎn)附近無(wú)法確認(rèn)的帳,做一個(gè)時(shí)間窗,在時(shí)間窗內(nèi)的數(shù)據(jù),留待第二天對(duì)賬時(shí)繼續(xù)處理。
    –請(qǐng)教一下,這個(gè)時(shí)間窗如何設(shè)置?能大概講下?謝謝

    來(lái)自上海 回復(fù)
  13. 點(diǎn)贊,好文。

    回復(fù)
  14. “軋帳中最大的坑,莫過(guò)于切分點(diǎn)的問(wèn)題”,這個(gè)對(duì)于沒做過(guò)的人,真的不見得注意到這個(gè)坑;

    想起我們做通信的時(shí)候,一次正常的呼叫,有很多信令記錄點(diǎn),比如起呼是一個(gè)信令記錄點(diǎn),在23:59分發(fā)起; 接通是一個(gè)信令點(diǎn),在00:01分發(fā)生; 這樣,起呼就在上一個(gè)時(shí)間點(diǎn),接通在下一個(gè)時(shí)間點(diǎn),當(dāng)我們按小時(shí)來(lái)統(tǒng)計(jì)接通率的時(shí)候,這就悲劇了;

    來(lái)自廣東 回復(fù)
    1. 這個(gè)怎么統(tǒng)計(jì)比較好啊

      來(lái)自廣東 回復(fù)
  15. 前輩,解決切分點(diǎn)問(wèn)題的時(shí)間窗是指什么呢?

    來(lái)自浙江 回復(fù)
  16. 好文!但是發(fā)現(xiàn)一個(gè)小小的瑕疵,“本地未退款,支付渠道已退款,則以支付渠道為準(zhǔn),修改本地為已退款狀態(tài),并出發(fā)后續(xù)處理?!边@個(gè)地方是不是應(yīng)該為“觸發(fā)”。

    來(lái)自廣東 回復(fù)
    1. 謝謝, 是筆誤。

      來(lái)自北京 回復(fù)
  17. 以表敬意

    回復(fù)
  18. 太棒了,居然有一系列的分享,大神就是這樣

    來(lái)自北京 回復(fù)
  19. 看到以前自己天天面對(duì)的業(yè)務(wù),哈哈,還有些懷念呢。

    來(lái)自江蘇 回復(fù)
    1. 現(xiàn)在面對(duì)什么業(yè)務(wù)

      來(lái)自上海 回復(fù)
    2. 時(shí)髦的O2O,線下智能POS與線上結(jié)合

      來(lái)自江蘇 回復(fù)
  20. 好文,希望能寫的更深入點(diǎn),多舉一些實(shí)際場(chǎng)景 ??

    來(lái)自廣東 回復(fù)
  21. 良心文章

    來(lái)自廣東 回復(fù)
    1. 謝謝。

      來(lái)自北京 回復(fù)