支付宝异步通知接收:success 响应、RSA2 验签与 8 次重试节奏
依据支付宝官方文档《异步通知说明》《如何接收异步通知》。
触发机制
一笔交易支付完成后,支付宝会按商户下单时传入的 notify_url 发 POST 请求,推送交易变更结果。没有设置 notify_url 就不会触发。
除支付结果外,以下几类通知也走同一套接收方式:
- 应用网关异步地址:如商家扣款主动解约;
- 蚂蚁消息订阅 HTTP 方式:如单笔转账、分账。
触发条件有限制:只有该笔交易已经存在于支付宝交易管理,并且发生状态变更时才发通知。WAIT_BUYER_PAY(等待买家付款)默认不发。
第一次发生交易状态变化时,页面跳转的同步处理结果(GET)与服务器异步通知(POST)会同时触发:一个落在浏览器跳转后的页面,一个落到 notify_url。
接收要求
承载异步通知的地址必须:
- 支持 POST;
- 外网可访问;
- 不能是重定向地址;
- 把
success这 7 个英文字符作为唯一响应内容,不能带空格、HTML 标签、框架抛出的异常输出。
程序执行完在响应体输出 success,表示消息获取成功;响应体不是 success 时,支付宝会反复重发,直到超过 24 小时 22 分钟。正常情况下,25 小时内完成 8 次通知,间隔为 4m、10m、10m、1h、2h、6h、15h。
处理过程中不能做页面跳转。一旦跳转,支付宝接收不到 success,会判定为"运行出现异常"并重发。同时注意:该页面取不到 cookies/session,不能依赖会话状态。
异步通知的实际定位是兜底:防止订单丢失。页面跳转的同步通知没有处理订单更新时,由异步通知补上。
notify_id 与成功标志
每条通知携带 notify_id。当商户处理完并打印 success 后,该 notify_id 才失效。同一条通知如果因为未输出 success 被重复推送,notify_id 不会变化。
trade_status 四值与付款判定
trade_status | 含义 |
|---|---|
WAIT_BUYER_PAY | 交易创建,等待买家付款 |
TRADE_CLOSED | 未付款超时关闭;或支付完成后全额退款 |
TRADE_SUCCESS | 交易支付成功 |
TRADE_FINISHED | 交易结束,不可退款 |
- 默认开启通知的类型为
TRADE_CLOSED、TRADE_FINISHED、TRADE_SUCCESS;WAIT_BUYER_PAY默认关闭。 - 只有
TRADE_SUCCESS和TRADE_FINISHED才代表买家已付款成功,其他状态不能作为入账依据。 - 部分退款也会触发
TRADE_SUCCESS异步通知。业务上要区分这代表"首笔支付成功"还是"退款后的通知",不能拿状态值直接覆盖订单支付状态。
RSA2 验签流程
收到异步通知后先验签,防止报文被篡改并确认报文来自支付宝:
- 取出异步通知的 POST 参数。
- 去掉
sign、sign_type后,其余返回参数都是待验签参数。对剩余参数做 URLDecode,按字典序排序并拼接,得到待签名字符串。
特殊场景:生活号异步通知组成的待验签串,需要保留sign_type。 - 将
sign参数做 base64 解码,得到字节串。 - 用支付宝公钥对待签名字符串和 base64 解码后的
sign做 RSA 验签。 - 验签通过后,还必须严格校验通知数据正确性。任一环节不通过就按异常通知忽略。
验签通过后再进入业务处理,并过滤重复通知数据。最终只有 TRADE_SUCCESS / TRADE_FINISHED 被当作付款成功。
返回 success / fail 的时间点
响应语义如下:
- 输出
success:支付宝认为消息获取成功,停止通知; - 输出
fail:支付宝认为消息获取失败,会再次发送。
所以推荐先验签:验签成功输出 success;验签失败输出 fail,让支付宝按重试节奏重新推送。
SDK 调用示例
Java:
AlipaySignature.rsaCheckV1(params, alipayPublicKey, charset, "RSA2");
// 公钥证书模式:
AlipaySignature.rsaCertCheckV1(params, alipayPublicCertPath, charset, sign_type);
PHP:
$aop->rsaCheckV1($_POST, NULL, "RSA2");
不用 SDK 手动验签:把返回字符串按 & 拆分,再按 = 拆成 key/value 放进 LinkedHashMap,取出 sign,最后调用:
rsaCheckV1(map, publicKey, charset, sign_type);
对接排查点
对接时把文档列出的这几点确认清楚:
- 收不到异步通知:
notify_url未设置、地址不可达、被重定向、返回内容不是success; - 退款是否触发通知;
- 交易关闭接口是否触发通知;
- 异步通知如何区分全额退款与订单超时关闭;
- 如何判断通知对应哪一笔退款交易。
订单更新约定
notify_url 收到的参数要在商户 app 的服务端处理,不能依赖页面跳转的同步返回直接修改订单状态。官方给出的原则是:以后台异步通知为主,配合主动查询兜底。电脑网站支付 demo 可以作为异步通知接收的通用参考。