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,并在返回页通过服务端确认订单状态。
备注:内容仅供参考。
