接到对账需求,先搞清楚"差"在哪里
接到对账需求,先搞清楚"差"在哪里
内部系统显示今天收了 100 笔款、共 8762 元。支付宝账单一下载,99 笔,8682 元。
差一笔、差 80 元——钱去哪儿了?对账要解决的就是这件事,而且不只是找出差异,还要处理它。
为什么会对不上
每笔交易,平台系统和支付渠道各自记了一份账。正常情况下两边一致,但这些场景会导致出入:
- 平台有,渠道没有:平台记了扣款,但网络超时,渠道没收到请求——实际没扣款,平台账里却显示"支付中"
- 渠道有,平台没有:渠道扣款成功了,但回调没送到平台——用户钱出去了,平台以为没付
- 金额不一致:渠道记的是原币种,平台做了汇率转换,四舍五入规则不同导致差几分钱
- 时区问题:渠道用 UTC,平台用 UTC+8,日切时间点前后的交易被分在不同日期
对账的基本流程
第一步:拉账单
每天凌晨跑批,从渠道下载前一天的流水文件(微信/支付宝都提供账单 API),同时从平台数据库导出同一时间段内的支付记录。
# 拉微信账单(T-1 的所有交易)
wx_bill = wxpay.download_bill(bill_date="2024-01-14", bill_type="ALL")
# 拉平台记录(同一天)
platform_records = db.query(
"SELECT out_trade_no, amount, status, created_at FROM payment_record "
"WHERE DATE(created_at) = '2024-01-14'"
)
第二步:按 out_trade_no 做 full join 比对
用交易号做关联,逐条比较。
| 情况 | 描述 | 差错类型 |
|---|---|---|
| 平台有,渠道无 | 平台记了扣款,渠道没有该笔 | 长款(平台多记了) |
| 渠道有,平台无 | 渠道扣款了,平台无记录 | 短款(平台少记了) |
| 两边都有,金额不符 | 金额差异 | 差额 |
| 两边都有,金额一致 | ✅ 平账 | — |
第三步:生成差错表,人工或自动处置
差错处置:不同类型处理方式不同
长款(平台有,渠道无):大概率是请求没到渠道,平台主动查询渠道确认,如果渠道确实没有这笔,则把平台记录改为"支付失败",不需要退款(钱根本没扣)。
短款(渠道有,平台无):这是最危险的情况——用户钱出去了但平台没记录,订单没发货/没发券。处置是用渠道的交易号反查平台订单,补录支付成功状态,触发发货流程,同时发告警通知人工复核。
金额差异:差几分钱通常是精度问题,要看是系统性差异(每笔都差同样比例)还是偶发,前者要修代码,后者要人工核实。
实现细节:增量对账还是全量
日切对账通常是全量:把当天所有交易都比一遍。
但如果交易量大(比如几百万笔),全量对账耗时很长。可以用增量方案:只对"状态为 PENDING 超过 30 分钟"的记录做实时对账,其余走日切全量。
// 实时对账:针对长时间 PENDING 的单子
@Scheduled(fixedDelay = 600_000) // 每 10 分钟
public void realtimeReconcile() {
List<PaymentRecord> suspects = paymentDao.findLongPending(30);
for (PaymentRecord record : suspects) {
WxPayQueryResult result = wxPay.queryOrder(record.getOutTradeNo());
reconcileOne(record, result);
}
}
实时 + 日切组合,既能及时发现问题,又不遗漏。
最难处置的是短款
短款意味着用户钱出去了、平台没记录——订单状态不对,该发货的没发货。这类差错不能等,发现就要立刻处理:找到对应的渠道交易号,反查平台订单,补录状态,触发后续流程。
长款(平台多记了但渠道没扣)和金额差异通常可以进人工队列慢处理;短款必须优先,因为用户那边已经付了钱。
评论(0)
登录后参与评论。
还没有评论,来抢沙发吧。

