PAYATHON 2026

支付宝商圈交易成功信息订阅为何未收到通知?

支付老李

结论

收不到“交易成功信息订阅”通知,通常不代表支付接口有问题,更可能是下面某个环节没有满足要求:

  • 测试交易不属于已接入的商圈、商户或门店;
  • 交易方式或状态不符合“支付即积分”的通知条件;
  • 消息订阅没有启用,或者配置到了错误的支付宝应用或商圈环境;
  • 应用授权、商户绑定或门店映射关系不完整;
  • 支付宝无法访问通知地址,或者接收端在验签、解析、应答时发生错误;
  • 使用了沙箱、测试账号或普通支付交易,而这些场景不会产生商圈订阅消息。

排查时,先确认这笔交易是否应该触发通知,再确认支付宝有没有发送,以及接收端是否正确处理。

一、确认交易是否满足触发条件

先核对交易主体和支付渠道:

  1. 收款商户是否已经加入目标商圈。
  2. 支付门店是否已经绑定商圈内的对应门店。
  3. 商户、门店和支付宝应用之间的映射是否正确。
  4. 交易是否通过“综合体支付即积分”支持的支付链路完成。
  5. 交易最终状态是否为成功,而不是处理中、关闭、撤销或退款。
  6. 测试交易使用的应用、商户和环境是否与订阅配置一致。

普通支付成功不一定会触发商圈交易成功订阅。比如,使用未加入商圈的门店收款码完成支付,即使交易成功,也可能不会进入该商圈的积分交易链路。

如果使用沙箱或内部测试交易,还要确认当前测试环境是否支持这项订阅能力。生产环境会产生商圈消息,不代表沙箱也一定会产生。

二、检查订阅和应用配置

进入支付宝开放平台和商圈相关控制台,逐项确认:

  • 是否已经开通并启用交易成功信息订阅;
  • 订阅是否配置在实际发起交易或承接商圈能力的应用下;
  • 当前应用的 app_id 是否与生产配置一致;
  • 服务商代商户接入时,商户是否已经完成授权;
  • 授权是否仍然有效,相关权限是否已被取消;
  • 商圈、商户和门店的签约或审核状态是否正常;
  • 通知地址是否已经保存并正式生效。

多应用接入时很容易出现配置错位。例如,订阅配置在 A 应用下,实际交易却由 B 应用或另一套服务商关系产生。排查时要以具体交易对应的应用、商户和门店为准,不能只确认账号下“存在一条订阅配置”。

三、检查通知地址的可达性

通知地址一般需要满足这些条件:

  • 使用公网可以访问的 HTTPS 地址;
  • 域名解析正常,证书有效,证书链完整;
  • 不依赖登录状态、Cookie 或人工验证码;
  • 不会被防火墙、WAF、网关白名单或访问频率限制拦截;
  • 接口支持支付宝使用的 HTTP 方法和内容类型;
  • 路由不会发生异常重定向;
  • 服务端能在平台规定的时间内返回正确的确认内容。

可以从公网环境测试基础连通性:

curl -i -X POST 'https://example.com/alipay/business-circle/notify' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data 'probe=1'

这个测试只能说明接口可以访问,不能证明支付宝一定会发送通知,也不能代替签名校验。如果接口返回 401、403、404、405、5xx,或者长时间没有响应,应先处理网关或服务端问题。

四、确认请求是否到达接收端

建议同时查询负载均衡、API 网关和应用服务的日志,并以测试交易时间为中心,检索前后几分钟的记录。

接收入口可以先记录必要的诊断信息:

@PostMapping("/alipay/business-circle/notify")
public ResponseEntity<String> receive(
        HttpServletRequest request,
        @RequestParam Map<String, String> params) {

    String tradeNo = params.get("trade_no");
    String notifyId = params.get("notify_id");

    log.info(
        "Alipay notification received, tradeNo={}, notifyId={}, remoteAddr={}",
        tradeNo,
        notifyId,
        request.getRemoteAddr()
    );

    // 后续执行验签、幂等校验和业务处理。
    return ResponseEntity.ok("success");
}

字段名称和成功应答内容必须以当前订阅能力的官方协议为准。商圈信息订阅与普通支付异步通知的报文结构不一定完全相同,因此不能在未核对协议的情况下固定读取 trade_no,也不能直接认定成功应答一定是 success。

如果网关有访问记录,但应用没有日志,需要检查反向代理路由、HTTP 方法和请求体大小限制。如果负载均衡、网关和应用都没有记录,应优先检查订阅关系、交易触发条件和平台侧的发送记录。

五、检查验签和报文解析

如果通知采用支付宝开放平台的 RSA2 签名机制,可以使用官方 SDK 验签。下面的示例适用于表单参数形式的通知:

Map<String, String> params = new HashMap<>();

request.getParameterMap().forEach((name, values) -> {
    if (values != null && values.length > 0) {
        params.put(name, String.join(",", values));
    }
});

boolean verified = AlipaySignature.rsaCheckV1(
    params,
    alipayPublicKey,
    "UTF-8",
    "RSA2"
);

if (!verified) {
    throw new SecurityException("Alipay notification signature verification failed");
}

验签失败时,重点检查以下事项:

  • 验签要使用支付宝公钥,不能误用应用公钥;
  • 公钥必须属于当前应用和当前环境;
  • sign_type、字符集和 SDK 配置要与实际报文一致;
  • 验签前不能修改参数值、字符编码或空格;
  • 表单通知和 JSON 消息的取参方式不同;
  • 如果平台使用证书模式,应按照证书模式初始化 SDK,不能直接套用公钥字符串示例。

如果具体消息采用其他签名或加密协议,应严格按照该订阅接口的文档处理。

六、正确处理应答和重试

出现以下情况时,支付宝可能会判定通知失败:

  • 接口超时;
  • 返回非 2xx 状态码;
  • 返回内容不符合协议;
  • 服务端完成业务处理后才应答,导致响应时间过长;
  • 应用抛出异常,网关因此返回 5xx。

建议按以下顺序处理通知:

  1. 读取并保存原始通知。
  2. 完成验签和必要的合法性校验。
  3. 根据通知标识或交易号执行幂等判断。
  4. 将消息写入本地队列或可靠存储。
  5. 尽快返回协议要求的成功响应。
  6. 异步处理积分计算等耗时业务。

首次通知失败不代表后续不会重试。接收逻辑必须支持重复通知,并确保同一笔交易不会重复发放积分。

七、最快的定位方法

选择一笔触发条件明确的测试交易,记录以下信息:

  • 支付宝交易号;
  • 商户订单号;
  • app_id;
  • 收款商户 PID;
  • 商圈标识;
  • 门店标识;
  • 支付完成时间;
  • 通知地址;
  • 接收端日志和 HTTP 状态码。

再根据结果判断问题所在:

  • 平台没有发送记录时,重点检查交易触发条件、订阅开通状态、应用授权以及商圈和门店的绑定关系。
  • 平台显示发送失败时,根据响应码检查域名、证书、网关、超时和返回内容。
  • 平台显示发送成功,但业务没有处理时,检查验签、报文解析、幂等逻辑、数据库事务和异步队列。
  • 接收端完全没有访问记录时,检查通知地址是否配置正确,以及请求是否被 CDN、WAF 或防火墙拦截。

如果控制台没有提供消息发送记录,可以携带上述信息向支付宝技术支持查询。只提供“没有收到通知”通常不足以定位问题。交易号、应用、商户、门店和准确时间是排查时最重要的信息。

备注:内容仅供参考。