支付宝转账异步通知没到:从应用网关订阅到 uni.transfer / multistep 状态判定
转账类接口的坑集中在两处:钱扣了但状态不知道,或者通知没来只能靠轮询。下面按单笔转账 alipay.fund.trans.uni.transfer 和多步转账 alipay.fund.trans.multistep.transfer 两条线,把异步通知的链路、配置和收不到通知时的排查路径理清楚。
文档来源:
一、单笔转账:消息走应用网关,不是 notify_url
转账到支付宝账户的异步通知通过应用网关地址发送蚂蚁消息,而不是接口里的 notify_url。能发蚂蚁消息的 API 是 alipay.fund.trans.uni.transfer(单笔转账接口)。
配置三步:
- 在应用设置里配置应用网关地址。一个应用只能配置一个,必须以
https://或http://开头。 - 应用详情页 →「消息服务」→ From蚂蚁 标签,订阅
alipay.fund.trans.order.changed(转账单据状态变更通知)。 - 在服务端处理 From蚂蚁 消息。
触发条件要注意:转账到支付宝账户只有 SUCCESS 状态会触发异步通知。WAIT_PAY 和 CLOSED 是现金红包含有的转账状态,不要指望这两个状态给你推消息。
二、收到通知先验签,响应值只有两种
商户收到通知后必须验签,验证 sign。公钥证书模式下:
- Java:
rsaCertCheckV1 - .NET:
RSACertCheckV1
返回值的语义很关键:
| 响应 | 含义 | 支付宝行为 |
|---|---|---|
fail | 消息获取失败 | 重试 |
success | 消息获取成功 | 不重试 |
也就是说,验签失败或业务处理抛异常时不要硬返回 success,否则这条消息不会再推第二次;反过来,处理成功却返回 fail,会等来重复通知,业务侧要做幂等。
三、收不到通知:先分清是哪一类
排查前先归类,三类原因的处理方向完全不同:
- 支付宝系统未发送:异步设置方式有误、异步地址有误、未满足触发条件。
- 系统发送了但商户没收到:网络、网关、服务端问题。
- 通知发送成功但以为没收到:地址配到了老环境,或验签失败导致数据没落库。
异步地址的三种配置方式
不同产品用不同入口,配错地方等于没配:
- 接口 API 设置
notify_url:APP 支付、电脑网站支付等。 - 应用网关设置异步地址:商家扣款主动解约等。
- 订阅消息 API:单笔转账到支付宝账户、商家分账等。
From蚂蚁 消息有个前置条件:必须先在应用功能列表添加对应功能,再在 From 平台订阅。少了前一步,订阅了也收不到。
HTTP 接入的硬性要求
notify_url/ 应用网关必须以http(s)开头,支持 IP,推荐用域名。- 不能带
?id=123这类自定义参数。 - 不能以
http://localhost开头,必须外网可达。 - 必须能接收 POST 请求。
用异步通知工具看商户响应的 HTTP 状态码
| 状态码 | 判断 |
|---|---|
http 0 | 服务连接或解析问题 |
3xx | 被重定向 |
4xx | 地址不存在或无法访问 |
5xx | 服务端异常 |
200 | 已收到,需检查是否配置到老地址,或验签失败导致数据未同步 |
一个特殊通知
收单退款冲退完成通知 alipay.trade.refund.depositback.completed,需要在退款接口传 query_options=deposit_back_info 才会推。
四、多步转账:创建、查询与通知订阅
多步转账用 alipay.fund.trans.multistep.transfer(多步转账创建并支付),受理结果用 alipay.fund.trans.multistep.query 查询。
重试策略按返回码区分:
- 返回系统异常或未明确错误码:保持原始请求信息重试。
- 返回
UNIQUE_VIOLATION_EXCEPTION:表示批次已创建,不要再重试创建,转去查询受理结果,避免重复支付。
查询参数 out_biz_no、order_id 不可同时为空,优先级 order_id > out_biz_no。
状态判定上有个时间窗:建议以转账调用返回后 3~5 分钟的查询结果为准,避开极端情况造成的资损。
多步转账的异步通知走 alipay.fund.trans.multistep.notify,触发条件包含 status=SUCCESS、FAIL、DEALING、REFUND——注意它比单笔转账宽,FAIL 和 DEALING 也会推。
订阅这里有个容易踩的组合问题:
- 只订阅了单笔转账消息接口
alipay.fund.trans.order.changed、没订阅multistep.notify:单笔转账消息接口会收到多条转账消息。 - 两个都订阅:两个都会发。
也就是说,消息接口和业务接口不是一一对应的,处理端要按消息内容判断,而不是按订阅关系假设。
另外,多步转账文档要求商户服务端请求测试必须使用公钥证书方式。
五、排错顺序
按这个顺序走,能砍掉大部分无效排查:
- 确认业务是否满足触发条件。单笔转账只有
SUCCESS才推;多步转账看status是否落在SUCCESS/FAIL/DEALING/REFUND。 - 确认订阅做全了:应用功能列表已添加对应功能 → From平台已订阅 → 应用网关地址已配置(一个应用只有一个)。
- 确认地址本身合规:
http(s)开头、无自定义参数、非 localhost、外网可达、POST 接收。 - 用异步通知工具看商户侧返回的 HTTP 状态码,按上表定位是连接、重定向、路由还是服务端异常。
- 状态码 200 但仍然「没收到」,回头查两件事:地址是不是指到了老环境;验签是否失败导致数据没落库。
- 通知链路都正常、只是状态没更新,用查询接口兜底:单笔走转账查询,多步走
alipay.fund.trans.multistep.query,并注意 3~5 分钟的时间窗。
通知是主路径,查询是兜底。两条都通,转账状态才算可控。