支付宝支付之SpringBoot整合支付宝创建自定义支付二维码

文章目录

自定义支付二维码

继:SpringBoot支付入门

pom.xml

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

yml 复制代码
spring:
  thymeleaf:
    enabled: true  # 启用Thymeleaf
    cache: false    # 禁用Thymeleaf缓存,方便开发时查看修改的效果
    prefix: classpath:/static/html/  # Thymeleaf模板文件所在目录,默认classpath:/static/html/
    suffix: .html   # Thymeleaf模板文件的后缀,默认为.html

自定义二维码类

java 复制代码
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-8
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            // 设置容错级别为 M
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
            // 设置边距为 2
            hints.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

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

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


    @Override
    public 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

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 {

    @Autowired
    private 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

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>
相关推荐
大数据编程之光16 分钟前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
爪哇学长30 分钟前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
ExiFengs34 分钟前
实际项目Java1.8流处理, Optional常见用法
java·开发语言·spring
paj12345678935 分钟前
JDK1.8新增特性
java·开发语言
捂月41 分钟前
Spring Boot 深度解析:快速构建高效、现代化的 Web 应用程序
前端·spring boot·后端
繁依Fanyi1 小时前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
慧都小妮子1 小时前
Spire.PDF for .NET【页面设置】演示:打开 PDF 时自动显示书签或缩略图
java·pdf·.net
m51271 小时前
LinuxC语言
java·服务器·前端
IU宝1 小时前
C/C++内存管理
java·c语言·c++
瓜牛_gn1 小时前
依赖注入注解
java·后端·spring