系统里的资金交易如何与银行通道对账?我们这样设计
以系统里的出金交易为例, 与银行对账不外乎做两件事:①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 * * ?。 但这样依然无法根本解决对账不及时的问题。 因此,更合适的实现方案是,拉取到对账单后就异步触发对账。
【EOF】知识就是力量,但更重要的是...。欢迎关注我的微信公众号「靠谱的程序员」,解密靠谱程序员的日常,让我们一起做靠谱的程序员。
当看到一些不好的代码时,会发现我还算优秀;当看到优秀的代码时,也才意识到持续学习的重要!--buguge
本文来自博客园,转载请注明原文链接:https://www.cnblogs.com/buguge/p/17891549.html