How to Integrate Third-Party Payment Like Alipay in the Mall Project
To integrate Alipay into the Mall project, add the Alipay SDK dependency in mall-portal/pom.xml, configure credentials via AlipayConfig, implement the payment logic in AlipayServiceImpl, and expose REST endpoints through AlipayController to handle desktop payments, mobile wallets, asynchronous notifications, and transaction queries.
The Mall repository by macrozheng provides a production-ready reference implementation for integrating third-party payment like Alipay into a Spring Boot e-commerce platform. The implementation follows a clean layered architecture that isolates payment concerns within the mall-portal module, making it straightforward to swap providers or add additional gateways such as WeChat Pay.
Architecture Overview
The Alipay integration spans four distinct layers within the mall-portal module. The configuration layer (AlipayConfig) externalizes credentials and URLs. The domain layer (AliPayParam) defines the contract for payment requests. The service layer (AlipayServiceImpl) encapsulates SDK interactions, signature verification, and order state management. Finally, the controller layer (AlipayController) exposes HTTP endpoints that return HTML forms for browser redirection and handle server-to-server callbacks.
Step-by-Step Integration Guide
Follow these steps to activate Alipay payments in your Mall instance:
-
Add the SDK dependency in
mall-portal/pom.xmlusing the${alipay-sdk.version}property. -
Configure Alipay properties in
application.yml(gateway URL, App ID, private/public keys, charset, sign type, and callback URLs). -
Enable configuration binding by ensuring
AlipayConfigis annotated with@Componentand@ConfigurationProperties(prefix = "alipay"). -
Define the request DTO (
AliPayParam) to captureoutTradeNo,subject, andtotalAmount. -
Implement the service contract in
AlipayServiceImpl, injectingAlipayConfig,AlipayClient, andOmsPortalOrderService. -
Create the controller (
AlipayController) mapping/alipay/pay,/alipay/webPay,/alipay/notify, and/alipay/query. -
Ensure order service integration by verifying that
OmsPortalOrderService.paySuccessByOrderSnis available to update order status upon successful payment. -
Test the flow by triggering a payment, validating the asynchronous notification signature, and querying the trade status.
Core Implementation Components
Adding the Alipay SDK Dependency
Declare the Alipay SDK in the mall-portal module’s Maven configuration. The project manages the version through a property to ensure consistency across environments.
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>${alipay-sdk.version}</version>
</dependency>
Source: mall-portal/pom.xml
Configuring Alipay Credentials
Externalize all sensitive parameters and endpoint URLs in application.yml. The AlipayConfig class maps these properties to a Spring bean using @ConfigurationProperties.
alipay:
gatewayUrl: https://openapi.alipay.com/gateway.do
appId: your_app_id
appPrivateKey: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
alipayPublicKey: |
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
returnUrl: http://yourdomain.com/alipay/return
notifyUrl: http://yourdomain.com/alipay/notify
charset: UTF-8
signType: RSA2
Source: AlipayConfig.java
Implementing the Payment Service
The AlipayServiceImpl class implements the AlipayService interface, providing methods for pay, webPay, notify, and query. It constructs SDK requests and returns HTML forms for client-side redirection.
Desktop Payment Generation:
@Override
public String pay(AliPayParam param) {
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setReturnUrl(alipayConfig.getReturnUrl());
request.setNotifyUrl(alipayConfig.getNotifyUrl());
JSONObject bizContent = new JSONObject();
bizContent.put("out_trade_no", param.getOutTradeNo());
bizContent.put("subject", param.getSubject());
bizContent.put("total_amount", param.getTotalAmount());
bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
request.setBizContent(bizContent.toString());
return alipayClient.pageExecute(request).getBody();
}
Asynchronous Notification Handling:
The notify method validates the callback signature using AlipaySignature.rsaCheckV1 and updates the order status only when trade_status equals TRADE_SUCCESS.
@Override
public String notify(Map<String, String> params) {
try {
boolean verified = AlipaySignature.rsaCheckV1(
params,
alipayConfig.getAlipayPublicKey(),
alipayConfig.getCharset(),
alipayConfig.getSignType());
if (verified && "TRADE_SUCCESS".equals(params.get("trade_status"))) {
portalOrderService.paySuccessByOrderSn(
params.get("out_trade_no"), 1);
return "success";
}
} catch (AlipayApiException e) {
log.error("Alipay notify verification error", e);
}
return "failure";
}
Transaction Status Query:
The query method allows synchronous verification of a payment state by calling the Alipay query API and updating the local order record when the remote status confirms success.
@Override
public String query(String outTradeNo, String tradeNo) {
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
JSONObject biz = new JSONObject();
if (StringUtils.isNotEmpty(outTradeNo))
biz.put("out_trade_no", outTradeNo);
if (StringUtils.isNotEmpty(tradeNo))
biz.put("trade_no", tradeNo);
request.setBizContent(biz.toString());
AlipayTradeQueryResponse resp = alipayClient.execute(request);
if (resp.isSuccess() && "TRADE_SUCCESS".equals(resp.getTradeStatus())) {
portalOrderService.paySuccessByOrderSn(outTradeNo, 1);
}
return resp.getTradeStatus();
}
Source: AlipayServiceImpl.java
Exposing REST Endpoints
The AlipayController routes HTTP requests to the service layer. For payment endpoints, it sets the response content type to text/html and writes the generated Alipay form directly to the output stream, triggering an immediate browser redirect to the Alipay gateway.
@Autowired
private AlipayService alipayService;
@Autowired
private AlipayConfig alipayConfig;
@ApiOperation("Alipay desktop payment")
@RequestMapping(value = "/pay", method = RequestMethod.GET)
public void pay(AliPayParam param, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=" + alipayConfig.getCharset());
resp.getWriter().write(alipayService.pay(param));
}
@ApiOperation("Alipay async notification")
@RequestMapping(value = "/notify", method = RequestMethod.POST)
public String notify(HttpServletRequest request) {
Map<String, String> params = new HashMap<>();
// extract params from request...
return alipayService.notify(params);
}
Source: AlipayController.java
Summary
- The Alipay integration resides entirely within the
mall-portalmodule, avoiding coupling with core domain logic. - AlipayConfig externalizes all credentials and URLs, enabling environment-specific configurations without code changes.
- AlipayServiceImpl handles three critical flows: generating payment forms (
pay/webPay), verifying callback signatures (notify), and synchronizing transaction states (query). - The controller returns raw HTML forms to facilitate immediate browser redirection to Alipay’s sandbox or production environment.
- Signature verification via
AlipaySignature.rsaCheckV1is mandatory in the notification handler to prevent spoofing attacks before callingpaySuccessByOrderSn.
Frequently Asked Questions
How does the Mall project secure Alipay callback notifications?
The notify method in AlipayServiceImpl validates every incoming request using AlipaySignature.rsaCheckV1, which checks the RSA signature against the configured alipayPublicKey. Only after verification succeeds and the trade_status equals TRADE_SUCCESS does the service invoke portalOrderService.paySuccessByOrderSn to update the order. This prevents fraudulent status updates from unauthorized sources.
What is the difference between pay and webPay methods in the Mall Alipay integration?
The pay method generates a form for desktop web payments using AlipayTradePagePayRequest, while webPay (if implemented similarly) targets mobile web or WAP clients using AlipayTradeWapPayRequest. Both methods construct a BizContent JSON object containing out_trade_no, subject, and total_amount, but they specify different product codes to optimize the checkout experience for the respective device type.
How do I test Alipay integration without real transactions?
Configure the gatewayUrl in AlipayConfig to point to the Alipay sandbox environment (https://openapi.alipaydev.com/gateway.do) instead of the production URL. Obtain sandbox credentials (App ID, private key, and Alipay public key) from the Alipay Open Platform console, then set the notifyUrl to an accessible endpoint (via ngrok or similar) to receive test callbacks locally.
Can I adapt this architecture to integrate WeChat Pay or other providers?
Yes. The Mall project’s layered design allows you to implement a new WechatPayConfig, WechatPayServiceImpl, and WechatPayController following the same pattern: externalize credentials, implement a service interface with pay, notify, and query methods, and expose corresponding REST endpoints. The existing OmsPortalOrderService.paySuccessByOrderSn method can be reused to finalize orders regardless of the payment provider.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →