微信小程序余额退费
需求:用户充值使用后的剩余金额,需要退回到用户原路。
参考文档:微信支付-开发者文档
pom.xml配置:
<!--微信支付SDK--> <dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-java</artifactId><version>0.2.12</version> </dependency><!--微信支付SDK--> <dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-apache-httpclient</artifactId><version>0.4.4</version> </dependency>
配置说明:在application.yml文件中配置
wx:app_id: wx70f123456abc0000 #微信小程序appIdapp_secret: 012029bc88ab195f64000c0f40003ed9 #小程序秘钥mch_id: 1000008342 #微信支付商户号mch_serial_no: 47401236EAE7432BA123456E95F3EC483A000000 #商户API证书序列号api_key: ABCD20225806STOPCHARGE0123WXZFSH #微信支付API密钥;apiV3秘钥key_path: C:\apiclient_key.pem #商户API私钥路径
package com.xxxx.common.vo;import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component
@ConfigurationProperties(prefix = "wx")
@Data
@ToString
public class WxPayV3Vo {//小程序appidprivate String appId;//商户号private String mchId;//证书序列号private String mchSerialNo;//小程序秘钥private String appSecret;//微信支付API密钥;apiV3秘钥private String apiKey;//证书地址private String keyPath;
}
不废话直接上代码
控制层:小程序传2个参数,余额和用户Id
/*** 退款* @param amount* @param userId* @return*/@ApiOperation(value = "退款", notes = "退款")@GetMapping(value = "/refund")@ResponseBodypublic CommonResult<Boolean> refund(String amount,Integer userId) {return CommonResult.success(chargeOrderStatusService.refund(amount,userId));}
实现类
/*** 退款*/@Overridepublic boolean refund(String amount, Integer userId) {BigDecimal amount1 = new BigDecimal(amount);//查询充值订单集合List<UserRecharge> chargeOrderStatusList = selectChargeOrderData(userId);for (UserRecharge userRecharge : chargeOrderStatusList) {String orderId = userRecharge.getOrderId();//商户订单号if (amount1.compareTo(BigDecimal.ZERO) <= 0) {throw new CrmebException("退款金额不能为0,请修改退款金额");}//用户剩余金额User user = queryUserMoney(userId);//退款金额>用户剩余金额if (amount1.compareTo(user.getNowMoney()) > 0) {throw new CrmebException("退款金额大于剩余金额,请修改退款金额");}if (amount1.compareTo(user.getNowMoney()) <= 0) {try {//开始退款chargeOrderStatusService.refundStart(amount1, userId, orderId);} catch (Exception e) {e.printStackTrace();throw new CrmebException("微信申请退款失败!");}}}return false;}
/*** 查询充值订单** @return*/private List<UserRecharge> selectChargeOrderData(Integer userId) {LambdaQueryWrapper<UserRecharge> lqw = Wrappers.lambdaQuery();lqw.eq(UserRecharge::getUid, userId);lqw.orderByDesc(UserRecharge::getCreateTime);lqw.last("LIMIT 1");List<UserRecharge> userRechargeList = userRechargeDao.selectList(lqw);if (userRechargeList.size() < 0) {throw new CrmebException("没有找到充值订单信息");}return userRechargeList;}
/*** 查询用户剩余金额** @return*/private User queryUserMoney(Integer userId) {LambdaQueryWrapper<User> lqw = Wrappers.lambdaQuery();lqw.eq(User::getUid, userId);User User = userDao.selectOne(lqw);if (ObjectUtil.isNull(User)) {throw new CrmebException("没有找到订单信息");}return User;}
/*** 开始退款** @param amount1 退款金额* @param userId* @param orderId* @return*/@Overridepublic CommonResult<Object> refundStart(BigDecimal amount1, Integer userId, String orderId) {//查询用户剩余金额User user = queryUserMoney(userId);try {Config config = new RSAAutoCertificateConfig.Builder().merchantId(wxPayV3Bean.getMchId()).privateKeyFromPath(wxPayV3Bean.getKeyPath()).merchantSerialNumber(wxPayV3Bean.getMchSerialNo()).apiV3Key(wxPayV3Bean.getApiKey()).build();//构造申请退款对象RefundService service = new RefundService.Builder().config(config).build();//请求参数CreateRequest requestParam = new CreateRequest();//设置退款金额AmountReq amountReq = new AmountReq();String amountStr = amount1.toString();//用户退款金额Number number = Float.parseFloat(amountStr) * 100;int oamount = number.intValue();long refundLong = Long.valueOf(oamount);amountReq.setRefund(refundLong);//退款金额String nowMoneyStr = String.valueOf(user.getNowMoney());//用户剩余金额Number number1 = Float.parseFloat(nowMoneyStr) * 100;int oamount1 = number1.intValue();long LongNowMoney = Long.valueOf(oamount1);//生成商户退款单号String formattedTime = formatTime(LocalDateTime.now(), "yyyyMMddHHmmss");String randomNum = String.valueOf(generateRandomNumber(1000, 9999));String StartChargeSeq = "refund_" + formattedTime + randomNum;amountReq.setTotal(LongNowMoney);//原订单金额amountReq.setCurrency("CNY");//货币类型(默认人民币)requestParam.setAmount(amountReq);requestParam.setReason("退款");requestParam.setOutRefundNo(StartChargeSeq);requestParam.setOutTradeNo(orderId);//商户订单号//发起请求,申请退款Refund refund = service.create(requestParam);//调用成功的响应数据System.out.println("退款调用成功的响应数据======" + refund);if (Status.SUCCESS.equals(refund.getStatus().SUCCESS)) {return CommonResult.success("退款成功");}if (Status.PROCESSING.equals(refund.getStatus().PROCESSING)) {//根据请求返回状态修改对应订单状态return CommonResult.success("退款中");}if (Status.ABNORMAL.equals(refund.getStatus().ABNORMAL)) {//根据请求返回状态修改对应订单状态return CommonResult.success("退款异常");}if (Status.CLOSED.equals(refund.getStatus().CLOSED)) {//根据请求返回状态修改对应订单状态return CommonResult.success("退款关闭");}} catch (Exception e) {e.printStackTrace();}return null;}
相关文章:
微信小程序余额退费
需求:用户充值使用后的剩余金额,需要退回到用户原路。 参考文档:微信支付-开发者文档 pom.xml配置: <!--微信支付SDK--> <dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId&g…...
宁波银行票据案例解读,要注入科技赋能票据新形式
随着科技的飞速发展,金融行业正迎来一场前所未有的变革。作为一家以科技创新为驱动的现代化银行,宁波银行在这场变革中积极探索,宁波银行票据案例之后持续通过引入先进技术,为客户提供更加高效、智能的金融服务。 宁波银行推出的…...
博客已迁移
迁移至 烧烤er (makkapakka996.github.io)...
大模型应用研发基础环境配置(Miniconda、Python、Jupyter Lab、Ollama等)
老牛同学之前使用的MacBook Pro电脑配置有点旧(2015 年生产),跑大模型感觉有点吃力,操作起来有点卡顿,因此不得已捡起了尘封了快两年的MateBook Pro电脑(老牛同学其实不太喜欢用 Windows 电脑做研发工作&am…...
24年嘉兴市索贝进出口有限公司--信息安全实施项目
截至24年6月24日,oms生产环境订单数12万5673条。 索贝是一家致力于成为竹木小家具头部企业的公司,截至24年6月24日,在册员工数130人,产值10个亿。 由于信息安全人才和能力的缺失,导致部署在阿里云生产环境的系统处于…...
亚马逊云科技官方活动:一个月拿下助理架构师SAA+云从业者考试认证(送半价折扣券)
为了帮助大家考取AWS SAA和AWS云从业者认证,小李哥争取到了大量考试半价50%折扣券,使用折扣券考试最多可省75刀(545元人民币)。 领取折扣券需要加入云师兄必过班群,在群中免费领取。目前必过班群招募到了超过200名小伙伴,名额有限…...
【山东】2024年夏季高考文化成绩一分一段表
文末有图片版,可直接保存下载!! 2024年夏季高考文化成绩一分一段表分数段全体-选考物理-选考化学-选考生物-选考思想政治-选考历史-选考地理分数段本段人数累计人数本段人数累计人数本段人数累计人数本段人数累计人数本段人数累计人数本段人…...
栈与队列 Leetcode 347 前k个高频元素
栈与队列 Leetcode 347 前k个高频元素 Leetcode 347 灵活运用C库函数,使用匿名函数排序,sort可以替换为快排实现(面试感觉可能会手撕,机考直接使用sort) class Solution { public:vector<int> topKFrequent(v…...
windchill 相关配置
-Dhttp.proxyHostproxy.acme.com -Dhttp.proxyPort8080 -Dwt.rmi.clientSocketFactorywt.boot.WTRMIMasterSocketFactory -Dwt.rmi.javarmicgiservlet/JavaRMIServlet...
XGBoost算法深度解析:原理、实现与应用
摘要 XGBoost(eXtreme Gradient Boosting)是一种高效的机器学习算法,以其出色的预测性能和计算效率在众多数据科学竞赛和实际应用中取得了巨大成功。本文将深入探讨XGBoost算法的基本原理、实现机制、优化技巧以及在不同领域的应用案例。 1…...
27-29、redis优化(令牌主动失效机制)-controllert额外添加参数接收请求头、拦截器
1、SpringBoot集成redis <!--redis坐标--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency> @SpringBootTest//如果在测试类上添加了这个注解,那么…...
【Linux】性能分析器 gperftools 详解
1、安装 1.1 源码安装 1)源码下载 最新版本:https://github.com/gperftools/gperftools 稳定版本:https://github.com/gperftools/gperftools/releases 2)编译 ./configure make -j83)安装,默认安装在/usr/local/lib目录下 sudo make install1.2 命令安装 以Ubuntu…...
C语言基础——函数(2)
ʕ • ᴥ • ʔ づ♡ど 🎉 欢迎点赞支持🎉 文章目录 前言 一、return语句 二、数组做函数参数 三、嵌套调用和链式访问 3.1 嵌套调用 3.2 链式访问 四、函数声明和定义 4.1 单个文件 4.2 多个文件 总结 前言 大家好啊,继我们上一…...
Kafka Stream 流处理设计概述
Kafka Stream 流处理设计概述 Kafka 流处理是指使用 Kafka 及其生态系统中的组件来处理实时数据流。Kafka Streams 是 Kafka 官方 提供的流处理库,它简化了构建流处理应用程序的过程,并与 Kafka 无缝集成。以下是 Kafka 流处理的设 计原理和相关概念。 1. Kafka 流处理基本…...
Centos7安装自动化运维Ansible
自动化运维Devops-Ansible Ansible是新出现的自动化运维工具,基于Python 开发,集合了众多运维工具(puppet 、cfengine、chef、func、fabric)的优点,实现了批量系统配置 、批量程序部署、批量运行命令 等功能。Ansible…...
element-ui 下拉菜单el-dropdown-item添加点击事件
使用element-ui下拉菜单组件Dropdown时绑定点击事件,事件不生效。 click 常见于其用在Vue中的事件绑定,而实际上是 v-on 的简写,而 v-on 则是对 vue 的事件体系封装之后的 API接口。 native修饰符用于处理DOM原生事件,由于组件 …...
Day45
Day45 jQuery动画 显示和隐藏 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title><script src"js/jquery-1.8.2.js" type"text/javascript" charset"utf-8"></script&…...
新媒体矩阵系统是什么?怎么搭建矩阵系统?
目录 前言: 一、新媒体矩阵分别是什么? 1、横向矩阵 2、 纵向矩阵 二、新媒体矩阵的作用? 1、多元化发展,吸引目标 2、多平台协同,放大宣传效果 3、多平台运营,分散风险 三、怎么做矩阵系统&…...
HarmonyOS应用开发——Hello World
下载 HUAWEI DevEco Studio: https://developer.harmonyos.com/cn/develop/deveco-studio/#download 同意,进入配置页面: 配置下载源以及本地存放路径,包括nodejs和ohpm: 配置鸿蒙SDK路径: 接受协议: 确认无误后&#…...
Ubuntu20.04使用Samba
目录 一、Samba介绍 Samba 的主要功能 二、启动samba 三、主机操作 四、Ubuntu与windows系统中文件互联 五、修改samba路径 一、Samba介绍 Samba 是一个开源软件套件,用于在 Linux 和 Unix 系统上实现 SMB(Server Message Block)协议…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...
