文章目录
- 自定义支付二维码
- pom.xml
- application.yml
- 自定义二维码类
- AlipayService.java
- AlipayServiceImpl.java
- AlipayController.java
- qrCode.html
自定义支付二维码
继:SpringBoot支付入门
pom.xml
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency><dependency><!--ZXing(Zebra Crossing)核心库,提供了二维码生成和解析的基本功能--><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.4.1</version>
</dependency>
<!--ZXing 的 JavaSE 扩展库,提供了在 Java 环境中生成和解析二维码的更高级功能,例如将二维码保存为图像文件、从图像文件解析二维码等。
-->
<dependency><groupId>com.google.zxing</groupId><artifactId>javase</artifactId><version>3.4.1</version>
</dependency>
application.yml
spring:thymeleaf:enabled: true # 启用Thymeleafcache: false # 禁用Thymeleaf缓存,方便开发时查看修改的效果prefix: classpath:/static/html/ # Thymeleaf模板文件所在目录,默认classpath:/static/html/suffix: .html # Thymeleaf模板文件的后缀,默认为.html
自定义二维码类
package com.sin.demo.utils;import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;/*** @createTime 2024/4/17 10:07* @createAuthor SIN* @use 二维码创建工具类*/
public class QRCodeUtil {private static final int WIDTH = 300; // 二维码宽度private static final int HEIGHT = 300; // 二维码高度private static final String FORMAT = "png"; // 二维码格式/*** 生成二维码* @param text 二维码内容,一定是互联网内容,本地是无法扫的到的* @param filePath 二维码生成地址*/public static void generateQRCode(String text, String filePath) {try {// 创建一个存储编码参数的 HashMap 对象Map<EncodeHintType, Object> hints = new HashMap<>();// 设置字符集为 UTF-8hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");// 设置容错级别为 Mhints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);// 设置边距为 2hints.put(EncodeHintType.MARGIN, 2);// 使用 MultiFormatWriter 类将指定文本 text 编码为二维码矩阵BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);// 将二维码矩阵转换为 BufferedImage 对象BufferedImage image = toBufferedImage(bitMatrix);// 创建一个表示目标文件的 File 对象File file = new File(filePath);// 将 BufferedImage 对象保存为图像文件ImageIO.write(image, FORMAT, file);System.out.println("二维码已生成,保存路径:" + filePath);} catch (Exception e) {e.printStackTrace();}}/*** 将二维码矩阵转为可视化图像* @param matrix* @return 生成BufferdImage对象,获得二维码的可视化图像*/private static BufferedImage toBufferedImage(BitMatrix matrix) {// 获取二维码的宽和高int width = matrix.getWidth();int height = matrix.getHeight();// 创建一个新的BufferedImage对象,指定宽和高,已经颜色类型BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {// 获取当前坐标 (x, y) 的像素值(true 表示黑色,false 表示白色)boolean pixel = matrix.get(x, y);// 根据像素值设置对应位置的 RGB 值,将黑色或白色像素点绘制到 BufferedImage 对象中int rgb = pixel ? Color.BLACK.getRGB() : Color.WHITE.getRGB();// 设置x,y坐标和颜色image.setRGB(x, y, rgb);}}// 返回生成的 BufferedImage 对象return image;}
}
AlipayService.java
package com.sin.demo.service;import com.alipay.api.AlipayApiException;/*** @createTime 2024/4/17 8:20* @createAuthor SIN* @use*/
public interface AlipayService {/*** 创建支付订单* @param outTradeNo 订单号* @param totalAmount 支付金额* @param subject 支付标题* @return 返回二维码信息* @throws AlipayApiException*/public String getgenerateQrCode(String outTradeNo,double totalAmount,String subject) throws AlipayApiException;
}
AlipayServiceImpl.java
package com.sin.demo.service.impl;import com.alipay.api.AlipayApiException;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.sin.demo.service.AlipayService;
import com.sin.demo.utils.QRCodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;/*** @createTime 2024/4/17 8:23* @createAuthor SIN* @use*/
@Service
@Slf4j
public class AlipayServiceImpl implements AlipayService {// 从配置文件中获取参数值@Value("${alipay.appId}")private String appId; // 支付宝应用ID@Value("${alipay.privateKey}")private String privateKey; // 商户应用私钥@Value("${alipay.publicKey}")private String publicKey; // 支付宝公钥@Value("${alipay.gatewayUrl}")private String gatewayUrl; // 支付宝网关URL@Overridepublic String getgenerateQrCode(String outTradeNo, double totalAmount, String subject) throws AlipayApiException {// 创建支付宝客户端DefaultAlipayClient client = new DefaultAlipayClient(gatewayUrl, appId, privateKey, "json", "UTF-8", publicKey, "RSA2");// 创建预下单请求对象AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();// 设置测试业务参数request.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\","+ "\"total_amount\":\"" + totalAmount + "\","+ "\"subject\":\"" + subject + "\"}");// 执行预下单请求AlipayTradePrecreateResponse response = client.execute(request);// 判断预下单请求是否成功if (response.isSuccess()) {// 获取生成的支付二维码信息final String qrCode = response.getQrCode();// 打印二维码信息到控制台System.out.println("二维码信息:" + qrCode);// 记录生成支付二维码成功的日志log.info("生成支付二维码成功:{}", response.getBody());// 生成自定义二维码QRCodeUtil.generateQRCode(qrCode,"src/main/resources/static/image/qrcode.png");// 返回生成的支付二维码地址return "支付宝支付二维码地址:" + qrCode;} else {// 记录生成支付二维码失败的日志log.error("生成支付二维码失败:{}", response.getSubMsg());// 返回生成支付二维码失败的信息return "生成支付二维码失败:" + response.getSubMsg();}}
}
AlipayController.java
package com.sin.demo.controller;import com.alipay.api.AlipayApiException;
import com.sin.demo.service.AlipayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;/*** @createTime 2024/4/17 8:28* @createAuthor SIN* @use*/
@Controller
public class AlipayController {@Autowiredprivate AlipayService alipayService;@ResponseBody@GetMapping("/generateQrCode/{outTradeNo}/{totalAmount}/{subject}")public String getGenerateQrCode(@PathVariable("outTradeNo") String outTradeNo,@PathVariable("totalAmount") double totalAmount,@PathVariable("subject")String subject) throws AlipayApiException {String s = alipayService.getgenerateQrCode(outTradeNo, totalAmount, subject);return s;}@GetMapping("/getQrCode")public String getQrCode(){return "qrCode";}}
qrCode.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>支付页面</title>
</head>
<body>
<h1>支付页面</h1>
<div><h2>扫描下方二维码进行支付:</h2><img id="qrCode" src="../image/qrcode.png" alt="支付二维码">
</div>
</body>
</html>