SpringBoot集成支付宝二维码支付接口详解
前言
在电商和移动支付时代,集成支付宝支付功能已成为许多Java应用的必备功能。本文将详细介绍如何在SpringBoot项目中集成支付宝的二维码支付接口,包括从申请支付宝开发者账号到最终实现支付功能的完整流程。
一、准备工作
1. 注册支付宝开发者账号
首先需要访问支付宝开放平台注册开发者账号。
2. 创建应用
登录后进入"开发者中心" → "网页&移动应用" → "创建应用",选择"网页应用"或"移动应用"。
3. 获取必要参数
应用创建成功后,你需要获取以下关键信息:
- APPID:应用的唯一标识
- 应用私钥(APP_PRIVATE_KEY)
- 支付宝公钥(ALIPAY_PUBLIC_KEY)
- 网关地址(GATEWAY_URL)
二、项目配置
1. 添加依赖
在SpringBoot项目的pom.xml中添加支付宝SDK依赖:
<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.22.64.ALL</version>
</dependency>
2. 配置支付宝参数
在application.yml或application.properties中添加配置:
alipay:app-id: 你的APPIDmerchant-private-key: 你的应用私钥alipay-public-key: 支付宝公钥notify-url: 你的异步通知地址return-url: 你的同步跳转地址gateway-url: https://openapi.alipay.com/gateway.dosign-type: RSA2charset: UTF-8format: json
3. 创建配置类
@Configuration
public class AlipayConfig {@Value("${alipay.app-id}")private String appId;@Value("${alipay.merchant-private-key}")private String merchantPrivateKey;@Value("${alipay.alipay-public-key}")private String alipayPublicKey;@Value("${alipay.notify-url}")private String notifyUrl;@Value("${alipay.return-url}")private String returnUrl;@Value("${alipay.gateway-url}")private String gatewayUrl;@Value("${alipay.sign-type}")private String signType;@Value("${alipay.charset}")private String charset;@Value("${alipay.format}")private String format;@Beanpublic AlipayClient alipayClient() {return new DefaultAlipayClient(gatewayUrl, appId, merchantPrivateKey, format, charset, alipayPublicKey, signType);}
}
三、实现二维码支付
1. 创建支付服务类
@Service
public class AlipayService {@Autowiredprivate AlipayClient alipayClient;@Value("${alipay.notify-url}")private String notifyUrl;@Value("${alipay.return-url}")private String returnUrl;public String createQrCodePay(String outTradeNo, String totalAmount, String subject, String body) throws AlipayApiException {AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();request.setNotifyUrl(notifyUrl);request.setReturnUrl(returnUrl);JSONObject bizContent = new JSONObject();bizContent.put("out_trade_no", outTradeNo);bizContent.put("total_amount", totalAmount);bizContent.put("subject", subject);bizContent.put("body", body);bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");request.setBizContent(bizContent.toJSONString());AlipayTradePrecreateResponse response = alipayClient.execute(request);if(response.isSuccess()){return response.getQrCode();} else {throw new RuntimeException("创建支付二维码失败: " + response.getSubMsg());}}
}
2. 创建控制器
@RestController
@RequestMapping("/api/pay")
public class PayController {@Autowiredprivate AlipayService alipayService;@PostMapping("/createQrCode")public ResponseEntity<?> createQrCode(@RequestBody PayRequest payRequest) {try {// 生成订单号String outTradeNo = "ORDER_" + System.currentTimeMillis();String qrCode = alipayService.createQrCodePay(outTradeNo, payRequest.getAmount().toString(), payRequest.getSubject(), payRequest.getBody());return ResponseEntity.ok(new PayResponse(outTradeNo, qrCode));} catch (AlipayApiException e) {return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("支付二维码生成失败: " + e.getMessage());}}@Datapublic static class PayRequest {private BigDecimal amount;private String subject;private String body;}@Data@AllArgsConstructorpublic static class PayResponse {private String orderNo;private String qrCode;}
}
四、处理支付结果通知
支付宝支付成功后,会通过异步通知(notifyUrl)和同步跳转(returnUrl)两种方式通知支付结果。
1. 异步通知处理
@RestController
@RequestMapping("/api/pay")
public class PayNotifyController {@Value("${alipay.alipay-public-key}")private String alipayPublicKey;@PostMapping("/notify")public String notify(HttpServletRequest request) throws AlipayApiException {Map<String, String> params = convertRequestParamsToMap(request);boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8", "RSA2");if(signVerified) {// 验证成功,处理业务逻辑String tradeStatus = params.get("trade_status");String outTradeNo = params.get("out_trade_no");String tradeNo = params.get("trade_no");String totalAmount = params.get("total_amount");if("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {// 支付成功,更新订单状态// orderService.updateOrderStatus(outTradeNo, "PAID");return "success";}}return "failure";}private Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {Map<String, String> params = new HashMap<>();Map<String, String[]> requestParams = request.getParameterMap();for (String name : requestParams.keySet()) {String[] values = requestParams.get(name);String valueStr = "";for (int i = 0; i < values.length; i++) {valueStr = (i == values.length - 1) ? valueStr + values[i]: valueStr + values[i] + ",";}params.put(name, valueStr);}return params;}
}
2. 同步跳转处理
@Controller
@RequestMapping("/api/pay")
public class PayReturnController {@Value("${alipay.alipay-public-key}")private String alipayPublicKey;@GetMapping("/return")public String returnUrl(HttpServletRequest request, Model model) throws AlipayApiException {Map<String, String> params = convertRequestParamsToMap(request);boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8", "RSA2");if(signVerified) {String outTradeNo = params.get("out_trade_no");String totalAmount = params.get("total_amount");model.addAttribute("outTradeNo", outTradeNo);model.addAttribute("totalAmount", totalAmount);return "paySuccess"; // 跳转到支付成功页面} else {return "payFailure"; // 跳转到支付失败页面}}// convertRequestParamsToMap方法同上
}
五、前端集成
1. 调用后端接口获取二维码
// 使用axios调用后端接口
axios.post('/api/pay/createQrCode', {amount: 100.00,subject: '测试商品',body: '测试商品描述'
}).then(response => {const { orderNo, qrCode } = response.data;// 显示二维码document.getElementById('qrcode').src = `data:image/png;base64,${qrCode}`;// 开始轮询支付状态checkPaymentStatus(orderNo);
}).catch(error => {console.error('生成二维码失败:', error);
});
2. 轮询支付状态
function checkPaymentStatus(orderNo) {const interval = setInterval(() => {axios.get(`/api/pay/status?orderNo=${orderNo}`).then(response => {if(response.data.paid) {clearInterval(interval);alert('支付成功');// 跳转到成功页面window.location.href = '/order/success?orderNo=' + orderNo;}}).catch(error => {console.error('查询支付状态失败:', error);clearInterval(interval);});}, 3000); // 每3秒查询一次
}
六、测试与上线
1. 沙箱环境测试
支付宝提供沙箱环境用于测试,配置网关地址为:
https://openapi.alipaydev.com/gateway.do
2. 生产环境上线
测试通过后,修改配置为生产环境网关:
https://openapi.alipay.com/gateway.do