|

Aimee

Write the Code. Change the World.

接到对账需求,先搞清楚"差"在哪里

· 分享镜

接到对账需求,先搞清楚"差"在哪里

内部系统显示今天收了 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

登录后参与评论。

还没有评论,来抢沙发吧。

回到顶部