PAYATHON 2026

AlipayJSBridge tradePay 支付成功后如何跳转自定义页面

支付老李

结论

tradePay 的回调会在支付宝收银台结束并返回当前 WebView 后执行。如果支付完成后直接进入支付宝官方完成页,通常有两种原因:当前订单采用了“页面跳转支付”流程,或者服务端创建订单时没有配置商户返回地址。由于原页面没有恢复,代码自然不会执行到 result.resultCode == "9000"。

首先要确定使用哪种支付模式:

  • 使用 AlipayJSBridge.call("tradePay"):服务端创建支持 JSAPI 支付的订单,只向前端返回支付宝交易号 trade_no。支付期间保留原页面,等待 Bridge 回调。
  • 使用手机网站支付跳转流程:服务端调用 alipay.trade.wap.pay 并配置 return_url。支付完成后,支付宝跳转到该地址,不依赖 tradePay 回调。

“提交 WAP 支付表单”和“调用 tradePay”是两套流程,不要混用。

为什么没有进入回调

9000 的判断通常没有问题,更常见的是以下几种情况。

1. 使用了页面跳转型订单

如果后端通过 alipay.trade.wap.pay 生成支付表单或支付链接,再由页面提交到支付宝,当前 WebView 会随之跳转。支付完成后,支付宝根据 return_url 返回。没有设置有效的 return_url 时,页面可能停留在支付宝默认完成页。

此时,原页面的 JavaScript 上下文可能已经销毁,之前注册的 tradePay 回调无法继续执行。

2. tradeNO 不是正确的支付宝交易号

tradePay 中的 tradeNO 必须是支付宝侧交易号,也就是接口返回的 trade_no,不能使用商户订单号 out_trade_no。

{
  tradeNO: "支付宝返回的 trade_no"
}

如果后端返回的是支付表单、支付 URL 或商户订单号,就需要调整服务端的下单逻辑。

3. 调用时 Bridge 尚未初始化

必须等到 AlipayJSBridgeReady 触发后再调用。否则在某些页面加载时序下,调用和回调可能出现异常。

4. 支付页面没有返回原 WebView

即使支付已经成功,只要收银台随后跳转到了其他页面,原页面就收不到 Bridge 回调。只有回调真正执行后,判断 resultCode 才有意义。

使用 tradePay 的代码调整

可以封装 Bridge 初始化逻辑,并打印完整结果,确认实际返回的内容:

function ready(callback) {
  if (window.AlipayJSBridge) {
    callback();
    return;
  }

  document.addEventListener(
    "AlipayJSBridgeReady",
    callback,
    false
  );
}

function startPay(tradeNo) {
  ready(function () {
    AlipayJSBridge.call(
      "tradePay",
      {
        tradeNO: tradeNo
      },
      async function (result) {
        console.log("tradePay result:", result);

        const resultCode = String(
          result && (result.resultCode || result.result_code || "")
        );

        if (resultCode === "9000") {
          // 建议先请求服务端确认订单状态,再展示支付成功页面
          const url =
            `/pages/property/payment/paySuccess` +
            `?merchantName=${encodeURIComponent(_this.merchantName)}` +
            `&money=${encodeURIComponent(_this.money)}`;

          uni.redirectTo({
            url,
            fail(error) {
              console.error("redirectTo failed:", error);
            }
          });
        } else if (resultCode === "6001") {
          // 用户取消支付
          console.log("用户取消支付");
        } else {
          // 支付失败、处理中或未知状态
          console.log("支付未确认成功:", result);
        }
      }
    );
  });
}

服务端需要返回支付宝创建订单接口生成的 trade_no:

{
  "outTradeNo": "商户订单号",
  "tradeNo": "支付宝交易号"
}

前端调用时传入:

startPay(response.tradeNo);

具体使用哪个支付宝下单接口,要根据商户已签约的支付产品和当前接入方案确定,并以对应的支付宝开放平台文档为准。不能直接把 alipay.trade.wap.pay 返回的表单内容作为 tradeNO 使用。

如果继续采用手机网站支付

如果业务使用的是 alipay.trade.wap.pay,就不应依赖 tradePay 回调完成页面跳转,而应在服务端请求中配置 return_url:

https://example.com/payment/return

支付完成后,支付宝会跳转到该地址。返回页可以根据商户订单号向服务端查询订单状态,然后跳转到自定义成功页面,或者直接展示支付结果。

服务端还应配置 notify_url,用于接收支付宝的异步通知:

https://api.example.com/alipay/notify

三者的用途不同:

  • return_url:指定用户支付后浏览器返回的页面。
  • notify_url:接收支付宝通知,供商户服务端更新订单状态。
  • tradePay 回调:当前 WebView 恢复后,向前端返回交互结果。

只配置 notify_url 无法控制页面跳转,只配置 return_url 也不能替代服务端验签和订单确认。

还需要检查的配置

逐项确认以下配置与实际接入的支付产品一致:

  • 页面运行在支付宝客户端的内置浏览器中。
  • 下单所用的应用、商户身份和签约支付产品相互匹配。
  • tradeNO 来自支付宝返回的 trade_no。
  • 支付页面域名、应用授权和相关安全域名已按当前产品要求配置。
  • 调用 tradePay 后,没有立即提交表单、执行 location.href 或触发其他页面跳转。
  • uni.redirectTo 的目标不是 tabBar 页面。如果目标是 tabBar 页面,应改用 uni.switchTab。
  • 如果代码实际运行在普通 H5 页面,而不是 uni-app 页面,应使用路由框架或 location.replace() 跳转。

不要只根据 9000 发货

resultCode === "9000" 只能用于前端交互提示,不能作为最终支付凭证。打开支付成功页之前,最好先向业务服务端查询订单状态。服务端应对支付宝异步通知进行验签,必要时主动调用交易查询接口确认支付结果。

建议采用以下流程:

前端调用 tradePay
        ↓
收到 9000 或返回支付页
        ↓
前端请求业务服务端查询订单
        ↓
服务端确认支付宝交易状态
        ↓
跳转并展示自定义支付成功页

因此,当前问题不在 if 条件,而在于支付模式没有统一。使用 tradePay 时,需要让收银台返回原 WebView;使用 WAP 跳转支付时,则要配置 return_url,并在返回页通过服务端确认订单状态。

备注:内容仅供参考。