2. 支付基础概念

在企业支付系统中,业务同学最常问的一句话是:“这笔款到底付出去没有?”要回答这个问题,不能只看“付款”这一个动作,而要理解一条完整的支付链路:付款发起 → 渠道受理 → 回执返回 → 状态机流转 → 异步通知 → 对账核销。本节把这些基础术语放回真实业务场景中,帮助大家建立统一的语言体系。

一、核心术语与它们的分工

付款是业务系统向支付渠道发起的一笔资金划出请求,它描述的是“意图”。例如企业向供应商打款 10 万元,业务系统生成付款单并调用渠道接口,此时付款单状态是“处理中”,并不代表钱已经到账。

回执是渠道对付款请求的应答凭证,分为同步回执和异步回执。同步回执通常只表示“请求已受理”,例如返回 code=SUCCESS、channelOrderNo=202405200001;异步回执才是最终结果,例如“付款成功”或“付款失败”。很多线上事故的根因,就是把同步回执误当成最终结果。

状态机是付款单在生命周期内允许的状态集合与迁移规则。它约束了“哪些状态可以跳到哪些状态”,防止出现“已成功又变失败”这类脏数据。

异步通知是渠道在结果确定后,主动回调企业系统的机制。它解决的是“同步接口无法立即返回终态”的问题,是支付系统可靠性的关键。

对账是企业账务系统与渠道账单的逐笔核对,用于发现“状态不一致、金额不一致、单边账”等问题,是资金安全的最后一道防线。

一句话记忆:付款是“我说要付”,回执是“渠道说收到/结果”,状态机是“我内部怎么记”,异步通知是“渠道主动告诉我”,对账是“我和渠道对答案”。

二、状态机:付款单的“合法人生轨迹”

一个典型的付款单状态机包含以下状态:INIT(已创建)、PROCESSING(处理中)、SUCCESS(成功)、FAIL(失败)、UNKNOWN(结果未知)、CLOSED(已关闭)。其中 UNKNOWN 是最容易被忽视、也最危险的状态:它表示“请求已发出,但没拿到确定结果”,必须通过查询或对账来收敛。

状态迁移必须遵守规则,例如:INIT → PROCESSING 合法;PROCESSING → SUCCESS 合法;SUCCESS → FAIL 非法;UNKNOWN → SUCCESS/FAIL 合法。任何非法迁移都应被拦截并告警。

付款单状态机与外部信号关系 INIT 已创建 PROCESSING 处理中 SUCCESS 成功 FAIL 失败 UNKNOWN 结果未知 对账核销 发起付款 同步回执 异步通知 账单核对

三、异步通知与对账:两条收敛路径

当付款进入 PROCESSING 或 UNKNOWN 后,系统需要两条路径把状态收敛到终态:

  1. 异步通知路径:渠道回调企业接口,企业验签、幂等处理后更新状态。若回调丢失,状态会长期停留在处理中。
  2. 主动查询与对账路径:定时任务查询渠道订单状态,或下载渠道对账文件逐笔核对,修正不一致数据。

两条路径必须同时存在。只依赖异步通知,会因网络抖动、回调地址变更而丢单;只依赖对账,则时效性差,用户等待时间长。生产实践中,通常“异步通知优先、查询兜底、对账最终校准”。

异步通知处理三要素:验签(确认来源可信)、幂等(同一笔通知重复到达只处理一次)、终态保护(已成功的单子不再被失败通知覆盖)。

四、典型业务场景与误区复盘

场景:某企业向供应商付款,渠道同步返回“受理成功”,业务系统立即把付款单置为“成功”并通知财务放款。两小时后渠道异步通知“付款失败”,系统却因终态保护拒绝更新,导致账实不符。

复盘要点如下:

误区 后果 正确做法
把同步回执当终态 提前放款、资金损失 同步仅置为处理中,等待异步或查询结果
无 UNKNOWN 状态 超时后状态悬空 超时置为 UNKNOWN,由查询/对账收敛
异步通知不做幂等 重复入账、重复放款 以渠道流水号做唯一键,重复通知直接返回成功
不做对账 单边账长期潜伏 每日下载渠道账单,逐笔核对并生成差异工单

再看一段典型的异步通知日志,帮助大家建立“看日志定位状态”的直觉:

2024-05-20 14:03:11 INFO  pay.notify recv channel=ALIPAY outTradeNo=P20240520001
2024-05-20 14:03:11 INFO  pay.notify verifySign result=true
2024-05-20 14:03:11 INFO  pay.notify idempotent check: first time, proceed
2024-05-20 14:03:11 INFO  pay.notify status=SUCCESS amount=100000.00
2024-05-20 14:03:11 INFO  pay.state PROCESSING -> SUCCESS, operator=notify
2024-05-20 14:03:11 INFO  pay.notify resp code=SUCCESS

状态机是“内部纪律”,回执和异步通知是“外部输入”,对账是“最终裁判”。三者缺一不可。任何绕过状态机直接改库的行为,都会在后续对账中暴露为差异。