PAYATHON 2026

支付宝 H5 调用 ap.tradePay 提示支付唤起方式不正确

支付阿杰

结论

这段 ap.tradePay 前端代码没有明显的语法问题。报错 商家支付唤起方式不正确,通常是因为传入的 tradeNO 不是为支付宝客户端 JSAPI 支付创建的交易号,或者交易使用的支付产品、应用身份与当前唤起方式不一致。

resultCode 为 6001,只表示弹窗出现后交易流程被取消,并不是最初的失败原因。排查重点应放在服务端创建交易的接口和参数上,不要把 6001 当成根因。

正确的调用流程

支付宝客户端内的 H5 页面使用 ap.tradePay 时,调用流程如下:

  1. H5 页面运行在支付宝客户端内。
  2. 服务端调用适合该场景的交易创建接口,例如 alipay.trade.create。
  3. 服务端完成签名,并向支付宝创建交易。
  4. 服务端取得支付宝返回的 trade_no。
  5. 服务端将 trade_no 返回给 H5。
  6. H5 将其作为 tradeNO 传给 ap.tradePay。

这里的 tradeNO 是支付宝交易号,通常来自接口响应中的 trade_no,不是商户订单号 out_trade_no。

常见错误原因

1. 把商户订单号当成 tradeNO

下面的传值方式是错误的:

ap.tradePay({
  tradeNO: outTradeNo
});

out_trade_no 是商户系统生成的订单号,而 tradeNO 必须是支付宝创建交易后返回的 trade_no。

正确写法是:

ap.tradePay({
  tradeNO: alipayTradeNo
});

2. 使用其他支付产品创建订单

如果服务端通过以下接口创建支付,再把相关订单号交给 ap.tradePay,可能会出现支付场景不匹配的问题:

  • alipay.trade.wap.pay:手机网站支付
  • alipay.trade.app.pay:App 支付
  • alipay.trade.precreate:扫码支付
  • 其他仅适用于特定收银台或扫码场景的接口

这些接口生成的交易不一定能通过 ap.tradePay 唤起。支付宝会校验订单对应的支付产品、创建方式和当前客户端场景。如果校验未通过,就可能提示 支付唤起方式不正确。

如果业务场景是在支付宝客户端内打开 H5,并通过 JSAPI 唤起支付,服务端需要按照对应的支付宝内支付方案创建交易。可以使用哪些接口、需要传入哪些参数,还要看商户签约的产品和应用配置。

3. 创建订单和调用支付时使用了不同的应用身份

还要确认以下信息一致:

  • 创建交易时使用的 app_id
  • 当前商户签约支付产品对应的应用
  • 商户账号及收款主体
  • 服务端签名使用的应用私钥
  • 支付宝公钥或证书配置
  • 创建订单时声明的支付场景

如果订单由应用 A 创建,却在应用 B 对应的业务环境中尝试唤起,支付宝也可能拒绝这次支付。

前端调用示例

发起支付前,应等待支付宝 JSAPI 初始化完成,并检查服务端是否返回了交易号:

<script src="https://appx/web-view.min.js"></script>
<script>
  document.addEventListener('AlipayJSBridgeReady', function () {
    // 此值必须由服务端创建交易后返回
    var tradeNO = '支付宝返回的 trade_no';

    if (!tradeNO) {
      ap.alert({
        title: '支付失败',
        content: '未取得支付宝交易号'
      });
      return;
    }

    ap.tradePay(
      {
        tradeNO: tradeNO
      },
      function (res) {
        console.log('tradePay result:', res);

        if (String(res.resultCode) === '9000') {
          console.log('客户端支付流程完成');
        } else {
          console.log('支付未完成,resultCode:', res.resultCode);
        }
      }
    );
  }, false);
</script>

如果已经正确加载 alipayjsapi.min.js,可以继续使用现有的引入方式。问题的关键不在脚本文件名,而在于调用时支付宝客户端的 JSBridge 是否就绪,以及 tradeNO 的来源是否正确。

服务端需要核对的内容

服务端创建交易后,应保留完整的支付宝响应日志,重点检查以下字段:

app_id
method
out_trade_no
trade_no
code
sub_code
sub_msg

接口调用成功并返回有效的 trade_no 后,才能将它传给前端:

{
  "code": "10000",
  "trade_no": "支付宝交易号",
  "out_trade_no": "商户订单号"
}

前端取值时要注意字段映射:

const tradeNO = response.trade_no;

不要写成:

const tradeNO = response.out_trade_no;

关于 6001

6001 通常表示用户取消了支付流程,或者客户端将流程判定为已取消。在这个场景中,支付宝先弹出 支付唤起方式不正确,用户关闭弹窗后,回调才返回 6001,所以它只是后续结果。

排查时应先确认:

  • 服务端通过哪个接口创建了交易;
  • tradeNO 是否确实是支付宝返回的 trade_no;
  • 创建交易所用的产品是否支持 ap.tradePay;
  • 创建交易和唤起支付是否使用同一个 app_id、商户和签约产品。

支付结果处理注意事项

即使 ap.tradePay 返回 9000,也不应只根据前端回调将订单直接标记为支付成功。客户端回调只能反映客户端支付流程的结果,最终状态应由服务端通过支付宝异步通知或主动查询交易来确认。

可以按以下流程处理:

前端收到 9000
    → 请求业务服务端查询订单
    → 服务端调用支付宝交易查询接口或检查异步通知
    → 确认交易状态后更新业务订单

当前问题的修复重点是调整服务端的下单方式,并向前端传递正确的支付宝 trade_no。如果已经确认 tradeNO 无误,再检查创建交易时使用的接口、app_id 和商户签约产品是否支持支付宝客户端内的 JSAPI 唤起场景。

备注:内容仅供参考。