系统里的资金交易如何与银行通道对账?我们这样设计

发布时间 2023-12-09 21:45:28作者: buguge

以系统里的出金交易为例, 与银行对账不外乎做两件事:①T+1日拉取银行账单,保存银行账单交易流水;②银行账单交易流水与本系统里的通道交易流水比对并记录差异。

 

数据表设计

数据表表名comment主要字段
银行账单批次表 bank_bill_batch 银行账单表,每银行每天一条记录

batchNo-批次号(PK)

bankId-系统里记录的银行通道编号

trans_date-交易日期

createTIme-记录创建时间,即账单的首次拉取时间

updateTime-最后更新时间

checkState-对账处理状态 - IPS(初始待对账/对账中/对账完成)

银行账单交易流水 bank_bill_detail 银行账单交易明细

batchNo-批次号(PK)

bankId-系统里记录的银行通道编号

transOrderNo-系统里的交易单号

bankTransOrderNo-银行侧交易单号

bankTransState-银行侧交易状态(程序里转换为系统里的交易状态)

bankTransAmount-交易金额,以分为单位存储

bankTransTime-银行侧交易完成时间

createTIme-记录创建时间

银行对账记录表 bank_bill_check_result 银行账单与系统交易对账结果  

 

 

 

 

 

如何实现对账?

毋庸置疑,实现方案是使用定时任务。如,每隔30分钟从系统对接的各银行获取账单,再进行对账。

拉取银行账单JOB银行对账JOB

获取需要拉取账单的银行通道列表-bankList

依次遍历 bankList

查询bank_bill_batch,获取待对账的账单批次-batchList

依次遍历batchList

 ↓

拉取银行账单方法(){

  防重复执行控制

  组装银行请求参数,拉取银行账单

  持久化入库,包括银行账单批次表和账单明细表(事务)

}

银行对账方法(){

  防重复执行控制

  更新batch的checkState=P

  对该批次与系统里的T-1日交易进行check

  完成后,标记batch的checkState=S

 

细节

银行账单是在T+1日生成T日账单。不同银行的对账单的具体生成时间点有所不同,有的是01:00,有的可能是09:00,甚至有的是中午11:00。1因此,定时任务的开始时间可以从00:30开始,每隔半小时触发。银行账单一旦拉取完成,后续触发时不再重复拉取。

上面表格里的方案是两个定时任务,即将拉取银行账单与银行对账分开了。 这是有缺点的。——可能出现对账不及时的情况。

那么,如何优化呢? 保留一个JOB即可。 拉取银行账单的业务完成后,则异步触发银行对账,保证银行对账及时性。

 

 

【花絮】

我组起初也是2个定时任务,拉取银行账单JOB是整点每隔1小时执行(cron=0 0 1-12/1 * * ?),银行对账JOB是整半点点每隔1小时执行(cron=0 30 1-12/1 * * ?)。后来,产品经理和结算人员反馈对账不及时。开发人员就不断调整这2个cron表达式,让其触发时间间隔更接近。 例如,变更银行对账JOB的cron=cron=0 15 1-12/1 * * ?。 但这样依然无法根本解决对账不及时的问题。 因此,更合适的实现方案是,拉取到对账单后就异步触发对账。