UniApp + SpringBoot 实现接入支付宝支付功能和退款功能
一、支付宝开放平台设置
注册支付宝支付功能需要个体工商户或企业才可以!需要有营业执照才能去申请哦!
1、登录到控制台
进入支付宝开放平台 控制台
2、开发设置
3、产品绑定APP支付
如果没有绑定APP支付就会报商家订单参数异常,请重新发起支付的错误
二、Springboot后端代码
1、pom.xml中导入两个包
<!-- 支付宝官方 SDK-->
<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.22.32.ALL</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>
2、application.yml中添加以下配置
# 支付宝支付
alipay:server_url: https://openapi.alipay.com/gateway.doapp_id: 你的APPIDprivate_key: 应用私钥format: jsoncharset: utf-8alipay_public_key: 支付宝公钥sign_type: RSA2notifyUrl: 回调地址
3、新建AlipayConfig类和BizAlipayService类
AlipayConfig类代码
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Getter
@Setter
@ToString
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayConfig extends com.alipay.api.AlipayConfig {private String serverUrl;private String appId;private String privateKey;private String format;private String charset;private String alipayPublicKey;private String signType;private String notifyUrl;
}
BizAlipayService类代码
import com.alipay.api.AlipayApiException;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** 阿里云支付类*/
@Service
public class BizAlipayService {private static Logger logger = LoggerFactory.getLogger(BizAlipayService.class);@AutowiredAlipayConfig alipayConfig;private DefaultAlipayClient client() throws AlipayApiException {return new DefaultAlipayClient(alipayConfig);}/*** 预下单** @param subject 订单标题* @param outTradeNo 商家生成的订单号* @param totalAmount 订单总价值* @return*/public String appPay(String subject, String outTradeNo, String totalAmount) {String source = "";try {DefaultAlipayClient client = client();AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();model.setSubject(subject);model.setOutTradeNo(outTradeNo);model.setTotalAmount(totalAmount);// alipay 封装的接口调用AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();request.setBizModel(model);request.setNotifyUrl(alipayConfig.getNotifyUrl());AlipayTradeAppPayResponse response = client.sdkExecute(request);source = response.getBody();} catch (AlipayApiException e) {logger.error("支付出现问题,详情:{}", e.getErrMsg());e.printStackTrace();}return source;}
}
4、编写接口支付接口和回调接口
接口代码
@RestController
@CrossOrigin // @CrossOrigin注解 解决uniapp跨域访问后端问题。
@RequestMapping("/productOrder")
public class UniProductOrderController {@Autowiredprivate AlipayConfig alipayConfig;@Autowiredprivate BizAlipayService alipayService;/*** 发起支付** @return*/@GetMapping("/pay")public Object pay() {System.out.println("正在测试支付宝支付···");String s = alipayService.appPay("测试支付", String.valueOf(System.currentTimeMillis()), new BigDecimal("0.01").toString());System.out.println(s);return s;}/*** 订单回调** @return*/@RequestMapping(method = RequestMethod.POST, value = "/notify")public String orderNotify(HttpServletRequest request) {Map<String, String> params = new HashMap<>();Map<String, String[]> requestParams = request.getParameterMap();for (String name : requestParams.keySet()) {String[] values = requestParams.get(name);String valueStr = "";for (int i = 0; i < values.length; i++) {valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";}params.put(name, valueStr);}try {boolean flag = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(), alipayConfig.getCharset(), alipayConfig.getSignType());if (flag) {System.out.println("支付回调信息:"+ params);return "success";} else {return "error";}} catch (AlipayApiException e) {System.out.println("支付宝错误回调:"+e.getErrMsg());e.printStackTrace();return "error";}}
}
三、UniApp前端代码
1、配置manifest.json的App模块开启支付
2、编写uni.request请求
代码
//发起支付
pay(){let that = thisuni.request({url: getApp().globalData.myurl + "/productOrder/pay",data:{},method: 'GET',dataType: 'json',header: {'content-type': 'application/x-www-form-urlencoded'},success(res) {console.log(res);uni.requestPayment({provider: 'alipay',orderInfo: res.data,success(r) {uni.showToast({title:"支付成功",icon: "success"})},fail(e) {uni.showToast({title:"用户取消支付",icon: "error"})},complete: () => {console.log("payment结束")}})}})
},
四、支付功能展示
1、用户确认支付
2、用户取消支付
五、退款功能
1、支付成功回调返回结果
返回结果:
返回结果里面的trade_no 一会退款需要用到这个!
2、在刚才的BizAlipayService.类中添加以下代码
代码
/*** 退款** @param tradeNo* @param totalAmount* @return*/
public AlipayTradeRefundResponse refund(String tradeNo, String totalAmount) {try {DefaultAlipayClient client = client();AlipayTradeRefundModel alipayTradeRefundModel = new AlipayTradeRefundModel();alipayTradeRefundModel.setTradeNo(tradeNo);alipayTradeRefundModel.setRefundAmount(totalAmount);AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();request.setBizModel(alipayTradeRefundModel);AlipayTradeRefundResponse response = client.execute(request);return response;} catch (AlipayApiException e) {logger.error("退款出现问题,详情:{}", e.getErrMsg());e.printStackTrace();}return null;
}
3、在接口中添加退款接口
代码
/*** 订单退款** @return* @TODO 仅实现了全部退款*/
@RequestMapping(value = "/orderRefund", method = RequestMethod.GET)
public AlipayTradeRefundResponse orderRefund() {AlipayTradeRefundResponse refund = alipayService.refund("2022020922001434041429269213", "0.01");return refund;
}
六、支付成功后支付宝异步多次回调问题
- 当订单的状态发生改变后,支付宝通常会以异步的方式通知商家服务器。
- 商家服务器需要返回success这 7 个字符,如果不是,则支付宝则会不断重复通知商家服务器。
但是有时即使返回“success”,支付宝还是继续回发异步通知!!!
我们需要在本地加点验证来解决这个问题,根据当前订单编号去查他的状态,如果状态是0我们就去存储,如果状态是1了则不存!
本文仅供学习使用,本文参考博客园作者奔跑的砖头的文章感谢作者的详细说明以及代码 (*╯3╰) (*╯3╰) (*╯3╰)
相关文章:

UniApp + SpringBoot 实现接入支付宝支付功能和退款功能
一、支付宝开放平台设置 注册支付宝支付功能需要个体工商户或企业才可以!需要有营业执照才能去申请哦! 1、登录到控制台 进入支付宝开放平台 控制台 2、开发设置 3、产品绑定APP支付 如果没有绑定APP支付就会报商家订单参数异常,请重新发起…...

初识进程
文章目录一、进程的概念1. 进程是什么及进程的管理2. Linux 下的 pcb3. 系统调用接口 getpid 和 getppid4. 系统调用接口 fork一、进程的概念 1. 进程是什么及进程的管理 在 Linux下 ./binaryfile 运行一个程序或者在 Windows下双击运行一个程序时,程序就变成了一个…...

SOAP传输协议
一.HTTP传输协议 超文本传输协议(HyperText Transfer Protocol,缩写:HTTP),它是基于请求-响应的模式协议,客户端发出请求,服务器端给出响应并返回请求内容。方法如下,HTTP传输协议常…...

<Linux>进程控制
进程控制 文章目录进程控制一、进程创建1.fork函数认识2.写时拷贝3.fork常规用法4.fork调用失败的原因二、进程终止1.进程退出场景2.进程退出码3.进程退出的方式三、进程等待1.进程等待是什么?2.进程等待的必要性3.进程等待的方法3.1.wait函数3.2.waitpid函数4.如何…...

有手就行 -- 搭建图床(PicGo+腾讯云)
🍳作者:贤蛋大眼萌,一名很普通但不想普通的程序媛\color{#FF0000}{贤蛋 大眼萌 ,一名很普通但不想普通的程序媛}贤蛋大眼萌,一名很普通但不想普通的程序媛🤳 🙊语录:多一些不为什么的…...

“蓝桥杯”递推和递归(一)——取数位
1. 算法简介 递推和递归虽然叫法不同,但它们的基本思想是一致的,在很多程序中,这两种算法可以通用,不同的是递推法效率更高,递归法更方便阅读。 (1)递推法 递推法是一种重要的数学方法&#…...

蓝桥杯·3月份刷题集训Day02
本篇博客旨在记录自已打卡蓝桥杯3月份刷题集训,同时会有自己的思路及代码解答希望可以给小伙伴一些帮助。本人也是算法小白,水平有限,如果文章中有什么错误之处,希望小伙伴们可以在评论区指出来,共勉💪。 文…...
python --获取内网IP地址
方法一 import socketdef get_local_ip_address():ip_address try:# 获取本机主机名hostname socket.gethostname()# 获取本机IPip_address socket.gethostbyname(hostname)except:passreturn ip_address方法二 import subprocessdef get_local_ip_address():ip_address …...

如何衡量你的Facebook广告活动的成功
投入大量资金和资源在Facebook广告上并不总能带来预期的回报,这很可能是由于缺乏恰当的衡量广告活动成功的方法。在这篇文章中,我们将介绍一些关键的指标,帮助你更好地了解如何衡量你的Facebook广告活动的成功。1.费用每次点击(CP…...
Linux对一个目录及其子目录所有文件添加权限
1、chmod指令 chmod是一个改变用户拥有指定文件的权限的命令.r:只读,w:写,x执行.也可以用数字 -rw------- (600) -- 只有属主有读写权限。 -rw-r--r-- (644) -- 只有属主有读写权限;而属组用户和其他用户只有读权限。 -rwx------ (700) -- 只有属主有读、写、执…...

宝刀未老?低代码何德何能受大厂们的推崇
风口之下,低代码蓬勃发展,本文从国内低代码的走红现象引入,浅析低代码发展中的变化趋势,重点探讨如此趋势之下,国内大厂如何通过低代码实现了良性发展。 一、国内爆火的低代码 据Gartner最新报告显示,到2…...

智能扑克牌识别软件(Python+YOLOv5深度学习模型+清新界面)
摘要:智能扑克牌识别软件利用视觉方法检测和识别日常扑克牌具体花色与数字,快速识别牌型并标注结果,帮助计算机完成扑克牌对战的前期识别步骤。本文详细介绍基于深度学习的智能扑克牌识别软件,在介绍算法原理的同时,给…...

SQL优化13连问,收藏好!
1.日常工作中,你是怎么优化SQL的? 大家可以从这几个维度回答这个问题: 分析慢查询日志 使用explain查看执行计划 索引优化 深分页优化 避免全表扫描 避免返回不必要的数据(如select具体字段而不是select*) 使用…...

【小技巧】公式从docx文件复制到doc文件变成了图片怎么办?
文章目录0、word文件后缀命名1、docx和doc默认的公式编辑方式2、MathTpye公式编辑器3、MathType 运行时错误‘53’:文件未找到:MathPage.WLL4、结束语0、word文件后缀命名 1997-2003的旧版本文件名后缀是.doc 从2007版以后,后缀名是.docx…...

Python3入门与进阶笔记(六):初识类
目录 一些解释 属性 类名建议首字母大写,通常用驼峰规则命名。变量名建议小写,下划线隔开。类最基本的作用是封装。 写在类内非方法中的语句在类加载的时候会执行,且只会执行一次,例如下面的print语句,类加载时就会…...

Prometheus监控实战系列九:主机监控
Prometheus使用各种Exporter来监控资源。Exporter可以看成是监控的agent端,它负责收集对应资源的指标,并提供接口给到Prometheus读取。不同资源的监控对应不同的Exporter,如node-exporeter、mysql-exporter、kafka-exporter等,在这…...

JVM知识整理
JVM知识整理 JVM的主要组成部分 JVM包含两个两个子系统(类加载子系统和执行引擎)和两个组件(运行时数据区与和本地库接口) 类加载子系统:根据给定的全限定类名来加载class文件到运行时数据区域中的方法区。执行引擎&a…...

【C++】二叉搜索树
A:你长大后想要做什么? B:写下“快乐”…… A:不,你理解错我的意思了,我是说 B:不,是你理解错了人生…… 文章目录一、二叉搜索树的实现1.struct TreeNode{}2.迭代版本2.1 Insert()插入结点(解决链接的问题)…...

leetcode -- 21. 合并两个有序链表
🐨目录📑1. 题目🛶2. 解法- 头插到新链表🐬2.1 思路🐬2.1 代码实现⛵3. 解法优化 - 带哨兵位🐋3.1 思路🐋3.2 代码实现🚤4. 题目链接📑1. 题目 将两个升序链表合并为一个…...

计算机组成原理|第四章(笔记)
目录第四章 存储器4.1 概述4.1.1 存储器分类4.1.2 存储器的层次结构4.2 主存储器4.2.1 概述4.2.2 半导体存储芯片简介4.2.3 随机存取存储器(RAM)4.2.4 只读存储器(ROM)4.2.5 存储器与CPU的连接4.2.6 存储器的校验4.2.7 提高访存速…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...