对接阿里支付宝支付

1. 账号注册

注册地址: 支付宝

文档地址: 小程序文档 - 支付宝文档中心

2.登录商家平台

登录地址: https://b.alipay.com/page/portal/home

1. 产品中心 - 当面付 - 申请开通

3. 登录开放平台

访问地址: 支付宝开放平台

1. 控制台 - 网页移动应用

2. 进入应用详情 - 开发设置

3. 设置接口加签方式

4. 下载密钥工具 , 生成密钥 (记录应用私钥, 后面要用到)

5. 记录支付宝公钥

6. 设置接口内容加密方式

4. 支付代码

项目引入Pom

<dependency>
  <groupId>com.alipay.sdk</groupId>
  <artifactId>alipay-sdk-java</artifactId>
  <version>4.39.2.ALL</version>
</dependency>

配置文件

pay:
  ali-pay:
    # 应用ID
    app-id: 
    # 支付宝服务器网关地址
    url: https://openapi.alipay.com/gateway.do
    # 应用私钥
    private-key: 
    # 支付宝公钥
    ali-public-key: 
    # 支付&二维码超时时间/单位:分钟
    time-out: 5
    # 接收结果通知地址.如果路径需要动态替换订单号,则以 {orderNo} 占位
    notify-url: https://xxxxxx/{orderNo}
    # 单笔最大金额
    max-money: 2000
    # 单笔最小金额
    min-money: 0.1
package cn.com.baidu.operator.util.pay;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * 从配置文件读取阿里支付的配置文件
 * 2024年3月21日10:20:50
 * 崔宝铖
 */
@Configuration
@ConfigurationProperties(prefix = "pay.ali-pay")
public class AliPayProperties {

    // 应用ID
    private  String appId;

    // 支付宝服务器地址
    private  String url;

    // 应用私钥
    private  String privateKey;

    // 支付宝公钥
    private  String aliPublicKey;

    // 超时时间
    private  String timeOut;

    // 接收结果通知地址
    private  String notifyUrl;

    // 单笔最大金额
    private Double maxMoney;

    // 单笔最小金额
    private Double minMoney;

    public String getAppId() {
        return appId == null ? "" : appId.trim();
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public String getUrl() {
        return url == null ? "" : url.trim();
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getPrivateKey() {
        return privateKey == null ? "" : privateKey.trim();
    }

    public void setPrivateKey(String privateKey) {
        this.privateKey = privateKey;
    }

    public String getAliPublicKey() {
        return aliPublicKey == null ? "" : aliPublicKey.trim();
    }

    public void setAliPublicKey(String aliPublicKey) {
        this.aliPublicKey = aliPublicKey;
    }

    public String getTimeOut() {
        return timeOut == null ? "5" : timeOut.trim();
    }

    public void setTimeOut(String timeOut) {
        this.timeOut = timeOut;
    }

    public String getNotifyUrl() {
        return notifyUrl == null ? "" : notifyUrl.trim();
    }

    public void setNotifyUrl(String notifyUrl) {
        this.notifyUrl = notifyUrl;
    }

    public Double getMaxMoney() {
        return maxMoney == null ? 2000 : maxMoney;
    }

    public void setMaxMoney(Double maxMoney) {
        this.maxMoney = maxMoney;
    }

    public Double getMinMoney() {
        return minMoney == null ? 0.1 : minMoney;
    }

    public void setMinMoney(Double minMoney) {
        this.minMoney = minMoney;
    }
}
package cn.com.baidu.operator.util.pay;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.domain.AlipayTradeCloseModel;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import cn.com.baidu.exceptions.SaveException;
import cn.com.baidu.exceptions.SearchException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.awt.image.BufferedImage;
import java.text.SimpleDateFormat;

/**
 * 支付宝支付
 * 2024年3月19日15:47:30
 * CBC
 */
@Component
public class ALiPay {

    @Autowired
    private AliPayProperties aliPayProperties;

    private static AliPayProperties aliPayStaticProperties;

    @PostConstruct
    public void init() {
        aliPayStaticProperties = this.aliPayProperties;
    }
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static void closePay(String orderNo) {
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl(aliPayStaticProperties.getUrl());// 支付地址
        alipayConfig.setAppId(aliPayStaticProperties.getAppId());// 应用ID
        alipayConfig.setPrivateKey(aliPayStaticProperties.getPrivateKey());// 应用私钥
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(aliPayStaticProperties.getAliPublicKey());// 支付宝公钥
        alipayConfig.setCharset("UTF-8");
        alipayConfig.setSignType("RSA2");// 编码
        try{
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
            AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
            AlipayTradeCloseModel model = new AlipayTradeCloseModel();
            model.setOutTradeNo(orderNo);
            request.setBizModel(model);
            AlipayTradeCloseResponse response = alipayClient.execute(request);
            if (!response.isSuccess() && !response.getSubMsg().equals("交易不存在")) {
                throw new SearchException(response.getSubMsg());
            }
        }catch(Exception e) {
            throw new SearchException(e.getMessage());
        }
    }

    public static PayResultDTO queryPay(String orderNo) {
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl(aliPayStaticProperties.getUrl());// 支付地址
        alipayConfig.setAppId(aliPayStaticProperties.getAppId());// 应用ID
        alipayConfig.setPrivateKey(aliPayStaticProperties.getPrivateKey());// 应用私钥
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(aliPayStaticProperties.getAliPublicKey());// 支付宝公钥
        alipayConfig.setCharset("UTF-8");
        alipayConfig.setSignType("RSA2");// 编码
        try{
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            AlipayTradeQueryModel model = new AlipayTradeQueryModel();
            model.setOutTradeNo(orderNo);
            request.setBizModel(model);
            AlipayTradeQueryResponse response = alipayClient.execute(request);
            PayResultDTO dto = new PayResultDTO();
            dto.setOrderStatus("0");
            dto.setOrderNo(response.getOutTradeNo());
            if (response.isSuccess()) {
                dto.setOrderId(response.getTradeNo());
                dto.setOrderStatus(response.getTradeStatus().equals("TRADE_SUCCESS") || response.getTradeStatus().equals("TRADE_FINISHED") ? "1" : "0");
                dto.setOrderSuccessTime(sdf.format(response.getSendPayDate()));
                dto.setMoney(PayUtil.buiderMoney(Double.parseDouble(response.getTotalAmount())));
            }
            if (response == null || (!response.isSuccess() && !response.getSubMsg().equals("交易不存在"))) {
                throw new SearchException(response.getSubMsg());
            }
            return dto;
        }catch(Exception e) {
            throw new SearchException(e.getMessage());
        }
    }

    /**
     * 创建支付的二维码
     * @param orderNo 本地订单编号(唯一)
     * @param money 支付金额, 1元为100
     * @param orderDescription 订单详细说明
     * @return
     */
    public static String createPay(String orderNo, Integer money, String orderDescription) {
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl(aliPayStaticProperties.getUrl());// 支付地址
        alipayConfig.setAppId(aliPayStaticProperties.getAppId());// 应用ID
        alipayConfig.setPrivateKey(aliPayStaticProperties.getPrivateKey());// 应用私钥
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(aliPayStaticProperties.getAliPublicKey());// 支付宝公钥
        alipayConfig.setCharset("UTF-8");
        alipayConfig.setSignType("RSA2");// 编码
        try{
            if (PayUtil.buiderMoney(money) > aliPayStaticProperties.getMaxMoney() || PayUtil.buiderMoney(money) < aliPayStaticProperties.getMinMoney()) {
                throw new SaveException("支付金额超出范围");
            }
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
            AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
            String notifyUrl = aliPayStaticProperties.getNotifyUrl().replaceAll("\\{orderNo}", orderNo);
            request.setNotifyUrl(notifyUrl);
            AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
            model.setOutTradeNo(orderNo);// 本地订单号
            model.setTotalAmount(PayUtil.buiderMoney(money) + ""); // 本次付款金额
            model.setTimeoutExpress(aliPayStaticProperties.getTimeOut() + "m");//交易超时时间
            model.setQrCodeTimeoutExpress(aliPayStaticProperties.getTimeOut() + "m");//二维码失效时间
            model.setSubject(orderDescription); // 本次订单说明
            request.setBizModel(model);
            AlipayTradePrecreateResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                String qrCode = response.getQrCode();
                if (qrCode.startsWith("http")) {
                    BufferedImage bufferedImage = QRUtils.createQrCodeImage(QRUtils.createQrCode(qrCode, 330, 330), "");
                    return QRUtils.imageToBase64(bufferedImage);
                }
            }
            throw new SaveException(response.getSubMsg());
        }catch(Exception e) {
            e.printStackTrace();
            throw new SaveException("生成支付二维码失败");
        }
    }

}
package cn.com.baidu.operator.util.pay;

import io.swagger.annotations.ApiModelProperty;

/**
 * 支付结果对象
 * 2024年3月19日17:03:25
 * CBC
 */
public class PayResultDTO {

    @ApiModelProperty(name = "orderId", value = "第三方订单ID")
    private String orderId;

    @ApiModelProperty(name = "orderNo", value = "本地订单编号")
    private String orderNo;

    @ApiModelProperty(name = "orderStatus", value = "支付结果,1:成功")
    private String orderStatus;

    @ApiModelProperty(name = "orderSuccessTime", value = "支付成功时间")
    private String orderSuccessTime;

    @ApiModelProperty(name = "orderMessage", value = "支付结果详情")
    private String orderMessage;

    @ApiModelProperty(name = "money", value = "订单总金额")
    private Integer money;

    public String getOrderId() {
        return orderId == null ? "" : orderId.trim();
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    public String getOrderNo() {
        return orderNo == null ? "" : orderNo.trim();
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public String getOrderStatus() {
        return orderStatus == null ? "" : orderStatus.trim();
    }

    public void setOrderStatus(String orderStatus) {
        this.orderStatus = orderStatus;
    }

    public String getOrderSuccessTime() {
        return orderSuccessTime == null ? "" : orderSuccessTime.trim();
    }

    public void setOrderSuccessTime(String orderSuccessTime) {
        this.orderSuccessTime = orderSuccessTime;
    }

    public String getOrderMessage() {
        return orderMessage == null ? "" : orderMessage.trim();
    }

    public void setOrderMessage(String orderMessage) {
        this.orderMessage = orderMessage;
    }

    public Integer getMoney() {
        return money == null ? 0 : money;
    }

    public void setMoney(Integer money) {
        this.money = money;
    }
}

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

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

相关文章

nRF Sniffer 在Wireshark中的使用

一、简介 使用nRF Sniffer在wireshark中抓包是经常使用的。但是每次抓包会获取到空气中所有的数据包&#xff0c;数据量非常大。而对于开发人员而言&#xff0c;只需要其中特定的信息。此时就需要掌握数据的过滤语句。 二、过滤 1.根据MAC地址进行过滤 btle.advertising_add…

蓝桥杯刷题-替换字符

代码&#xff1a; 顺着题目意思写即可 sinput() nint(input()) for i in range(n):l, r, x, y input().split() if x not in s[int(l)-1:int(r)]: # 如果待替换字符不在区间内则跳过continueelse:# 找到待替换字符的位置&#xff0c;用replace函数进行替换ss[:int(l)-1]s[in…

Qt 坐标位置转换

Qt 坐标位置转换 文章目录 Qt 坐标位置转换常见的位置坐标转换Qt窗体中常用坐标的区别与获取途径当前光标相对于屏幕的绝对位置当前光标相对于当前窗口的位置鼠标事件发生的位置窗体的位置判断鼠标光标是否悬浮在某个子控件上 从事Qt快一年了 &#xff0c;在做坐标转换的时候容…

linux下设置背景

参考https://zhidao.baidu.com/question/1778024793821420060.html 我要在QWidget里设置背景&#xff0c;之前在windows里选中对应的QWidget对象&#xff0c;右键changeStyleSheet后有个小笔一样的编辑&#xff0c;可以添加资源&#xff0c;并设置为背景&#xff1b;但是linux…

x-zse-96,android端,伪dex加固,so加固,白盒AES,字符串加密

x-zse-96,android端,伪dex加固,so加固,白盒AES,字符串加密 上一篇某招聘软件的sig及sp参数被和谐掉了,所以懂得都懂啊! 因为web的api没有那么全,所以来看了下app的,ios的防护几乎没有,纸糊的一样,android端的有点复杂了,到最后我也没能完整的实现整个加密过程,我也只复现到DF…

【MySql实战--日志系统:一条SQL更新语句是如何执行的?】

前面我们系统了解了一个查询语句的执行流程&#xff0c;并介绍了执行过程中涉及的处理模块。相信你还记得&#xff0c;一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等功能模块&#xff0c;最后到达存储引擎。 那么&#xff0c;一条更新语句的执行流程又是怎…

亮数据代理IP轻松解决爬虫数据采集痛点

文章目录 一、爬虫数据采集痛点二、为什么使用代理IP可以解决&#xff1f;2.1 爬虫和代理IP的关系2.2 使用代理IP的好处 三、亮数据代理IP的优势3.1 IP种类丰富3.1.1 动态住宅代理IP3.1.2 静态住宅代理IP3.1.3 机房代理IP3.1.4 移动代理IP 3.2 高质量IP全球覆盖3.3 超级代理服务…

UE4 Json事件设置Asset值

通过Json事件来设置&#xff0c;比如骨骼网格体&#xff08;换皮&#xff09;等等

【漏洞复现】1. WebLogic 反序列化漏洞(CVE-2019-2890)复现与分析

文章目录 1. 基础知识2. 复现2.1 漏洞介绍漏洞影响版本&#xff1a; 2.2 漏洞原理分析2.3 漏洞复现2.3.1 环境搭建2.3.2 漏洞验证2.3.3 漏洞利用2.3.4 POC分析 2.4 漏洞修复 1. 基础知识 WebLogic是美国Oracle公司出品的一个application server&#xff0c;确切的说是一个基于J…

区域规划(Regional Planning)的学习笔记

目录 一、概念题 1.区域的概念、类型、特性 2.区域分析的概念、主要内容 3.自然环境、自然资源的概念 4.区域自然资源评价的内容 5.可持续发展理论定义 6.经济增长、经济结构定义 7.产业结构概念 8.人口增长分析的含义、指标 9.技术进步概念、类型 10.技术进步对区域…

『Python爬虫』极简入门

本文简介 点赞 收藏 关注 学会了 声明&#xff1a;请勿使用爬虫技术获取公民隐私数据、数据以及企业或个人不允许你获取的数据。 本文介绍如何使用 Python 写一只简单的爬虫&#xff0c;作为入门篇&#xff0c;这个程序不会很复杂&#xff0c;但至少可以讲明爬虫是个什么东…

Nacos 配置管理-快速入门

** Nacos 配置管理-快速入门 ** 2024-3-18 段子手168 1、首先在 nacos 发布配置&#xff08;确认安装启动了 nacos 服务&#xff09;。 浏览器访问 http://127.0.0.1:8848/nacos, 打开 nacos 控制台&#xff0c; 并点击菜单&#xff1a;新增 --》配置管理 --》配置列表 --》…

html5cssjs代码 034 自定义字体

html5&css&js代码 034 自定义字体 一、代码二、解释 这是一个带有自定义字体的网页&#xff0c;设置了页面背景颜色、文字颜色以及全局样式。它定义了三种自定义字体并通过font-face规则引入外部字体文件&#xff0c;并通过CSS类&#xff08;.f1, .f2, .f3&#xff09;…

2024上半年四川省属事业单位报名指南✅

⏰报考时间 1⃣报名时间&#xff1a;2024年3月21日10:00——3月25日18:00 2⃣缴费时间&#xff1a;截止2024年3月26日18:00 ⚠通过网络报名且上传相片质量合格的报考者&#xff0c;未按要求在规定时间内进行网上缴费的&#xff0c;视为自动放弃报考。 3⃣公共科目笔试时间&…

力扣---两数相加

给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都不会以 0 …

QGIS开发笔记(一):QGIS介绍、软件下载和加载shp地图数据Demo

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/136888334 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

【亲测有效】axureRP9授权密钥 Mac/Windows

哪里有axureRP9授权密钥&#xff1f;这里为大家带来了axureRP9中文授权版资源&#xff0c;内含axureRP9授权密钥&#xff0c;亲测支持apple Intel/M1/M2以及Windows系统&#xff01; 【永久可用】axureRP9授权密钥 Mac版 【永久可用】axureRP9授权密钥 Windows版

吴恩达机器学习-可选实验室:简单神经网络(Simple Neural Network)

在这个实验室里&#xff0c;我们将使用Numpy构建一个小型神经网络。它将与您在Tensorflow中实现的“咖啡烘焙”网络相同。 import numpy as np import matplotlib.pyplot as plt plt.style.use(./deeplearning.mplstyle) import tensorflow as tf from lab_utils_common impor…

python网络爬虫实战教学——urllib的使用(3)

文章目录 专栏导读1、urlsplit2、urlunsplit3、urljoin4、urlencode 专栏导读 ✍ 作者简介&#xff1a;i阿极&#xff0c;CSDN 数据分析领域优质创作者&#xff0c;专注于分享python数据分析领域知识。 ✍ 本文录入于《python网络爬虫实战教学》&#xff0c;本专栏针对大学生、…

基于java+springboot+vue实现的学生管理系统(文末源码+Lw+ppt)23-486

摘 要 学生管理系统的目的是让使用者可以更方便的将人、设备和场景更立体的连接在一起。能让用户以更科幻的方式使用产品&#xff0c;体验高科技时代带给人们的方便&#xff0c;同时也能让用户体会到与以往常规产品不同的体验风格。 与安卓&#xff0c;iOS相比较起来&#x…