当前位置: 首页 > java >正文

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
http://www.xdnf.cn/news/17611.html

相关文章:

  • Python3.10 + Firecrawl 下载 Markdown 文档:构建高效通用文章爬虫
  • 不同FPGA开发板系统移植步骤
  • Chrome插件开发【Service Worker练手小项目】
  • 【LeetCode刷题集】--排序(三)
  • 【智能的起源】人类如何模仿,简单的“刺激-反应”机制 智能的核心不是记忆,而是发现规律并能迁移到新场景。 最原始的智能:没有思考,只有简单条件反射
  • Mamba 原理汇总2
  • AI(2)-神经网络(激活函数)
  • 支持小语种的在线客服系统,自动翻译双方语言,适合对接跨境海外客户
  • 数据结构-数组扩容
  • 开发指南130-实体类的主键生成策略
  • Apache ECharts 6 核心技术解密 – Vue3企业级可视化实战指南
  • 排错000
  • 基于 ZooKeeper 的分布式锁实现原理是什么?
  • windows上RabbitMQ 启动时报错:发生系统错误 1067。 进程意外终止。
  • 150V降压芯片DCDC150V100V80V降压12V5V1.5A车载仪表恒压驱动H6203L惠洋科技
  • git:分支
  • 提示词工程实战:用角色扮演让AI输出更专业、更精准的内容
  • 软件测评中HTTP 安全头的配置与测试规范
  • 数据变而界面僵:Vue/React/Angular渲染失效解析与修复指南
  • 基于 Axios 的 HTTP 请求封装文件解析
  • Console Variables Editor插件使用
  • 音视频学习(五十三):音频重采样
  • QT QProcess + xcopy 实现文件拷贝
  • Web安全自动化测试实战指南:Python与Selenium在验证码处理中的应用
  • Mybatis @Param参数传递说明
  • 【工作笔记】Wrappers.lambdaQuery()用法
  • RK3588在YOLO12(seg/pose/obb)推理任务中的加速方法
  • JS数组排序算法
  • 打靶日常-upload-labs(21关)
  • 【密码学】8. 密码协议