PAYATHON 2026

是否有 alipay.trade.page.pay 前置模式 Demo 或文档?

支付老李

结论

alipay.trade.page.pay 通常采用前置页面跳转。商户服务端调用接口生成支付宝收银台表单,把表单 HTML 返回给浏览器后自动提交。一般不需要,也不建议把支付宝收银台嵌入商户自己的 iframe。

官方 Demo 通常使用 pageExecute 生成表单并完成跳转,没有单独提供所谓的“iframe 前置模式”接口。如果合同、开放平台控制台或当前产品文档明确支持 iframe 模式,应按对应产品文档接入。否则,不要假定 alipay.trade.page.pay 能够在 iframe 中稳定运行。

推荐接入流程

完整流程如下:

  1. 用户在商户网站确认订单。
  2. 浏览器请求商户服务端的支付接口。
  3. 商户服务端创建 AlipayTradePagePayRequest。
  4. 服务端调用 pageExecute,获取自动提交的 HTML 表单。
  5. 浏览器提交表单,顶层页面跳转到支付宝收银台。
  6. 用户完成支付后,支付宝向 notify_url 发送异步通知。
  7. 商户验签并核对订单信息,再更新订单状态。
  8. return_url 只负责同步跳转和结果展示,不能作为确认支付成功的最终依据。

流程可以简化为:

商户页面
   ↓ 创建支付
商户服务端
   ↓ 返回自动提交表单
支付宝收银台
   ↓ 用户完成支付
notify_url → 商户服务端确认支付结果
return_url → 浏览器展示支付结果

Java 示例

下面是 Java SDK 的典型调用方式。该示例只用于说明调用结构。SDK 依赖版本、网关地址和证书配置,应以商户当前的开放平台配置为准。

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;

public class AlipayPagePayDemo {

    public static String createPayForm() throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(
            "https://openapi.alipay.com/gateway.do",
            "YOUR_APP_ID",
            "YOUR_APP_PRIVATE_KEY",
            "json",
            "UTF-8",
            "ALIPAY_PUBLIC_KEY",
            "RSA2"
        );

        AlipayTradePagePayRequest request =
            new AlipayTradePagePayRequest();

        request.setReturnUrl(
            "https://www.example.com/alipay/return"
        );
        request.setNotifyUrl(
            "https://www.example.com/alipay/notify"
        );

        request.setBizContent("""
            {
              "out_trade_no": "ORDER_202609090001",
              "total_amount": "99.00",
              "subject": "测试订单",
              "product_code": "FAST_INSTANT_TRADE_PAY"
            }
            """);

        return alipayClient.pageExecute(request).getBody();
    }
}

Web 接口需要把生成的表单直接返回给浏览器:

@GetMapping(
    value = "/pay",
    produces = "text/html;charset=UTF-8"
)
@ResponseBody
public String pay() throws AlipayApiException {
    return AlipayPagePayDemo.createPayForm();
}

浏览器收到的通常是一段包含 <form> 和自动提交脚本的 HTML。不要按 JSON 解析,也不要对内容进行 HTML 转义,否则表单可能无法正常提交。

如果业务页面必须保留

可以通过新窗口或顶层页面打开支付入口:

<form action="/pay" method="get" target="_blank">
  <button type="submit">支付宝支付</button>
</form>

也可以直接从当前页面跳转:

window.location.href = "/pay";

如果当前页面处于 iframe 中,需要跳出 iframe,可以使用:

window.top.location.href = "/pay";

这种方式要求父页面没有通过沙箱限制阻止顶层跳转。如果 iframe 设置了 sandbox,还要确认其配置是否允许顶层导航。

为什么不建议直接使用 iframe

支付宝收银台涉及登录、风控、扫码、短信验证和跨域跳转。使用 iframe 时可能出现以下问题:

  • 收银台页面不允许嵌入第三方页面;
  • 浏览器限制第三方 Cookie;
  • 扫码或登录后的跨域跳转失败;
  • iframe 的 sandbox 或安全策略阻止表单提交;
  • 移动端和桌面端的行为不一致;
  • 用户难以判断当前页面是否为真实的支付宝收银台。

即使 iframe 在某些环境中暂时能够显示,也不能说明这种方式稳定或受到官方支持。

异步通知处理要点

确认支付结果应以 notify_url 为主要入口。收到通知后,至少需要完成以下处理:

  1. 使用支付宝公钥验签;
  2. 核对 app_id;
  3. 核对 out_trade_no;
  4. 核对 total_amount;
  5. 检查 trade_status;
  6. 确保订单更新具有幂等性;
  7. 处理成功后,按协议返回成功响应。

不能因为浏览器跳转到了 return_url,就直接把订单改为已支付。用户可能关闭页面,网络也可能中断,而且同步参数不能代替服务端验签。

如果异步通知尚未到达,可以由服务端调用交易查询接口核实状态。不要让前端持有应用私钥,也不要让前端直接调用需要签名的开放接口。

注意事项

  • out_trade_no 必须在商户系统中保持唯一。
  • 金额应由服务端根据订单计算,不能直接采用前端传入的值。
  • 私钥只能保存在服务端,不能写入 JavaScript 或 HTML。
  • 正式环境和沙箱环境的网关、应用配置及密钥不能混用。
  • notify_url 必须能够被支付宝服务器通过公网访问。
  • 回调地址不能依赖登录状态、浏览器 Cookie 或前端页面。
  • 证书模式和公钥模式的初始化代码不同,需要与应用实际使用的签名配置一致。
  • 如果必须使用 iframe,应先查阅当前商户产品文档,或向支付宝技术支持确认该能力是否已对相关应用开放,再按官方提供的专用流程接入。

备注:内容仅供参考。