alipay-sdk-java-v3 是否支持 APP 支付及各支付方式调用方法
明确结论
alipay-sdk-java-v3 能否直接发起 APP 支付,要看具体的 SDK 版本,以及其中是否包含 AlipayTradeAppPayRequest。
常见的支付宝 Java SDK 通过以下接口生成 APP 支付参数:
alipay.trade.app.pay
对应的请求类是:
AlipayTradeAppPayRequest
服务端调用 AlipayClient.sdkExecute() 后,会得到一段已签名的 orderString。这一步并不会直接完成支付。服务端需要把该字符串返回给 Android 或 iOS 客户端,再由支付宝客户端 SDK 拉起支付宝完成付款。
SDK 示例没有明确标注支付方式,是因为支付宝 Java SDK 通常封装了多种交易接口。判断支付方式时,应查看请求类和 API 名称,不能只看 SDK 初始化代码。
APP 支付的调用方式
以下代码以常见的支付宝 Java SDK 接口为例。不同版本的模型类字段可能略有差异,请以当前安装版本的类定义和支付宝开放平台接口文档为准。
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
public class AlipayAppPayExample {
public static String createOrder() 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"
);
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setOutTradeNo("ORDER_202609090001");
model.setSubject("测试商品");
model.setTotalAmount("0.01");
model.setProductCode("QUICK_MSECURITY_PAY");
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
request.setBizModel(model);
request.setNotifyUrl("https://example.com/alipay/notify");
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
if (!response.isSuccess()) {
throw new IllegalStateException(
"生成 APP 支付参数失败:" + response.getSubCode()
+ " - " + response.getSubMsg()
);
}
// 将该字符串原样返回给 Android 或 iOS 客户端
return response.getBody();
}
}
APP 支付应使用 sdkExecute(),不能使用普通的 execute()。alipay.trade.app.pay 要生成一组完整的签名参数,供移动端支付宝 SDK 调用,并不是由服务端直接向支付宝提交付款。
客户端收到 response.getBody() 后,应将其原样交给支付宝客户端 SDK。不要在前端重新拼接、解析或修改其中的字段,否则可能导致验签失败。
常见支付方式与请求类
支付宝的不同支付方式对应不同的接口和请求类:
| 支付场景 | API | Java 请求类 | 常见调用方法 |
|---|---|---|---|
| APP 支付 | alipay.trade.app.pay | AlipayTradeAppPayRequest | sdkExecute() |
| 手机网站支付 | alipay.trade.wap.pay | AlipayTradeWapPayRequest | pageExecute() |
| 电脑网站支付 | alipay.trade.page.pay | AlipayTradePagePayRequest | pageExecute() |
| 当面付二维码 | alipay.trade.precreate | AlipayTradePrecreateRequest | execute() |
| 商家扫码或付款码支付 | alipay.trade.pay | AlipayTradePayRequest | execute() |
| 交易查询 | alipay.trade.query | AlipayTradeQueryRequest | execute() |
| 交易退款 | alipay.trade.refund | AlipayTradeRefundRequest | execute() |
| 交易关闭 | alipay.trade.close | AlipayTradeCloseRequest | execute() |
这三个调用方法可以按返回内容来区分:
sdkExecute()生成客户端 SDK 所需的签名参数,典型场景是 APP 支付。pageExecute()生成表单或跳转地址,典型场景是电脑网站支付和手机网站支付。execute()由服务端直接请求支付宝开放接口,常用于查询、退款、预创建二维码和付款码支付。
手机网站支付示例
手机浏览器中的支付不属于 APP 支付,应使用 alipay.trade.wap.pay:
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
request.setBizContent("""
{
"out_trade_no": "ORDER_202609090002",
"total_amount": "0.01",
"subject": "测试商品",
"product_code": "QUICK_WAP_WAY",
"quit_url": "https://example.com/pay/cancel"
}
""");
request.setReturnUrl("https://example.com/pay/result");
request.setNotifyUrl("https://example.com/alipay/notify");
String form = alipayClient.pageExecute(request).getBody();
返回内容通常是一段可提交的 HTML 表单。Web 项目可以将其写入 HTTP 响应,让浏览器跳转到支付宝收银台。
电脑网站支付示例
电脑网站支付使用 alipay.trade.page.pay:
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setBizContent("""
{
"out_trade_no": "ORDER_202609090003",
"total_amount": "0.01",
"subject": "测试商品",
"product_code": "FAST_INSTANT_TRADE_PAY"
}
""");
request.setReturnUrl("https://example.com/pay/result");
request.setNotifyUrl("https://example.com/alipay/notify");
String form = alipayClient.pageExecute(request).getBody();
电脑网站支付和手机网站支付都调用 pageExecute(),但两者使用的请求类、API 和 product_code 不同,不能只替换页面地址。
当面付二维码示例
如果需要由商家生成二维码,再让用户使用支付宝扫码付款,可以调用 alipay.trade.precreate:
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
request.setBizContent("""
{
"out_trade_no": "ORDER_202609090004",
"total_amount": "0.01",
"subject": "测试商品"
}
""");
request.setNotifyUrl("https://example.com/alipay/notify");
AlipayTradePrecreateResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
String qrCode = response.getQrCode();
// 将 qrCode 转换成二维码后展示给用户
}
如何确认当前 SDK 是否支持
先检查项目依赖中有没有以下两个类:
com.alipay.api.request.AlipayTradeAppPayRequest
com.alipay.api.response.AlipayTradeAppPayResponse
如果这两个类存在,通常可以通过 AlipayTradeAppPayRequest + sdkExecute() 生成 APP 支付参数。
如果不存在,不要自行仿造请求类,而应核对以下信息:
- Maven 或 Gradle 中实际使用的支付宝 SDK 坐标和版本。
- 当前 SDK 面向支付宝开放平台传统接口,还是新版 OpenAPI。
- 已开通的产品是否包含 APP 支付能力。
- SDK 是否提供
alipay.trade.app.pay对应的请求模型。 - 应用的签约状态、密钥类型和网关环境是否正确。
不同年代的 SDK 在包名、构造方法、证书模式配置和响应模型上可能有所不同,不能只凭“v3”这个名称判断调用方式。应以实际依赖版本、请求类和对应的 API 文档为准。
注意事项
APP_PRIVATE_KEY是商户应用私钥,必须保存在服务端,不能下发到 APP。ALIPAY_PUBLIC_KEY是支付宝公钥,不是应用公钥。使用证书模式时,需要采用不同的初始化方式。- 生产环境网关通常为
https://openapi.alipay.com/gateway.do。沙箱环境必须使用与沙箱应用匹配的网关、账号和密钥。 out_trade_no必须由商户系统生成,并在商户范围内保持唯一。- 金额建议使用字符串或
BigDecimal处理,避免用double进行金额运算。 - APP 展示的同步支付结果不能作为最终入账依据。订单状态应以服务端异步通知的验签结果,或主动调用
alipay.trade.query得到的查询结果为准。 - 异步通知处理成功后,需要按照支付宝接口要求返回成功响应,否则支付宝可能重复发送通知。
- 接收异步通知时必须验证签名,同时核对
app_id、out_trade_no、total_amount、seller_id等字段。 - APP 支付、手机网站支付和电脑网站支付属于不同的产品能力。SDK 中存在相应的请求类,不代表当前支付宝应用已经签约或开通该能力。
备注:内容仅供参考。
