美文网首页
多渠道的支付系统之对账模块(四)

多渠道的支付系统之对账模块(四)

作者: 天草二十六_简村人 | 来源:发表于2023-01-09 09:11 被阅读0次

    1.Overview/背景介绍

    对账是支付系统中重要的一环,确认在固定周期内和第三方支付的交易、资金的正确性,保证双方的交易、资金一致正确。

    它又包括信息流对账和资金流对账:

    • 信息流对账一般用在自己内部系统的对账,比如支付系统的支付数据和业务系统的业务数据进行对账,保证资金交易和业务交易的一致性。
    • 资金流对账是支付系统和第三方支付系统之间的资金交易对账。

    术语介绍

    扎帐:发现对账系统中的差异记录。

    平账:通过人工或自动的方式,解决上述的差异。

    平台长款:平台有该订单,但第三方支付无此订单。

    平台漏单:第三方支付有该订单,但平台无此订单。

    2.Goals and Product Requirements/目标和产品需求

    业务目标

    • 财务人员 | 隔天自动对账,支持差错处理 | 减少人工对账的成本 |
    • 业务方 | 支持和财务系统进行双向对账 | 避免财务系统已收,但是业务系统未收的异常情况 |

    技术目标

    • 技术人员 | 支持自动对账;运用多种设计模式,动态支持多渠道多商户的对账|
    • DBA | 能够对已对账的表数据进行归档,提升数据库的操作效率 |

    3.ASR/关键架构需求

    技术约束

    业务约束

    • 微信和杭州银行的对账单都是以商户号维度来生成的
    • 杭州银行生成对账单的时间不明确,建议我们平台于次日12点后获取
    • 微信的对账单是在次日9点启动生成前一天的对账单,平台最早于10点后才能获取
    • 微信的对账单接口只能下载三个月以内的账单

    4.Out of Scope/范围

    本方案中的双向对账,是针对业务订单在交易中台中的业务,像智通云缴费的业务订单跟支付服务的对账不包括在内。

    5.Open Questions/开放性问题

    随着交易量的上升,对账的优化后期可使用redis或spark技术。

    目前对账模块放在支付服务中,后期考虑单独部署。

    6.Design/设计实现

    总体设计:

    image.png

    整体流程

    image.png

    核心对账流程

    • 查询平台所有交易成功的订单
    • 查询平台所有的交易订单
    • 查询平台缓存池中的数据
    • 查询第三方支付交易成功的订单
    • 开始以平台的数据为准对账,平台长款记入缓冲池
    • 开始以第三方支付通道的数据为准对账,当第三方支付订单不存在于平台未成功的订单列表中,需进一步查询是否存在于平台缓冲池中

    下面是关键的两个对账流程示意图:

    流程一:


    image.png

    流程二:

    image.png

    流程三:

    image.png

    对账结果:
    // 银行不存在该订单
    BANK_MISS("银行漏单"),
    // 平台不存在该订单
    PLATFORM_MISS("平台漏单"),
    // 银行支付成功,平台支付不成功(比较常见) PLATFORM_SHORT_STATUS_MISMATCH("平台短款,状态不符"),
    // 平台需支付金额比银行实际支付金额少(基本不会出现) PLATFORM_SHORT_CASH_MISMATCH("平台短款,金额不符"),
    // 银行实际支付金额比平台需支付金额少 PLATFORM_OVER_CASH_MISMATCH("平台长款,金额不符"),
    // 平台支付成功,银行支付不成功(基本不会出现) PLATFORM_OVER_STATUS_MISMATCH("平台长款,状态不符"),
    // 目前未实现该项对账
    FEE_MISMATCH("手续费不匹配");

    数模设计

    image.png

    数模脚本

    
    `CREATE` `TABLE` ``bill_info` (`
    
    ``id` ``int``(10) ``NOT` `NULL` `COMMENT ``'主键ID'``,`
    
    ``channel_type` ``varchar``(20) ``NOT` `NULL` `COMMENT ``'渠道类型: WX,HzBank,ALIPAY'``,`
    
    ``mch_id` ``varchar``(64) ``NOT` `NULL` `COMMENT ``'商户ID,对应表channel_account.mch_id'``,`
    
    ``batch_no` ``varchar``(64) ``NOT` `NULL` `COMMENT ``'对账批次号'``,`
    
    ``bill_ymd` ``varchar``(8) ``NOT` `NULL` `COMMENT ``'账单日期,格式YYYYMMDD'``,`
    
    ``status` ``varchar``(16) ``NOT` `NULL` `COMMENT ``'状态:SUCCESS,FAIL;'``,`
    
    ``error_msg` ``varchar``(500) ``DEFAULT` `NULL` `COMMENT ``'错误信息'``,`
    
    ``platform_amt` ``int``(10) ``DEFAULT` `0 COMMENT ``'平台交易金额(单位:分)'``,`
    
    ``platform_count` ``int``(10) ``DEFAULT` `0 COMMENT ``'平台交易笔数'``,`
    
    ``platform_refund_amt` ``int``(10) ``DEFAULT` `0 COMMENT ``'平台退款金额(单位:分)'``,`
    
    ``platform_refund_count` ``int``(10) ``DEFAULT` `0 COMMENT ``'平台退款笔数'``,`
    
    ``platform_fee` ``int``(10) ``DEFAULT` `0 COMMENT ``'平台手续费(单位:分)'``,`
    
    ``platform_refund_fee` ``int``(10) ``DEFAULT` `0 COMMENT ``'平台退款手续费(单位:分)'``,`
    
    ``bank_amt` ``int``(10) ``DEFAULT` `0 COMMENT ``'银行交易金额(单位:分)'``,`
    
    ``bank_count` ``int``(10) ``DEFAULT` `0 COMMENT ``'银行交易笔数'``,`
    
    ``bank_refund_amt` ``int``(10) ``DEFAULT` `0 COMMENT ``'银行退款金额(单位:分)'``,`
    
    ``bank_refund_count` ``int``(10) ``DEFAULT` `0 COMMENT ``'银行退款笔数'``,`
    
    ``bank_fee` ``int``(10) ``DEFAULT` `0 COMMENT ``'银行总手续费(单位:分)'``,`
    
    ``bank_refund_fee` ``int``(10) ``DEFAULT` `0 COMMENT ``'银行退款手续费(单位:分)'``,`
    
    ``pay_check_pool_count` ``int``(10) ``DEFAULT` `0 COMMENT ``'支付缓冲池笔数'``,`
    
    ``refund_check_pool_count` ``int``(10) ``DEFAULT` `0 COMMENT ``'退款缓冲池笔数'``,`
    
    ``mistake_count` ``int``(10) ``DEFAULT` `0 COMMENT ``'差错笔数'``,`
    
    ``unhandle_mistake_count` ``int``(10) ``DEFAULT` `0 COMMENT ``'未处理的差错笔数'``,`
    
    ``create_by` ``varchar``(64) ``DEFAULT` `NULL` `COMMENT ``'创建人'``,`
    
    ``create_gmt` datetime ``DEFAULT` `current_timestamp``() COMMENT ``'创建时间'``,`
    
    ``modified_by` ``varchar``(64) ``DEFAULT` `NULL` `COMMENT ``'更新人'``,`
    
    ``modified_gmt` datetime ``DEFAULT` `current_timestamp``() COMMENT ``'更新时间'`
    
    `) ENGINE=InnoDB ``DEFAULT` `CHARSET=utf8mb4 COMMENT=``'对账统计表(渠道下的各个商户每天对账记录)'``;`
    
    
    `CREATE` `TABLE` ``bill_mistake` (`
    
    ``id` ``int``(10) ``NOT` `NULL` `COMMENT ``'主键ID'``,`
    
    ``channel_type` ``varchar``(20) ``NOT` `NULL` `COMMENT ``'渠道类型: WX,HzBank,ALIPAY'``,`
    
    ``mch_id` ``varchar``(64) ``NOT` `NULL` `COMMENT ``'商户ID,对应表channel_account.mch_id'``,`
    
    ``batch_no` ``varchar``(64) ``NOT` `NULL` `COMMENT ``'对账批次号'``,`
    
    ``bill_type` ``varchar``(16) ``NOT` `NULL` `COMMENT ``'账单类型:PAY,REFUND'``,`
    
    ``bill_ymd` ``varchar``(8) ``NOT` `NULL` `COMMENT ``'账单日期,格式YYYYMMDD'``,`
    
    ``status` ``varchar``(16) ``NOT` `NULL` `DEFAULT` `'NOHANDLE'` `COMMENT ``'状态:HANDLED--已处理,NOHANDLE--未处理'``,`
    
    ``error_type` ``varchar``(64) ``NOT` `NULL` `COMMENT ``'差错类别:BANK_MISS--银行漏单;PLATFORM_MISS--平台漏单;PLATFORM_SHORT_STATUS_MISMATCH--平台短款,状态不符;PLATFORM_SHORT_CASH_MISMATCH--平台短款,金额不符;PLATFORM_OVER_CASH_MISMATCH--平台长款,金额不符;PLATFORM_OVER_STATUS_MISMATCH--平台长款,状态不符;FEE_MISMATCH--手续费不匹配'``,`
    
    ``handle_date` datetime ``DEFAULT` `NULL` `COMMENT ``'处理日期'``,`
    
    ``handle_user` ``varchar``(32) ``DEFAULT` `NULL` `COMMENT ``'处理人'``,`
    
    ``handle_result` ``varchar``(32) ``DEFAULT` `NULL` `COMMENT ``'处理结果'``,`
    
    ``handle_remark` ``varchar``(100) ``DEFAULT` `NULL` `COMMENT ``'处理备注'``,`
    
    ``trade_no` ``varchar``(64) ``DEFAULT` `NULL` `COMMENT ``'平台支付/退款流水号'``,`
    
    ``trade_ok_date` datetime ``DEFAULT` `NULL` `COMMENT ``'平台支付/退款成功时间'``,`
    
    ``trade_amt` ``int``(11) ``DEFAULT` `0 COMMENT ``'平台支付/退款金额(单位:分)'``,`
    
    ``fee` ``int``(10) ``DEFAULT` `0 COMMENT ``'手续费(单位:分)'``,`
    
    ``bank_trade_no` ``varchar``(64) ``DEFAULT` `NULL` `COMMENT ``'银行方交易订单号'``,`
    
    ``bank_out_trade_no` ``varchar``(64) ``DEFAULT` `NULL` `COMMENT ``'银行方外部流水号,即商户订单号'``,`
    
    ``bank_trade_time` datetime ``DEFAULT` `NULL` `COMMENT ``'银行方交易时间'``,`
    
    ``bank_amt` ``int``(11) ``DEFAULT` `0 COMMENT ``'银行方支付金额(单位:分)'``,`
    
    ``bank_fee` ``int``(10) ``DEFAULT` `0 COMMENT ``'银行方手续费(单位:分)'``,`
    
    ``create_by` ``varchar``(64) ``DEFAULT` `NULL` `COMMENT ``'创建人'``,`
    
    ``create_gmt` datetime ``DEFAULT` `current_timestamp``() COMMENT ``'创建时间'``,`
    
    ``modified_by` ``varchar``(64) ``DEFAULT` `NULL` `COMMENT ``'更新人'``,`
    
    ``modified_gmt` datetime ``DEFAULT` `current_timestamp``() COMMENT ``'更新时间'`
    
    `) ENGINE=InnoDB ``DEFAULT` `CHARSET=utf8mb4 COMMENT=``'账单差错表'``;`
    
    
    `CREATE` `TABLE` ``bill_check_pool` (`
    
    ``id` ``int``(10) ``NOT` `NULL` `COMMENT ``'主键ID'``,`
    
    ``channel_type` ``varchar``(20) ``NOT` `NULL` `COMMENT ``'渠道类型: WX,HzBank,ALIPAY'``,`
    
    ``mch_id` ``varchar``(64) ``NOT` `NULL` `COMMENT ``'商户ID,对应表channel_account.mch_id'``,`
    
    ``batch_no` ``varchar``(64) ``NOT` `NULL` `COMMENT ``'对账批次号'``,`
    
    ``bill_type` ``varchar``(16) ``NOT` `NULL` `COMMENT ``'账单类型:PAY,REFUND'``,`
    
    ``bill_ymd` ``varchar``(8) ``NOT` `NULL` `COMMENT ``'账单日期,格式YYYYMMDD'``,`
    
    ``trade_no` ``varchar``(64) ``NOT` `NULL` `COMMENT ``'平台支付/退款流水号'``,`
    
    ``out_trade_no` ``varchar``(64) ``NOT` `NULL` `COMMENT ``'第三方支付/退款流水号'``,`
    
    ``trade_ok_date` datetime ``NOT` `NULL` `COMMENT ``'平台支付/退款成功时间'``,`
    
    ``trade_amt` ``int``(11) ``NOT` `NULL` `COMMENT ``'交易金额, 支付或退款金额(单位:分)'``,`
    
    ``fee` ``int``(10) ``DEFAULT` `0 COMMENT ``'手续费(单位:分)'``,`
    
    ``deleted` ``smallint``(4) ``NOT` `NULL` `DEFAULT` `0 COMMENT ``'逻辑删除,默认0--正常;1--已删除'``,`
    
    ``create_by` ``varchar``(64) ``DEFAULT` `NULL` `COMMENT ``'创建人'``,`
    
    ``create_gmt` datetime ``DEFAULT` `current_timestamp``() COMMENT ``'创建时间'``,`
    
    ``modified_by` ``varchar``(64) ``DEFAULT` `NULL` `COMMENT ``'更新人'``,`
    
    ``modified_gmt` datetime ``DEFAULT` `current_timestamp``() COMMENT ``'更新时间'`
    
    `) ENGINE=InnoDB ``DEFAULT` `CHARSET=utf8mb4 COMMENT=``'对账缓冲池表(平台已支付的订单不存在于当日账单中)'``;`
    
    

    接口设计

    提供给业务系统查询交易结果接口

    定时任务

    不同的支付渠道,生成对账单的时间点不一。所以我们的定时任务需要分开执行。

    1)微信对账

    遍历所有的微信商户,逐个商户进行对账。

    2)杭州银行对账

    遍历所有的杭州银行商户,逐个进行对账。

    7.Deployment/部署

    8.Monitoring and Logging/监控和日志埋点

    打印各渠道发起对账的详情

    监控未对账或对账失败的情况

    9.Metrics/业务指标

    对账结果的统计(按渠道类型、按商户号、按对账结果)

    对账异常的统计(按渠道类型、按商户号)

    10.Timeline and Components/任务计划和组件

    xxl-job :

    • wxCheckBillHandler
    • hzBankCheckBillHandler

    附录

    关于支付,特别是本文说的对账,参考了龙果学院的源码,感谢!
    https://github.com/roncoo/roncoo-pay

    相关文章

      网友评论

          本文标题:多渠道的支付系统之对账模块(四)

          本文链接:https://www.haomeiwen.com/subject/fqpucdtx.html