如何通过浏览器使用 alipay.trade.app.pay 跳转支付宝付款
结论
alipay.trade.app.pay 的这串参数不是浏览器支付链接,而是支付宝 Android/iOS SDK 使用的 orderString。不能把它简单拼接成:
https://openapi.alipay.com/gateway.do?原参数
然后打开支付宝收银台。这样做只是在浏览器中请求开放平台接口,通常无法得到可交互的付款页面。
应根据支付场景选择对应方案:
- 手机浏览器支付:服务端调用
alipay.trade.wap.pay - 电脑浏览器支付:服务端调用
alipay.trade.page.pay - 原生 App 支付:继续使用
alipay.trade.app.pay,将服务端生成的orderString交给支付宝客户端 SDK - H5 页面需要唤起支付宝:先通过
alipay.trade.wap.pay创建支付,再由支付宝返回的收银台页面按其支持的方式跳转或唤起,不要自行拼装私有 URL Scheme
为什么不能直接使用这串参数
alipay.trade.app.pay 的调用流程是:
商户服务端生成并签名 orderString
↓
商户 App 调用支付宝 SDK
↓
SDK 唤起支付宝客户端
↓
用户付款
↓
支付宝异步通知商户 notify_url
浏览器支付的调用流程是:
浏览器请求商户服务端
↓
商户服务端调用 alipay.trade.wap.pay 或 alipay.trade.page.pay
↓
服务端返回支付宝提供的 HTML 表单
↓
浏览器提交表单并进入支付宝收银台
这两类支付产品使用的接口和交互方式不同。即使 app_id、订单号和金额等业务数据相同,也需要更换 method,并根据新参数重新签名。不能只把原字符串中的:
method=alipay.trade.app.pay
替换为:
method=alipay.trade.wap.pay
原签名包含 method、biz_content、timestamp 等参数。任何参与签名的内容发生变化,原签名都会失效。
手机浏览器的正确实现
服务端应使用:
method=alipay.trade.wap.pay
常见的业务参数如下:
{
"out_trade_no": "YOUR_UNIQUE_ORDER_NO",
"total_amount": "3.60",
"subject": "订单 YOUR_UNIQUE_ORDER_NO",
"product_code": "QUICK_WAP_WAY"
}
同时配置:
return_url=https://merchant.example.com/pay/return
notify_url=https://merchant.example.com/pay/notify
各参数的作用和使用要求如下:
return_url用于付款后将浏览器带回商户页面,不能作为判断最终到账结果的依据。notify_url用于接收支付宝服务端的异步通知。支付状态应以验签成功的异步通知或主动查单结果为准。out_trade_no必须由商户服务端生成,并在商户应用范围内保持唯一。- 私钥、订单金额和签名逻辑必须放在服务端,不能写入网页 JavaScript。
Java 示例
使用支付宝开放平台 SDK 时,可以让 SDK 生成自动提交的 HTML 表单:
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi.alipay.com/gateway.do",
APP_ID,
APP_PRIVATE_KEY,
"json",
"UTF-8",
ALIPAY_PUBLIC_KEY,
"RSA2"
);
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
request.setReturnUrl("https://merchant.example.com/pay/return");
request.setNotifyUrl("https://merchant.example.com/pay/notify");
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setOutTradeNo("YOUR_UNIQUE_ORDER_NO");
model.setTotalAmount("3.60");
model.setSubject("订单 YOUR_UNIQUE_ORDER_NO");
model.setProductCode("QUICK_WAP_WAY");
request.setBizModel(model);
AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
if (!response.isSuccess()) {
throw new IllegalStateException(
response.getCode() + ": " + response.getSubMsg()
);
}
String paymentForm = response.getBody();
服务端再将 paymentForm 作为 HTML 返回给浏览器:
httpServletResponse.setContentType("text/html;charset=UTF-8");
httpServletResponse.getWriter().write(paymentForm);
httpServletResponse.getWriter().flush();
response.getBody() 通常是支付宝 SDK 生成的表单。浏览器加载后,表单会提交到支付宝网关,随后进入 H5 收银台。
不使用 SDK 时的请求形式
如果选择自行实现签名,需要按照支付宝接口要求生成公共参数和业务参数,再将请求提交到网关。请求结构大致如下:
<form id="alipay-form"
method="post"
action="https://openapi.alipay.com/gateway.do">
<input type="hidden" name="app_id" value="YOUR_APP_ID">
<input type="hidden" name="method" value="alipay.trade.wap.pay">
<input type="hidden" name="format" value="JSON">
<input type="hidden" name="charset" value="UTF-8">
<input type="hidden" name="sign_type" value="RSA2">
<input type="hidden" name="timestamp" value="2026-09-09 12:00:00">
<input type="hidden" name="version" value="1.0">
<input type="hidden" name="return_url"
value="https://merchant.example.com/pay/return">
<input type="hidden" name="notify_url"
value="https://merchant.example.com/pay/notify">
<input type="hidden" name="biz_content"
value='{"out_trade_no":"YOUR_UNIQUE_ORDER_NO","total_amount":"3.60","subject":"订单 YOUR_UNIQUE_ORDER_NO","product_code":"QUICK_WAP_WAY"}'>
<input type="hidden" name="sign" value="SERVER_GENERATED_SIGNATURE">
</form>
<script>
document.getElementById("alipay-form").submit();
</script>
这段代码只用于展示请求结构。sign 必须由服务端使用应用私钥,根据实际提交的参数重新计算。自行处理参数排序、字符编码和转义时很容易造成验签失败,因此通常应优先使用官方 SDK。
电脑浏览器支付
如果需要电脑网页收银台,应使用:
alipay.trade.page.pay
业务参数通常包括:
{
"out_trade_no": "YOUR_UNIQUE_ORDER_NO",
"total_amount": "3.60",
"subject": "订单 YOUR_UNIQUE_ORDER_NO",
"product_code": "FAST_INSTANT_TRADE_PAY"
}
处理方式与 WAP 支付相似。服务端创建请求并重新签名,再将 SDK 返回的表单输出给浏览器。
如果必须使用 alipay.trade.app.pay
只有原生 App 才应将服务端生成的完整支付字符串交给支付宝 SDK。例如,Android 端的典型调用方式是:
PayTask alipay = new PayTask(activity);
Map<String, String> result = alipay.payV2(orderString, true);
orderString 必须由自己的服务端生成。客户端不能保存商户私钥,也不应修改已经签名的参数。
App 支付字符串可以经过 URL 编码后传给自己的 App,但这不代表它能作为 HTTP 地址直接在浏览器中付款。自行拼装 alipays:// 等客户端 Scheme 也不能替代 alipay.trade.app.pay 的标准流程,而且容易受到浏览器拦截、版本兼容性和安全策略的影响。
对题目中参数的特别说明
题目中的字符串不能作为当前可用的付款链接,至少有以下几个问题:
method是alipay.trade.app.pay,用于客户端 SDK 支付。timestamp是2024-08-22 19:26:30,不应使用历史请求重新发起支付。out_trade_no、金额和签名已经固定。重复提交可能导致订单已存在、订单状态冲突、请求过期或验签失败。- 参数中的
notify_url使用了第三方域名,看起来不是当前开发者自行控制的支付配置。不要复制、篡改或重复使用他人的支付参数。 - 示例使用的是
sign_type=RSA。实际项目应以当前支付宝开放平台配置和所用 SDK 的要求为准。如果改用RSA2,应用公私钥配置和签名也必须保持一致。
应在自己有权使用的支付宝商户应用中创建新订单。手机浏览器使用 alipay.trade.wap.pay,电脑浏览器使用 alipay.trade.page.pay。所有参数和签名都由服务端重新生成,再将支付宝返回的表单交给浏览器执行。
备注:内容仅供参考。
