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

文章目录

  • 自定义支付二维码
    • 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  # 启用Thymeleaf
    cache: 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-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

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


    @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

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

<!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>

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/554915.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大语言模型微调技术

Adapter 参考资料&#xff1a;《Parameter-efficient transfer learning for nlp》 adpater首先将原始的d维特征映射到较小的维度m&#xff0c;应用非线性函数&#xff0c;然后再重新映射回d维。总的参数量&#xff08;包含biases&#xff09;为 2mddm&#xff0c; 当m远小于d…

算法打卡day38

今日任务&#xff1a; 1&#xff09;完全背包理论基础(卡码网52. 携带研究材料) 2&#xff09;518.零钱兑换II 3&#xff09;377. 组合总和 Ⅳ 4&#xff09;复习day13 完全背包理论基础(卡码网52. 携带研究材料) 题目链接&#xff1a;52. 携带研究材料&#xff08;第七期模拟…

以大学生活为主题的演讲稿(3篇)

以大学生活为主题的演讲稿&#xff08;3篇&#xff09; 以下是三篇以大学生活为主题的演讲稿范文&#xff0c;供您参考&#xff1a; 演讲稿一&#xff1a;拥抱大学生活&#xff0c;绽放青春梦想 尊敬的老师、亲爱的同学们&#xff1a; 大家好&#xff01; 今天&#xff0c;我…

VLAN知识点总结

首先对交换机等设备进行了解 中继器&#xff1a;物理层设备 只能提供电流信息的电压恢复&#xff0c;但无法恢复波形&#xff0c;所以无法理论无限延长传输距离 集线器&#xff1a;物理层设备 多接口的中继器 二层交换机的作用&#xff1a; 区别集线器&#xff08;HUB&#…

【问题处理】银河麒麟操作系统实例分享,服务器操作系统VNC远程问题分析

1.服务器环境以及配置 【内核版本】 4.19.90-23.8.v2101.ky10.aarch64 【OS镜像版本】 0518-server 2.问题现象描述 服务器通过vncserver:1.service服务启动的vnc服务后&#xff0c;普通用户用vnc连接时&#xff0c;锁屏后&#xff0c;然后输入登陆密码会报密码错误&…

五款3dmax常用插件推荐(含云渲染工具)

在三维建模和动画设计领域&#xff0c;3ds Max软件因其强大功能和灵活性而广受欢迎。为了进一步提升工作效率和创作质量&#xff0c;有许多插件可供选择。本文推荐五款常用3ds Max插件&#xff0c;帮助你更好实现复杂的模型和动效创作。 五款3dmax常用插件推荐 1、Kitchen Cab…

RocketMQ并发消息消费重试DEMO

无序消息的重试只针对集群消费模式生效&#xff1b;广播消费模式不提供失败重试特性 Producer 发了100个对象消息 public class AddProducer {public static void main(String[] args) throws Exception {DefaultMQProducer producer new DefaultMQProducer("a-group&q…

计算机视觉入门:探索机器如何“看见”世界

计算机视觉是人工智能领域的一个令人兴奋的分支&#xff0c;它使计算机能够从图像和视频中“看见”和理解世界。这项技术已经渗透到我们生活的方方面面&#xff0c;从智能手机的面部识别到自动驾驶汽车的导航系统。但是&#xff0c;计算机视觉是如何工作的呢&#xff1f;让我们…

U盘管理软件 设置U盘权限的软件

U盘管理软件 设置U盘权限的软件 我们都知道U盘的功能很强大&#xff0c;携带也很方便&#xff0c;但是它的危险指数也是相当高的&#xff0c;既容易携带病毒&#xff0c;又可以拷贝公司里的保密文件。所以很多企业都很关注对U盘使用的管理&#xff0c;而方法&#xff0c;最好的…

PLSQL的下载与安装

个人介绍 hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的…

色彩的魔力:渐变色在设计中的无限可能性

夕阳&#xff0c;天空&#xff0c;湖面&#xff0c;夕阳...随着距离和光影的变化&#xff0c;颜色的渐变色&#xff0c;近大远小、近实远虚的透视&#xff0c;为大自然营造了浪漫的氛围。延伸到UI/UX设计领域&#xff0c;这种现实、惊艳、独特的渐变色也深受众多设计师的喜爱。…

JavaEE初阶Day 13:多线程(11)

目录 Day 13&#xff1a;多线程&#xff08;11&#xff09;常见的锁策略1. 悲观锁 vs 乐观锁2. 重量级锁 vs 轻量级锁3. 自旋锁 vs 挂起等待锁4. 可重入锁 vs 不可重入锁5. 公平锁 vs 非公平锁6. 互斥锁 vs 读写锁 synchronized实现原理1. 锁升级2. 锁消除3. 锁粗化 CAS Day 13…

“捡到一束光,日落时还给太阳”

数据结构初阶题解 1.移除元素2.合并两个有序数组3.移除链表元素4.反转链表5.合并两个有序链表6.链表的中间结点7.环形链表的约瑟夫问题8.分割链表有感&#xff1a;其实我早就死了&#xff0c;死在破碎的三观里&#xff1b;死在飘渺的理想里&#xff1b;死在幻想的感情里&#x…

[AHK]自定义消息实现两个脚本之间通信

自己编写的两个脚本&#xff0c;用自定义消息实现&#xff0c;一个脚本控制另一个脚本&#xff0c;让被控脚本挂起或退出。 从aaa.ahk向bbb.ahk发送一个消息&#xff0c;bbb.ahk捕获消息后再进行处理&#xff0c;比如&#xff1a; 从aaa.ahk中向bbb.ahk发送特定的数字&#xff…

gpt-6有望成为通用工具

OpenAI CEO山姆奥特曼&#xff08;Sam Altman&#xff09;在最新的博客访谈中&#xff0c;提到gpt-6有望成为通用工具。 奥特曼还认为&#xff0c;目前的模型不够聪明&#xff0c;“使用GPT-2进行科学研究曾被认为是不切实际的想法。而如今&#xff0c;虽然人们使用GPT-4进行科…

短视频评论ID批量爬虫提取获客软件|DY评论下载采集工具

短视频评论批量抓取软件&#xff1a;智能拓客&#xff0c;精准抓取用户反馈 在当今数字化营销时代&#xff0c;了解用户的需求和反馈对于企业的发展至关重要。而作为流行的短视频平台&#xff0c;短视频评论蕴含了丰富的用户信息和市场洞察。为了帮助企业高效获取这些宝贵数据…

一秒内传输50万对纠缠光子?!纽约市量子网络刷新纪录

量子网络技术行业的领军企业Qunnect宣布&#xff0c;在纽约市的GothamQ网络上&#xff0c;其偏振量子比特的传输性能刷新了纪录。Qunnect利用现有的商用光缆实现了每秒传输50万对高保真度纠缠光子的速率&#xff0c;且该网络的正常运行时间超过了99%。 纽约34公里长的GothamQ量…

LIUNX文件系统

目录 1.磁盘的物理结构 2.CHS定位法 3.磁盘的逻辑存储 4.系统层面 inode.block[15] 创建文件的流程 查找文件的流程 了解文件系统&#xff0c;首先要了解磁盘是如何存储和读取数据的。 1.磁盘的物理结构 可以理解这个盘上有很多的小磁铁&#xff0c;通过旋转盘面和摆动…

C# 整数转罗马数字

罗马数字包含以下七种字符:I&#xff0c;V&#xff0c;X&#xff0c;L&#xff0c;C,D和M。 例如&#xff0c;罗马数字2写做 II &#xff0c;即为两个并列的 1。12 写做XII&#xff0c;即为XII。27写做 XXVII,即为XXV II 。 通常情况下&#xff0c;罗马数字中小的数字在大的数字…

显示msvcp140.dll丢失要如何解决?这5种方法高效修复msvcp140.dll

msvcp140.dll是Microsoft Visual C Redistributable软件包中的一个文件&#xff0c;主要用于支持使用C编程语言编写的软件的正常运行。如果你的电脑出现缺少msvcp140.dll的错误消息&#xff0c;可能会影响到某些程序的启动和运行。然而&#xff0c;不必过度担心&#xff0c;因为…