Step-by-Step Alipay Payment Integration in Java with Spring Boot
This guide walks through configuring the Alipay sandbox, adding Maven dependencies, setting up application.yml, implementing Java configuration classes, creating controller endpoints for payment, handling asynchronous callbacks, processing refunds, and using RabbitMQ delayed queues to auto‑cancel unpaid orders, all with complete code examples.
This article provides a comprehensive tutorial for integrating Alipay payment services into a Java Spring Boot backend.
Web Operation Steps (Alipay Sandbox)
1. Log in to the Alipay Open Platform sandbox environment.
2. Enter the sandbox and configure the interface signing method, choosing the system default key.
3. Set up an application gateway to receive asynchronous notifications from Alipay.
4. Generate your own RSA key pair if needed.
IDEA Project Setup
1. Import Dependency
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.22.110.ALL</version>
</dependency>2. Configure application.yml
alipay:
appId:
appPrivateKey:
alipayPublicKey:
notifyUrl: (callback URL)3. Java Configuration Class (AlipayConfig.java)
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayConfig {
private String appId;
private String appPrivateKey;
private String alipayPublicKey;
private String notifyUrl;
}Payment Controller (AliPayController.java)
@Data
public class AliPay {
private String traceNo;
private double totalAmount;
private String subject;
private String alipayTraceNo;
}
private static final String GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";
private static final String FORMAT = "JSON";
private static final String CHARSET = "UTF-8";
private static final String SIGN_TYPE = "RSA2";
@Resource
private AlipayConfig alipayConfig;
@Resource
private OrdersMapper ordersMapper;
@GetMapping("/pay")
public void pay(AliPay aliPay, HttpServletResponse httpResponse) throws Exception {
AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, alipayConfig.getAppId(), alipayConfig.getAppPrivateKey(), FORMAT, CHARSET, alipayConfig.getAlipayPublicKey(), SIGN_TYPE);
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setNotifyUrl(alipayConfig.getNotifyUrl());
JSONObject bizContent = new JSONObject();
bizContent.set("out_trade_no", aliPay.getTraceNo());
bizContent.set("total_amount", aliPay.getTotalAmount());
bizContent.set("subject", aliPay.getSubject());
bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY");
request.setBizContent(bizContent.toString());
String form = alipayClient.pageExecute(request).getBody();
httpResponse.setContentType("text/html;charset=" + CHARSET);
httpResponse.getWriter().write(form);
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
}Callback Interface
@PostMapping("/notify") // must be POST
public String payNotify(HttpServletRequest request) throws Exception {
if ("TRADE_SUCCESS".equals(request.getParameter("trade_status"))) {
Map
params = new HashMap<>();
for (String name : request.getParameterMap().keySet()) {
params.put(name, request.getParameter(name));
}
String sign = params.get("sign");
String content = AlipaySignature.getSignCheckContentV1(params);
boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, alipayConfig.getAlipayPublicKey(), "UTF-8");
if (checkSignature) {
// update order status to paid
ordersMapper.updateState(params.get("out_trade_no"), "已支付", params.get("gmt_payment"), params.get("trade_no"));
}
}
return "success";
}Refund Process
@GetMapping("/return")
public Result returnPay(AliPay aliPay) throws AlipayApiException {
// check 7‑day refund window
// create client and request
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
JSONObject bizContent = new JSONObject();
bizContent.set("trade_no", aliPay.getAlipayTraceNo());
bizContent.set("refund_amount", aliPay.getTotalAmount());
bizContent.set("out_request_no", aliPay.getTraceNo());
request.setBizContent(bizContent.toString());
AlipayTradeRefundResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
ordersMapper.updatePayState(aliPay.getTraceNo(), "已退款", DateUtil.now());
return Result.success();
} else {
return Result.error(response.getCode(), response.getBody());
}
}Automatic Order Cancellation (30‑minute timeout) Using RabbitMQ Delayed Queue
The article explains how to configure RabbitMQ with x-message-ttl and dead‑letter exchange/routing‑key to implement a delayed queue that moves messages to a dead‑letter queue after 30 minutes, where a consumer checks the order status and marks unpaid orders as cancelled.
Advantages: high efficiency, horizontal scalability, persistence for reliability.
Disadvantages: added operational complexity and cost due to RabbitMQ management.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.