alipay.trade.pay与APP、WAP支付接口有什么区别?
结论
alipay.trade.pay 不能直接替代 alipay.trade.app.pay 或 alipay.trade.wap.pay。
这三个接口都能发起支付宝交易,但支付入口、交互方式和返回结果并不相同:
| 接口 | 典型场景 | 用户如何付款 | 接口主要返回 |
|---|---|---|---|
alipay.trade.pay | 收银台、POS、扫码枪 | 用户出示付款码,商户扫码 | 同步支付结果 |
alipay.trade.app.pay | 原生 App | App 调起支付宝客户端 | 供支付宝 SDK 使用的订单字符串 |
alipay.trade.wap.pay | 手机浏览器、H5 页面 | 浏览器跳转支付宝收银台 | HTML 表单或跳转页面 |
选择哪个接口,要看实际支付场景,而不是比较哪个接口”功能更强”。如果用户没有向商户出示付款码,通常就不能用 alipay.trade.pay 替代 APP 支付或 WAP 支付。
核心区别
alipay.trade.pay:商户主动收款
这个接口主要用于付款码支付。用户打开支付宝付款码,商户使用扫码枪、摄像头或其他设备读取 auth_code,再由商户服务端调用接口完成扣款。
典型流程如下:
- 用户出示支付宝付款码。
- 商户设备读取付款码。
- 商户服务端调用
alipay.trade.pay。 - 支付宝同步返回成功、失败或等待用户确认等状态。
- 如果状态不明确,商户通过查询接口确认最终结果。
使用该接口的前提是,商户已经取得用户的付款授权码。它不能用于生成 APP 调起参数,也不会返回 H5 收银台页面。
以 Java SDK 的常见写法为例:
AlipayTradePayRequest request = new AlipayTradePayRequest();
request.setBizContent("""
{
"out_trade_no": "ORDER_20260908_001",
"scene": "bar_code",
"auth_code": "用户付款码",
"subject": "门店商品",
"total_amount": "99.00"
}
""");
AlipayTradePayResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
System.out.println("支付请求处理成功");
System.out.println(response.getTradeNo());
} else {
System.out.println(response.getCode());
System.out.println(response.getSubCode());
System.out.println(response.getSubMsg());
}
付款码是敏感数据,而且通常只在短时间内有效。不要把它写入普通业务日志,也不要让前端长期保存或重复使用。
alipay.trade.app.pay:原生 App 调起支付宝
该接口适用于原生 Android 或 iOS 应用。商户服务端调用接口后会得到一段已签名的订单字符串,再把它返回给 App,由 App 通过支付宝客户端 SDK 发起支付。
服务端示例:
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
request.setNotifyUrl("https://example.com/alipay/notify");
request.setBizContent("""
{
"out_trade_no": "ORDER_20260908_002",
"total_amount": "99.00",
"subject": "App会员订单",
"product_code": "QUICK_MSECURITY_PAY"
}
""");
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
if (response.isSuccess()) {
String orderString = response.getBody();
System.out.println(orderString);
}
这里的 response.getBody() 一般不是最终支付结果,而是供客户端 SDK 使用的订单信息。判断用户是否完成支付,需要综合客户端回调、服务端异步通知和主动查询结果。
alipay.trade.pay 无法生成供 APP SDK 使用的同类订单字符串,因此不能直接替代它。
alipay.trade.wap.pay:手机网页跳转支付
该接口适用于 H5、手机浏览器或 WebView。服务端创建支付请求后,通常会输出一个自动提交的 HTML 表单,让浏览器跳转到支付宝收银台。
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
request.setReturnUrl("https://example.com/payment/result");
request.setNotifyUrl("https://example.com/alipay/notify");
request.setBizContent("""
{
"out_trade_no": "ORDER_20260908_003",
"total_amount": "99.00",
"subject": "H5商品订单",
"product_code": "QUICK_WAP_WAY"
}
""");
AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
if (response.isSuccess()) {
String form = response.getBody();
System.out.println(form);
}
返回的表单需要输出到浏览器,由浏览器完成后续跳转。return_url 只用于支付完成后的页面跳转,不能作为已经到账的可信依据。订单状态应以服务端异步通知或主动查询结果为准。
alipay.trade.pay 不包含这套浏览器跳转流程,所以也不能直接替代 WAP 支付。
应该如何选择
线下门店中,如果顾客在收银台出示支付宝付款码,应选择:
alipay.trade.pay
如果业务运行在原生 Android 或 iOS App 中,需要调起支付宝客户端,应选择:
alipay.trade.app.pay
如果业务运行在手机浏览器、H5 页面或主要通过网页跳转的 WebView 中,应选择:
alipay.trade.wap.pay
如果同一套业务同时覆盖 App、H5 和线下门店,通常需要在支付服务层保留多个支付通道,不宜强行统一为一个支付宝接口。例如:
public PaymentResult createPayment(PaymentRequest payment) {
return switch (payment.getChannel()) {
case APP -> createAlipayAppPayment(payment);
case WAP -> createAlipayWapPayment(payment);
case BAR_CODE -> executeAlipayTradePay(payment);
};
}
业务层可以统一处理订单号、金额校验、幂等控制、支付通知和订单查询,但调用支付宝接口时,仍要按场景选择对应接口。
为什么不能通过传不同参数实现平替
三类接口的区别不只在请求参数,整个支付流程也不同:
alipay.trade.pay依赖用户付款码auth_code。alipay.trade.app.pay依赖客户端 SDK 调起支付宝。alipay.trade.wap.pay依赖浏览器页面跳转。- 三者对应的产品开通条件和应用权限可能不同。
- 三者的同步响应、异步通知和最终状态确认方式也不完全相同。
即使它们都包含订单金额、商户订单号和商品标题等相似字段,也不代表这些接口可以互换。
支付结果处理注意事项
不要只相信前端结果
APP SDK 返回成功,或者 WAP 页面跳转到 return_url,都不代表商户服务端已经确认收款。服务端应验证支付宝的异步通知,必要时调用:
alipay.trade.query
查询订单的最终状态。
做好幂等处理
同一个 out_trade_no 可能因为网络重试、页面刷新或重复扫码而被多次提交。创建订单、处理通知和更新支付状态时都要做好幂等控制,避免重复记账或重复发货。
正确验签并核对订单
处理异步通知时,至少要完成以下检查:
- 验证支付宝签名。
- 核对
app_id。 - 核对
out_trade_no。 - 核对订单金额和币种。
- 检查交易状态。
- 防止同一通知被重复处理。
付款码支付要处理不确定状态
调用 alipay.trade.pay 时,可能出现网络超时、用户需要输入密码或交易仍在处理等情况。此时不能直接判定支付失败并再次扣款,而应根据返回码和子错误码,决定查询、撤销还是等待。
可以采用类似流程:
调用 alipay.trade.pay
|
+-- 明确成功:订单置为已支付
|
+-- 明确失败:订单置为支付失败
|
+-- 状态未知:调用 alipay.trade.query
|
+-- 已支付:更新订单
|
+-- 未支付且需要关闭:按业务规则撤销或关闭
哪些错误码需要查询或撤销,应以当前接入产品的支付宝开放平台文档为准。不能只根据 HTTP 请求是否成功来判断交易结果。
总结
alipay.trade.pay 用于付款码收款,alipay.trade.app.pay 用于原生 App 支付,alipay.trade.wap.pay 用于手机网页支付。它们对应不同的支付入口和交互流程,不能通用替换。
商户可以在自己的支付业务层统一订单模型、金额校验、幂等机制、通知验签和状态查询。真正调用支付宝时,仍要根据付款码、原生 App 或 H5 场景选择相应接口。
备注:内容仅供参考。
