alipay.trade.query 使用 out_trade_no 查询提示订单不存在
支付老李
结论
这通常不代表订单真的不存在,更常见的原因是:查询订单时使用的应用或商户授权上下文,与创建交易时不一致。
trade_no 是支付宝生成的全局交易号,定位范围比较明确。out_trade_no 则是商家自行生成的订单号,查询时需要结合创建交易所用的 app_id、收款商户,以及服务商代调用场景中的 app_auth_token,才能准确定位订单。如果这些上下文不一致,支付宝可能返回:
ACQ.TRADE_NOT_EXIST
常见原因
可以重点检查以下情况:
- 创建交易和查询交易使用了不同的
app_id。 - 在服务商模式下,创建和查询使用了不同商户的
app_auth_token。 - 查询时使用的
out_trade_no与创建交易时传入的值不完全一致,例如:- 前后存在空格;
- 大小写不同;
- 查询时重新生成了订单号;
- 数据库保存或传输过程中发生截断;
- 混用了测试环境和生产环境。
- 同一个商户订单号曾用于不同的应用、收款主体或授权关系。
- 交易创建后立即发起查询,订单数据还没有完成同步。这种情况需要延迟重试才能确认,不能根据一次查询结果直接下结论。
如果使用 trade_no 可以稳定查到订单,说明支付宝交易已经存在。此时应优先检查 out_trade_no 和调用上下文,不要重新创建订单。
排查步骤
1. 核对创建交易时的原始参数
从实际请求日志或数据库中确认以下内容:
app_id
out_trade_no
seller_id
app_auth_token
支付宝网关环境
不要只看当前代码中的配置,应以创建这笔交易时实际发送的参数为准。
2. 核对查询请求
查询请求应满足:
查询 app_id = 创建交易时的 app_id
查询 app_auth_token = 创建交易时对应商户的 app_auth_token
查询环境 = 创建交易时使用的环境
查询 out_trade_no = 创建交易时原样传入的 out_trade_no
如果由服务商代商户调用,还要特别检查 app_auth_token 是否遗漏,或是否误用了其他商户的授权令牌。
3. 使用 trade_no 查询并回查商户订单号
先使用已知的 trade_no 查询订单。查询成功后,再检查响应中的 out_trade_no 是否与本地记录完全一致。
建议直接比较原始字符串,同时核对字符串长度,以便发现不可见空格等问题。
4. 检查配置切换
如果系统接入了多个应用、多个商户或多套环境,订单记录中应保存对应的支付配置标识。查询历史订单时,不能直接使用系统当前默认的 app_id 或授权令牌。
Java 示例
普通直连商户可以按商户订单号查询:
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
model.setOutTradeNo("ORDER_202609090001");
request.setBizModel(model);
AlipayTradeQueryResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
System.out.println("trade_no: " + response.getTradeNo());
System.out.println("out_trade_no: " + response.getOutTradeNo());
System.out.println("trade_status: " + response.getTradeStatus());
} else {
System.out.println("code: " + response.getCode());
System.out.println("sub_code: " + response.getSubCode());
System.out.println("sub_msg: " + response.getSubMsg());
}
服务商代商户查询时,需要传入创建交易时该商户对应的授权令牌:
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
model.setOutTradeNo("ORDER_202609090001");
request.setBizModel(model);
String appAuthToken = "创建该交易时对应商户的 app_auth_token";
AlipayTradeQueryResponse response =
alipayClient.execute(request, null, appAuthToken);
不同版本的支付宝 Java SDK,其 execute 重载形式可能略有不同,应以当前项目使用的 SDK 定义为准。具体使用哪个重载方法不是重点,查询和创建交易使用相同的应用及商户授权上下文才是关键。
注意事项
- 业务系统应持久化保存
out_trade_no,不要在查询时重新拼接或生成。 - 建议同时保存
trade_no、out_trade_no、支付应用标识和实际收款商户标识。 - 收到
ACQ.TRADE_NOT_EXIST后不要立即重新发起支付,以免产生重复交易。 - 多应用、多商户系统应根据原订单选择支付配置,不能统一使用当前默认配置查询。
- 如果已经确认参数和调用上下文完全一致,可以间隔数秒进行有限次数的重试。如果仍然失败,应保留创建请求、查询请求、响应内容和调用时间,交由支付宝技术支持进一步核查。
备注:内容仅供参考。
