WAP支付跳转支付宝页面时提示“网页无法访问”
结论
这个地址是支付宝收银台生成的临时跳转结果,不能作为固定支付地址保存、拼接或重复使用。“网页无法访问”通常与以下情况有关:
- 支付地址已经失效,或者它依赖的临时会话已经过期。
- URL 在传递时被截断、重复编码或错误转义。
- 商户服务端创建支付请求失败,但仍把异常结果当作跳转地址返回。
- 系统仍在使用旧版 WAP 支付接口或历史收银台地址,与当前接入方式不匹配。
- 客户端 WebView、网络代理、DNS、TLS 或支付宝 App 唤起环境存在问题。
每次支付都应由服务端调用当前有效的支付宝 WAP 支付接口重新创建订单,再把接口返回的完整 HTML 表单直接输出到浏览器。不要自行构造或长期保存 mclient.alipay.com/cashier/mobilepay.htm 地址。
先确认支付链接是否失效
示例地址中的以下参数:
alipay_exterface_invoke_assign_target
alipay_exterface_invoke_assign_sign
通常是收银台内部使用的跳转参数,可能有时效限制,也可能依赖创建支付请求时的上下文。
如果地址是从控制台日志、浏览器历史记录或聊天工具中复制出来后再次打开的,它可能已经无法使用。此时应重新发起一笔支付,由服务端实时生成新的支付页面。
还要检查:
- 地址是否刚刚生成,而不是历史订单中的旧地址。
- 同一个支付链接是否被打开过多次。
- 订单是否已经支付、关闭或超时。
- 从生成链接到打开链接是否间隔过久。
- 是否把测试环境生成的请求用于生产环境,或者反过来使用。
不要手工拼接收银台 URL
业务系统不应直接拼接此类地址:
https://mclient.alipay.com/cashier/mobilepay.htm?...
收银台域名、页面路径和内部参数都不是稳定接口。现在常见的手机网站支付接入方式是调用 alipay.trade.wap.pay,然后使用支付宝 SDK 返回的 HTML 表单。
下面以 Java 为例。具体的 SDK 版本、网关地址和密钥格式,应以商户实际接入配置为准:
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi.alipay.com/gateway.do",
appId,
merchantPrivateKey,
"json",
"UTF-8",
alipayPublicKey,
"RSA2"
);
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
request.setReturnUrl("https://merchant.example.com/pay/return");
request.setNotifyUrl("https://merchant.example.com/pay/notify");
request.setBizContent("""
{
"out_trade_no": "ORDER_202609090001",
"total_amount": "0.01",
"subject": "测试订单",
"product_code": "QUICK_WAP_WAY"
}
""");
AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
if (!response.isSuccess()) {
throw new IllegalStateException(
"创建支付宝支付页面失败: code=" + response.getCode()
+ ", subCode=" + response.getSubCode()
+ ", msg=" + response.getMsg()
+ ", subMsg=" + response.getSubMsg()
);
}
String form = response.getBody();
控制器应把 response.getBody() 返回的表单原样输出为 HTML:
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write(form);
response.getWriter().flush();
不要从返回内容中提取某个收银台 URL,再让前端长期保存或重新拼接。
检查 URL 在传递时是否损坏
如果支付请求会经过前端路由、网关、短链服务、二维码系统或数据库,需要逐项确认完整 URL 是否发生变化,尤其要检查:
&是否先被转换成&,随后又被当作普通文本跳转。%是否被重复编码为%25。+是否被表单解析为空格。- URL 是否因为字段长度不足而被截断。
- 前端是否调用了两次
encodeURIComponent()。 - 网关是否过滤了含有
sign的查询参数。 - 从日志中复制地址时,是否漏掉了后半段参数。
不要再次整体编码已经生成的完整支付地址:
// 错误:可能导致整条 URL 被当成普通字符串编码
location.href = encodeURIComponent(payUrl);
应直接跳转到服务端返回的完整地址:
window.location.href = payUrl;
如果需要把支付地址作为另一个 URL 的参数传递,只能在这一层编码一次,并在接收端解码一次:
const redirectUrl = `/pay/redirect?target=${encodeURIComponent(payUrl)}`;
服务端也要确认数据库字段能容纳完整内容。使用过短的 VARCHAR 保存支付地址,可能会截断签名参数。
查看服务端接口的实际返回结果
日志不能只记录最终跳转地址,还应记录支付宝开放平台接口返回的错误信息,包括:
code
msg
sub_code
sub_msg
out_trade_no
trade_no
记录时必须做好脱敏,不能输出商户私钥、完整签名、用户身份信息或全部支付凭证。
需要重点核对:
app_id是否属于当前商户应用。- 商户私钥与支付宝公钥是否配置正确。
- 签名算法是否一致,例如
RSA2。 - 字符集是否一致,通常为
UTF-8。 - 应用是否已经开通手机网站支付能力。
- 网关地址是否对应当前环境。
notify_url和return_url是否为能够访问的完整 HTTPS 地址。out_trade_no是否被重复使用。- 金额格式是否符合接口要求。
如果 pageExecute() 返回失败,应先处理接口错误,不能继续执行跳转。
区分服务端问题与客户端问题
可以使用同一笔新生成的支付请求做交叉测试:
- 分别在手机系统浏览器、支付宝内置浏览器和业务 App WebView 中打开。
- 分别使用移动网络和 Wi-Fi 测试。
- 确认设备时间准确。
- 检查设备是否配置了代理、VPN、抓包证书或企业网络过滤。
- 查看失败页面对应的实际 HTTP 状态码和最终地址。
如果系统浏览器能够打开,但 App WebView 无法打开,通常需要检查 WebView 配置或 URL 拦截逻辑:
- 是否允许加载 HTTPS 页面。
- 是否错误拦截了重定向。
- 是否只允许业务域名,导致支付宝域名被阻止。
- 是否把支付宝相关 scheme 当成普通 HTTP 地址处理。
- Android WebView 的
shouldOverrideUrlLoading返回值是否有误。 - iOS
WKNavigationDelegate是否取消了正常导航。
Android 示例:
@Override
public boolean shouldOverrideUrlLoading(
WebView view,
WebResourceRequest request) {
Uri uri = request.getUrl();
if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) {
return false;
}
try {
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
view.getContext().startActivity(intent);
return true;
} catch (Exception ignored) {
return false;
}
}
这段代码只用于说明处理思路。实际项目还要根据允许的域名、scheme 和安全策略增加限制,不能无条件打开任意外部地址。
旧接口接入需要迁移
如果现有系统仍依赖历史 WAP 支付接口,并直接获取 mobilepay.htm 形式的地址,需要先确认当前商户产品、接口权限和接入文档是否仍支持这种方式。
如果无法确认旧接口仍然有效,建议迁移到开放平台当前提供的手机网站支付接口:
alipay.trade.wap.pay
迁移不能只替换收银台域名,以下部分也要同步调整:
- 请求参数。
- 签名方式。
- SDK 调用代码。
- 异步通知验签。
- 同步返回处理。
- 订单查询和关闭流程。
排查顺序
先重新创建一笔订单,通过官方 SDK 实时生成支付表单。如果新订单可以正常打开,原地址大概率已经失效,或者在保存、复制过程中受损。
如果新订单仍然失败,可以按以下顺序继续检查:
pageExecute()返回的code、sub_code和sub_msg。- 应用、密钥、签名算法和接口权限。
- 返回表单或 URL 是否被截断、错误转义或重复编码。
- 系统浏览器和 App WebView 的表现是否一致。
- 当前接入是否仍在使用旧版 WAP 支付流程。
- 网络、DNS、代理和 TLS 环境。
仅凭”网页无法访问”无法判断唯一原因。排查时至少应保留失败时间、脱敏后的完整请求参数、支付宝接口返回码、HTTP 状态码和客户端环境信息。如果需要联系支付宝技术支持,这些信息也比单独提供一张收银台截图更有用。
备注:内容仅供参考。
