PAYATHON 2026

如何通过浏览器使用 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 的标准流程,而且容易受到浏览器拦截、版本兼容性和安全策略的影响。

对题目中参数的特别说明

题目中的字符串不能作为当前可用的付款链接,至少有以下几个问题:

  1. method 是 alipay.trade.app.pay,用于客户端 SDK 支付。
  2. timestamp 是 2024-08-22 19:26:30,不应使用历史请求重新发起支付。
  3. out_trade_no、金额和签名已经固定。重复提交可能导致订单已存在、订单状态冲突、请求过期或验签失败。
  4. 参数中的 notify_url 使用了第三方域名,看起来不是当前开发者自行控制的支付配置。不要复制、篡改或重复使用他人的支付参数。
  5. 示例使用的是 sign_type=RSA。实际项目应以当前支付宝开放平台配置和所用 SDK 的要求为准。如果改用 RSA2,应用公私钥配置和签名也必须保持一致。

应在自己有权使用的支付宝商户应用中创建新订单。手机浏览器使用 alipay.trade.wap.pay,电脑浏览器使用 alipay.trade.page.pay。所有参数和签名都由服务端重新生成,再将支付宝返回的表单交给浏览器执行。

备注:内容仅供参考。