手机网站支付成功后如何自动跳转回原网站查看订单
结论
不要依赖浏览器的”返回上一页”。发起手机网站支付时,应配置支付渠道提供的同步返回地址,例如 redirect_url 或 return_url,并指向商户自己的订单结果页。
使用微信 H5 支付时,通常要在拉起支付的 mweb_url 后追加经过 URL 编码的 redirect_url:
{mweb_url}&redirect_url={URL-encoded 商户订单页地址}
用户完成支付并点击”已支付完成,返回查看订单”后,微信会跳转到这个地址。
但页面发生跳转不等于支付成功。商户后端必须根据支付异步通知或主动查询结果,确认订单是否已经支付。
为什么现在只能手动返回
“已完成支付,请手动返回商户查看”一般来自支付渠道的中间结果页,并不属于商户网站,因此商户无法通过修改自己页面的 JavaScript 控制它。
如果发起支付时没有提供有效的返回地址,支付渠道只能提示用户手动回到商户页面。使用 history.back() 或让用户连续点击返回也不可靠,原因包括:
- 不同手机和浏览器保存的历史记录可能不同;
- 支付页面可能在新的浏览器窗口或微信页面中打开;
- 返回后可能进入支付确认页,而不是订单页;
- 用户可能再次提交支付请求。
应配置支付渠道支持的返回参数,并让商户订单页重新查询支付状态。
微信 H5 支付的处理方式
假设微信支付接口返回以下支付地址:
https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=xxx&package=xxx
商户希望用户返回这个页面:
https://www.example.com/orders/202609130001/result
先对返回地址进行 URL 编码,再将其追加到 mweb_url:
https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=xxx&package=xxx&redirect_url=https%3A%2F%2Fwww.example.com%2Forders%2F202609130001%2Fresult
后端可以这样生成跳转地址:
function buildWechatH5PayUrl(mwebUrl, orderNo) {
const returnUrl =
`https://www.example.com/payment/result?order_no=${encodeURIComponent(orderNo)}`;
return `${mwebUrl}&redirect_url=${encodeURIComponent(returnUrl)}`;
}
前端再跳转到生成后的地址:
window.location.href = payUrl;
不要直接拼接未经编码的返回地址。地址中的 ?、&、# 等字符可能破坏 mweb_url 原有的参数结构。
返回页面不能直接认定支付成功
用户进入订单结果页,只能说明他回到了商户网站,不能证明付款已经完成。实际使用中可能出现这些情况:
- 用户取消支付后仍进入了返回页面;
- 支付已经成功,但异步通知尚未到达;
- 网络中断,返回页未能及时获取订单状态;
- 用户伪造订单号或直接访问结果页。
结果页应调用商户后端接口查询订单状态:
async function loadPaymentResult(orderNo) {
const response = await fetch(
`/api/orders/${encodeURIComponent(orderNo)}/payment-status`,
{
credentials: 'include'
}
);
if (!response.ok) {
throw new Error('查询支付状态失败');
}
const result = await response.json();
if (result.status === 'PAID') {
window.location.replace(
`/orders/${encodeURIComponent(orderNo)}`
);
return;
}
if (result.status === 'PENDING') {
showPendingMessage();
return;
}
showUnpaidMessage();
}
后端查询时还要确认订单属于当前登录用户,不能只根据前端传入的订单号返回订单详情。
推荐的完整流程
- 商户后端创建支付订单,并调用支付渠道的下单接口。
- 支付渠道返回支付地址,例如微信 H5 支付的
mweb_url。 - 商户后端对订单结果页地址编码,再以
redirect_url参数追加到支付地址。 - 前端跳转到最终生成的支付地址。
- 支付渠道通过异步通知发送支付结果,商户后端验签后更新订单。
- 用户点击”已支付完成,返回查看订单”,进入商户结果页。
- 结果页向商户后端查询订单状态。
- 后端以异步通知记录或支付渠道的查询结果为准,返回真实状态。
- 如果订单已支付,则展示订单;如果仍在处理中,则提示用户稍候,并进行有限次数的轮询。
其他支付渠道
如果使用的不是微信 H5 支付,参数名称和配置位置可能不同,常见名称有:
return_urlredirect_url- 同步返回地址
- 支付完成跳转地址
有些渠道要求在下单接口中提交返回地址,有些要在商户后台配置,还有些要求把返回地址追加到支付链接中。具体应以当前支付产品和接口版本的接入文档为准,不要将微信 H5 支付的 redirect_url 直接用于其他渠道。
异步通知地址通常称为 notify_url。它负责让支付平台向商户服务器发送支付结果,不负责用户浏览器的跳转:
return_url / redirect_url:把用户带回商户页面
notify_url:把支付结果通知给商户后端
两类地址用途不同,通常需要同时配置。
注意事项
- 返回地址应使用 HTTPS,并符合支付渠道对域名、目录或授权域名的要求。
- 不要通过普通查询参数传递支付状态,例如
?paid=true。 - 不要只根据页面跳转或前端回调,将订单改为”已支付”。
- 收到异步通知后必须验签,并核对商户号、订单号、金额和币种等信息。
- 支付通知可能重复发送,因此订单更新接口必须具备幂等性。
- 进入最终订单页时,建议使用
location.replace(),减少用户返回后再次进入支付流程的情况。 - 返回地址中的订单号不能代替身份验证。查询订单时,仍需验证登录状态和订单归属。
- 如果配置后仍出现手动返回提示,请检查返回地址是否正确编码、域名是否符合渠道要求,以及最终支付链接中是否确实包含返回参数。
备注:内容仅供参考。