PAYATHON 2026

支付宝手机网页支付 Demo 中 quit_url 和 product_code 如何配置?

支付老李

结论

支付宝手机网页支付 Demo 通常调用 alipay.trade.wap.pay 接口:

  • product_code 是销售产品码。手机网站支付应使用固定值 QUICK_WAP_WAY。
  • quit_url 是用户在支付宝收银台中途取消或退出支付时返回的商户页面地址,需要填写完整且可访问的 URL。
  • 配置正确并发起请求后,商户服务端会生成用于跳转到支付宝收银台的表单。服务端需要将该表单返回给手机浏览器并自动提交,才能进入支付流程。
  • 能否直接唤起支付宝 App,取决于浏览器环境、手机系统、支付宝客户端是否安装以及支付宝收银台的处理策略。支付宝不能保证每次都直接打开 App,有时会继续使用 H5 收银台完成支付。

两个参数分别有什么作用

product_code

product_code 用于标识当前交易使用的支付宝产品。手机网站支付一般配置为:

QUICK_WAP_WAY

这个值不是商品编号,也不是商户自行定义的产品 ID。调用 alipay.trade.wap.pay 时,不应填入商品 SKU、订单号或应用名称。

示例:

{
  "product_code": "QUICK_WAP_WAY"
}

quit_url

quit_url 是用户在支付过程中主动退出时返回的地址,可以填写订单确认页或订单详情页,例如:

https://www.example.com/order/12345

quit_url 只处理退出收银台后的页面跳转,不代表支付成功,也不能作为修改订单状态的依据。

它与另外两个常见 URL 参数的用途不同:

参数作用
quit_url用户中途退出支付时返回的页面
return_url支付完成后,浏览器前台跳回商户页面的地址
notify_url支付宝服务端异步通知商户的地址

判断订单是否支付成功,应以 notify_url 收到的异步通知为准,必要时还要主动查询交易结果,不能只看浏览器是否跳转到了 return_url。

Demo 的基本使用步骤

1. 准备应用和签名配置

至少要正确配置以下信息:

  • 支付宝应用 app_id
  • 商户应用私钥
  • 支付宝公钥,或证书模式对应的证书
  • 签名算法,常见为 RSA2
  • 支付宝网关地址
  • 字符集,通常为 UTF-8
  • return_url
  • notify_url

沙箱环境和正式环境的应用、网关、密钥及账号配置不能混用。正式发起交易前,还需要确认应用已经具备手机网站支付能力。具体开通条件以对应支付宝开放平台应用的实际配置为准。

2. 组装支付业务参数

下面是 Java SDK 的常见写法:

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://www.example.com/pay/return");
request.setNotifyUrl("https://www.example.com/api/alipay/notify");

request.setBizContent("""
{
  "out_trade_no": "ORDER_202609090001",
  "total_amount": "99.00",
  "subject": "测试商品",
  "product_code": "QUICK_WAP_WAY",
  "quit_url": "https://www.example.com/order/ORDER_202609090001"
}
""");

AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);

if (response.isSuccess()) {
    String form = response.getBody();
    // 将 form 原样写入 HTTP 响应,使手机浏览器自动提交并进入支付宝收银台
} else {
    // 记录 response.getCode()、response.getSubCode() 等错误信息
}

实际项目中,不要直接拼接含有用户输入的 JSON。可以使用 SDK 提供的业务模型,也可以通过可靠的 JSON 库序列化参数。

3. 将 SDK 返回内容写给浏览器

pageExecute 通常会返回一个可以自动提交的 HTML 表单。服务端必须将它作为页面响应输出给浏览器。例如,在 Servlet 中可以这样处理:

response.setContentType("text/html;charset=UTF-8");
response.getWriter().write(alipayResponse.getBody());
response.getWriter().flush();

如果只在服务端调用接口、打印返回内容,或者把 HTML 当作普通字符串传给前端,支付宝收银台不会自动打开。用户当前使用的手机浏览器必须加载并提交这个表单。

会不会直接跳转到支付宝

正常配置后的典型流程如下:

用户点击支付
    → 商户服务端创建支付请求
    → 浏览器提交支付宝表单
    → 进入支付宝收银台
    → 根据终端环境使用支付宝 App 或 H5 页面支付

正常情况下,用户会进入支付宝支付流程,但不一定会直接唤起支付宝 App。实际情况可能是:

  • 手机已安装支付宝,且当前浏览器允许唤起 App,可能会打开支付宝客户端。
  • 手机未安装支付宝,通常会进入适用的网页支付流程或显示相应提示。
  • 浏览器限制跳转到外部应用时,页面可能停留在 H5 收银台,需要用户继续操作。
  • 微信等内置浏览器可能限制跳转到支付宝,并提示用户改用系统浏览器打开。
  • 参数、签名或产品权限存在异常时,用户无法进入正常收银台,页面或接口会返回错误。

不要自行使用支付宝私有 URL Scheme 强制拉起客户端。跳转应由 alipay.trade.wap.pay 返回的官方收银台页面完成。

常见错误和注意事项

不要把 quit_url 当成支付结果地址

用户可以在没有完成支付的情况下返回 quit_url。这个页面只能用于恢复订单页面或提示用户重新支付,不能据此把订单状态改为 “已支付”。

不要依赖 return_url 更新订单

前台跳转可能被关闭、拦截或重复访问。订单状态应在服务端对 notify_url 通知验签通过后更新,并至少校验以下内容:

  • 通知签名是否有效
  • app_id 是否属于当前应用
  • out_trade_no 是否存在
  • total_amount 是否与订单金额一致
  • seller_id 是否符合预期
  • 交易状态是否为业务允许处理的状态

回调处理还需要保证幂等,防止重复通知造成重复发货或重复记账。

URL 应使用完整地址

建议使用完整的 HTTPS 地址:

https://www.example.com/pay/quit

不要填写相对路径:

/pay/quit

联调时,需要确认相关地址在对应访问方的网络环境中可以访问。尤其是 notify_url,支付宝服务器必须能够通过公网访问它,因此不能使用 localhost、127.0.0.1 或只能从内网访问的地址。

订单号必须唯一

out_trade_no 是商户订单号。如果重复使用已经创建过交易的订单号,同时又修改金额或商品信息,可能会造成交易冲突。订单号应由服务端生成并持久化。

金额必须由服务端确定

不要直接采用前端提交的 total_amount。服务端应根据商品、优惠和订单记录重新计算应付金额,再生成支付宝请求,防止用户篡改支付金额。

不要手工修改签名后的参数

请求生成后,如果再修改 biz_content、回调地址或其他参与签名的字段,会导致验签失败。所有参数都应先设置完成,再交给支付宝 SDK 生成签名和表单。

备注:内容仅供参考。