对账功能是支付平台的核心功能之一,由于各种原因,支付平台的支付账单信息和银行的支付账单信息可能存在不一致的情况。对账的目的就是为了实现账单的最终一致,具体过程包括找出存在不一致的地方,找到具体的原因,执行相应的处理,确认最终一致,执行相关的统计。
支付平台一般都集合了多种支付渠道,典型的就是集中各个银行以及第三方机构的支付渠道(比如微信、支付宝、云闪付等)。
除了正常的支付交易以外,还存在退款交易,对账时也需要同时处理,有的银行将退款和支付放在一个对账文件中,也有的支付机构将退款和正常交易放在单独的文件中的。
1. 对账中存在的差错类型包括:
- 平台漏单,也就是银行有账单,平台没有对应的账单信息,具体原因需要具体分析;
- 银行漏单,也就是平台有账单,银行没有账单,具体原因需要具体分析;
- 金额不一致,具体又包括银行金额多余平台金额,平台金额多余银行金额;
- 状态不一致,比如银行是支付成功,平台是支付中;
- 支付渠道不一致,比如银行记录是微信支付,平台记录是支付宝支付;
- 账单日期不一致,比如银行记录的是一天,平台记录的是另外一天;
- 商户编号不一致,比如A商户的订单,记录到B商户了;
2. 对账的总体流程
- 下载对账文件,一般需要从第三方支付系统下载对账文件到本地;
- 解析并导入对账文件,需要对下载的文件进行解析,并按照统一的格式导入到数据库中;
- 准备对账数据,比如需要执行某一日的对账,就应分别从平台账单和银行账单提取对应日期的账单,并添加到对账表中;
- 首次对账并记录差错,根据对账表中的账单数据,找出差错并记录差错;
- 进行自动差错处理,对能够处理的差错执行自动处理,比如平台账单为支付中,银行账单中该账单为支付成功,此时将平台账单更新为支付成功;需要特别说明的是,需要同时更新平台账单表中的账单状态,也需要更新对账表中的账单状态;
- 再次对账并统计,本次对账是确认是否还存在差错,并对账单情况和差错情况进行统计并记录统计结果,统计内容包括:还存在的差错类型和数量,平台账单的数量和金额,银行账单的数量和金额等;
3. 对账处理的技术优化
如果对账处理的数量量大,比如每天需要处理1000+个商户以及100万+的账单对账,这将是一个比较费时的处理过程。由于各个第三方支付系统提供对账文件的时间也存在差异,存在处理失败以及需要重复处理的情况,所有提前考虑好这些场景的处理,有利于提高整体效率。
- 对账处理过程中,记录好对账日志,尤其是差错日志以及差错处理日志,以便在必要时进行查询;
- 按天对账时,每商户每天的对账形成一个批次,记录对账批次处理的中间状态,比如某个批次对账过程中,账单下载成功了,在后续处理过程中出现了异常,导致本次对账处理失败,下次对账的时候,就不必重复执行下载对账文件了;
- 能够批量处理的尽量批量处理,毕竟批量处理的效率比单个记录逐个处理效率高不少,尤其是在数据量大的时候;
- 对账过程中,记录对账进度信息,以便能够及时了解当前处理的整体进度,比如包括当日对账需要执行的商户数,已经执行完成的商户数,剩余的商户数,执行成功的商户数,有差错的商户数以及对账的开始时间和结束时间等;
4. 对账表结构参考
CREATE TABLE `bank_biz_check_bill` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '添加流水号',
`bill_no` varchar(64) CHARACTER SET utf8 DEFAULT NULL COMMENT '账单编号',
`plat_merchant_no` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '平台商户编号',
`plat_pay_channel` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '平台支付渠道',
`plat_trans_type` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '平台交易类型',
`plat_trans_datetime` datetime DEFAULT NULL COMMENT '平台交易时间',
`plat_trans_amount` bigint(15) DEFAULT NULL COMMENT '交易金额(分为单位)',
`plat_status` varchar(10) CHARACTER SET utf8 DEFAULT NULL COMMENT '状态',
`bank_type` varchar(20) CHARACTER SET utf8 DEFAULT NULL COMMENT '银行类型',
`bank_merchant_no` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '银行商户编号',
`bank_merchant_acct` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '银行商户账户',
`bank_pay_channel` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '银行支付渠道',
`bank_trans_type` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '银行交易类型',
`bank_fee` double(15,2) DEFAULT NULL COMMENT '银行手续费',
`bank_trans_datetime` datetime DEFAULT NULL COMMENT '银行交易时间',
`bank_trans_amount` bigint(15) DEFAULT NULL COMMENT '银行交易金额(分为单位)',
`bank_account_date` datetime DEFAULT NULL COMMENT '银行账单日期',
`bank_status` varchar(10) CHARACTER SET utf8 DEFAULT NULL COMMENT '银行状态',
PRIMARY KEY (`id`),
UNIQUE KEY `pkindex` (`bill_no`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT='对账表';