Java支付宝支付案例开发全流程详解(附核心代码)
目录导读
开发前准备:支付宝开放平台与沙箱环境
在整合支付宝支付前,必须完成两项基础配置:应用创建与密钥生成。
很多新手踩坑是因为没区分“开放平台”和“商家平台”——用于扫码支付、App支付的是“开放平台”。

1 创建应用并获取配置
- 登录支付宝开放平台 → 进入“控制台” → 选择“创建应用” → 选择“网页/移动应用”类型。
- 添加功能:勾选“手机网站支付”或“电脑网站支付”,提交审核(沙箱环境无需审核)。
- 设置接口加签方式:推荐使用RSA2(SHA256),生成公私钥对,将公钥上传到平台,并获得支付宝公钥。
2 沙箱环境配置(测试利器)
- 使用沙箱版支付宝(App可扫码测试),无需真实资金流转。
- 沙箱网关:
https://openapi-sandbox.dl.alipaydev.com/gateway.do - 沙箱应用的AppId、商户UID均与线上不同,必须单独配置。
项目搭建:Maven依赖与核心配置
选择Spring Boot + Alipay SDK (Easy版),能省去大量签名与网络调用代码。
1 引入Maven依赖
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.38.75.ALL</version>
</dependency>
注意:版本号请从Maven中央仓库获取最新稳定版,避免旧版SDK的接口变动。
2 配置文件(application.yml)
alipay: app-id: 20210001226xxxxxxxx private-key: MIIEvQIBADANBgkqhkiG9w0BAQEFAAS... # 商户私钥 alipay-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ... # 支付宝公钥 gateway-url: https://openapi-sandbox.dl.alipaydev.com/gateway.do notify-url: https://yourdomain.com/api/alipay/notify # 回调通知地址 return-url: https://yourdomain.com/pay/success
⚠️ 私钥绝不能泄露到前端或版本库中;生产环境的密钥需要从服务器环境变量读取。
3 初始化AlipayClient Bean
@Configuration
public class AlipayConfig {
@Bean
public AlipayClient alipayClient(@Value("${alipay.app-id}") String appId,
@Value("${alipay.private-key}") String privateKey,
@Value("${alipay.gateway-url}") String gatewayUrl) {
return new DefaultAlipayClient(gatewayUrl, appId, privateKey, "json", "UTF-8",
alipayPublicKey, "RSA2");
}
}
支付核心逻辑:下单与签名
下单接口通常由后端发起,构建并发送请求,返回给前端一个 form表单 或 tradeNo。
1 构建支付请求(示例:手机网站支付)
public String createPayOrder(String orderNo, BigDecimal amount, String subject) {
AlipayClient alipayClient = getAlipayClient();
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
// 基础参数
request.setNotifyUrl(notifyUrl);
request.setReturnUrl(returnUrl);
// 业务参数(JSON结构)
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setOutTradeNo(orderNo);
model.setTotalAmount(amount.toString());
model.setSubject(subject);
model.setProductCode("QUICK_WAP_WAY"); // 手机网站支付产品码
model.setQuitUrl("https://yourdomain.com/order/detail"); // 支付中途退出跳转
request.setBizModel(model);
// 执行调用,获取页面自动提交的HTML表单
AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
return response.getBody(); // 直接返回给前端,浏览器自动跳转
}
2 签名过程(SDK已自动处理)
- 开发者不需要手动签名:
DefaultAlipayClient在构建请求时会自动使用私钥签名。 - 关键是确保私钥格式正确(PKCS8),且支付宝公钥与商户公钥准确互换。
异步通知处理:验签与回调
支付宝支付成功后,会异步POST到notify_url,此环节是“必须验签”的关键节点。
1 验签与回调处理代码
@PostMapping("/api/alipay/notify")
public String handleNotify(HttpServletRequest request) {
// 1. 获取所有参数(包括签名)
Map<String, String> params = new HashMap<>();
request.getParameterMap().forEach((key, values) -> params.put(key, values[0]));
// 2. 验签:使用支付宝公钥校验
boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8", "RSA2");
if (!signVerified) {
return "failure"; // 必须返回"failure",否则支付宝会重复通知
}
// 3. 校验必要字段(防伪造)
String tradeStatus = params.get("trade_status");
String outTradeNo = params.get("out_trade_no");
String totalAmount = params.get("total_amount");
if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
// 4. 业务处理:更新订单状态、发货等(保持幂等性)
orderService.updateOrderPayed(outTradeNo, new BigDecimal(totalAmount));
}
return "success"; // 通知成功返回"success"
}
2 关键要点(必读)
- 只处理
TRADE_SUCCESS或TRADE_FINISHED状态:其他状态如等待付款,不要更新订单。 - 重复通知处理:支付宝会最多通知8次,业务接口必须做幂等(例如根据订单状态判断是否已处理)。
- 参数验证要完整:除了验签,还要比对
outTradeNo、totalAmount、appId是否正确,防止重放攻击。
常见支付异常排查与Q&A
Q1:调用下单接口报错“验签失败”
原因分析:
- 私钥文件格式错误(必须为PKCS8,无换行)。
- 上传到支付宝平台的公钥与代码中配置的支付宝公钥不一致。
- 字符编码不一致(确保所有地方使用UTF-8)。
解决方案:
- 使用支付宝官方提供的
密钥工具重新生成RSA2密钥对,严格按文档格式复制。 - 检查公钥是否包含
-----BEGIN PUBLIC KEY-----等标记。
Q2:异步通知收不到怎么办?
排查步骤:
- 检查
notify_url是否公网可访问(内网需使用内网穿透工具)。 - 确认接口返回的是
success而非success以外的字符串(包括大小写)。 - 查看支付宝开放平台“沙箱案例”中的“通知记录”是否有回调。
- 检查防火墙是否拦截了POST请求。
Q3:支付成功后订单状态未更新
常见Bug:
- 通知处理中未对
out_trade_no做去重,导致重复更新异常。 - 使用了
TRADE_FINISHED才更新支付状态(该状态表示交易已完成且不可退款,较晚收到)。
推荐做法:
- 优先以
TRADE_SUCCESS为准,完成付款就立即更新订单。 - 在更新SQL中增加
WHERE status = 0条件保证幂等。
Q4:是否需要自己实现签名?
- 无需手动签名,官方SDK的
AlipayClient自动处理,只有极特殊情况(如使用原生HttpClient)才需自己拼接签名串。 - 如果你必须自己实现,参考支付宝文档的“签名流程”:将参数按ASCII排序 → URL键值对拼接 → 拼接后加私钥签名 → 生成签名串。
Q5:退款接口如何实现?
AlipayClient alipayClient = getAlipayClient();
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
AlipayTradeRefundModel model = new AlipayTradeRefundModel();
model.setOutTradeNo(orderNo);
model.setRefundAmount(amount.toString());
model.setRefundReason("用户主动退款");
request.setBizModel(model);
AlipayTradeRefundResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
// 退款成功,更新订单状态为已退款
}
⚠️ 退款金额不能超过订单的实际支付金额,且需考虑部分退款场景。
Java支付宝支付开发全流程
- 环境准备:注册开放平台、创建应用、配置沙箱和密钥。
- 框架集成:Maven引入SDK、配置AlipayClient Bean。
- 下单逻辑:构建业务Model,调用
pageExecute生成支付链接。 - 回调处理:接收异步通知、验签、校验状态、幂等更新订单。
- 扩展功能:退款、查询、对账等。
核心原则:所有涉及金额的接口必须经过验签;所有的通知处理必须幂等;所有敏感配置(私钥)必须从环境变量读取。
只要遵循以上流程,无论你是Spring Boot、Spring Cloud还是传统Servlet项目,都能快速落地支付宝支付功能。