为什么对账这么重要
支付系统的钱,微信说扣了、商户说没到、用户说付了三次——没有对账,这三方永远各说各话。对账就是每天把平台侧的交易流水与微信侧的资金流水逐笔比对,确认每一笔钱都名副其实。
对账不是可选项:通道掉单、回调丢失、重复支付、金额篡改,全靠对账兜底。上线第一周就把对账做起来,比上线三个月后再补要省十倍力气。
对账是支付系统最后的防线,其他环节都可以出错,对账不能缺席。
- 账单微信侧资金明细。。
- 流水平台侧交易明细。。
- 差异逐笔比对与处置。。
下载与解析对账单
微信支付对账单按日生成,可在商户平台下载,也支持通过接口拉取。对账单包含交易时间、商户单号、微信单号、金额、状态等字段,一天一文件,格式固定。
# 拉取对账单接口(示例:Node.js)
const res = await pay.downloadBill({ billDate: '20261028' });
const lines = res.data.split('\n').filter(Boolean);
// 首行为表头,末行为汇总行,中间为明细
for (const line of lines.slice(1, -1)) {
const [time, mchId, outTradeNo, wxNo, type, amount, status] = line.split(',');
// 进入逐笔比对流程
}下载后先校验文件签名与汇总行:总笔数、总金额与明细累加对不上,说明账单本身有问题,立即停止处理并告警。
逐笔核对与差错处理
以微信单号或商户单号为键做集合比对,得到三类结果:双方都有、只有我方、只有微信侧。只有一方的记录要进入差错池,人工或自动化规则处置。
常见差错:我方已扣款但微信无记录(疑似伪造或掉单)、微信有扣款但我方未入账(回调丢失,需要补单)、金额不一致(优先级最高,必须冻结处理)。每类差错定义超时时间,超时升级。
退款流程与安全
退款接口同样要过签名与证书校验。退款金额不能超过实收金额,退款原路返回,状态要可查询。设计上把退款做成独立领域:申请、受理、转账、完成、失败,每一步落库。
# 退款接口调用前必查
const order = await orderRepo.getByNo(outTradeNo);
if (!order || order.status !== 'SUCCESS') {
throw new BizError('订单不可退款');
}
if (refundAmount > order.paidAmount) {
throw new BizError('退款金额超限');
}
// 幂等:同一退款单号只允许一笔
await refundRepo.tryCreate(refundNo, order.id, refundAmount);退款权限要隔离:运营人员只能发起不能放行,财务复核后才能执行,系统日志全程留痕。
回调验签与幂等
支付与退款结果都通过异步回调通知。回调第一件事是验签,第二件事是幂等处理。验签不过直接拒绝;同一通知重复到达,只有第一次能改变状态。
// 回调处理:验签 + 幂等
if (!verifySign(req.body)) return res.status(400).end();
const { outTradeNo, returnCode } = req.body;
const ok = await tx(async () => {
const o = await orderRepo.lock(outTradeNo);
if (o.status === 'PAID') return false; // 已处理
await orderRepo.markPaid(o.id);
return true;
});
res.json(ok ? { code: 0 } : { code: 0 }); // 都返回成功,避免重发数据库唯一索引 + 事务是幂等最可靠的实现方式,单纯用内存标记在重启后就会失效。
风控与审计
对账体系之外还要布风控规则:单日退款率异常、退款金额等于整单、退款集中在深夜,都可能指向刷单或内部违规。规则命中进入人工审核,审核记录与退款单关联保存。
审计上做到「每笔退款可解释」:申请原因、审批人、操作时间、系统日志、对账结果五要素齐备。监管或投诉要求解释时,五分钟内能拉出完整链路。
小结与延伸阅读
对账与退款是支付闭环的收尾段:对账保证账目真实,退款保证流程可控,验签与幂等保证接口安全。把这四件事做成自动化、做成定时任务,支付系统才算真正闭环。建议从每日对账脚本起步,逐步补齐差错处理与风控规则。
- 支付接入流程读《微信支付接入全流程指南》。
- 订单体系读《小程序支付与订单体系实战》。
- 支付分与信用读《微信支付分实战》。