支付宝支付之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>
相关推荐
XiaoLeisj2 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck2 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei2 小时前
java的类加载机制的学习
java·学习
码农小旋风3 小时前
详解K8S--声明式API
后端
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml44 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~4 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616884 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7894 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java5 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet