微信小程序余额退费

需求:用户充值使用后的剩余金额,需要退回到用户原路。

参考文档:微信支付-开发者文档

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;}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第十站:Java白——测试与调试的艺术

JUnit作为单元测试的首选工具&#xff0c;帮助开发者确保每个模块按预期工作。Mockito等模拟框架则使得复杂系统中的隔离测试成为可能。而集成开发环境&#xff08;IDE&#xff09;如IntelliJ IDEA&#xff0c;凭借其强大的代码分析、调试和重构功能&#xff0c;成为Java开发者…

经典游戏案例:仿植物大战僵尸

学习目标&#xff1a;仿植物大战僵尸核心玩法实现 游戏画面 项目结构目录 部分核心代码 using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using Random UnityEngine.Random;public enum…

Web APIs-DOM-事件相关整理(完成网页交互)

目录 1.事件监听 2.事件监听绑定 3.事件类型 4.实例注意 5.事件对象 6.环境对象 7.回调函数 1.事件监听 &#xff08;绑定事件/注册事件&#xff09;: 程序检测有没有事件产生&#xff08;事件&#xff1a;比如单机一个按钮&#xff08;编程时系统发生的动作或者事情&a…

网络爬虫Xpath开发工具的使用

开发人员在编写网络爬虫程序时若遇到解析网页数据的问题&#xff0c;则需要花费大量的时间编 写与测试路径表达式&#xff0c;以确认是否可以解析出所需要的数据。为帮助开发人员在网页上直接 测试路径表达式是否正确&#xff0c;我们在这里推荐一款比较好用的 XPath 开发工…

深入探索YARN集群:NodeManager内存配置与管理全攻略

深入探索YARN集群&#xff1a;NodeManager内存配置与管理全攻略 引言 Apache Hadoop YARN&#xff08;Yet Another Resource Negotiator&#xff09;作为Hadoop生态系统中的一个关键组件&#xff0c;为集群资源管理和作业调度提供了强大的支持。在YARN集群中&#xff0c;Node…

轻松学AI绘画:PS AI插件,小白的入门秘籍

各位AIGC创意爱好者们&#xff0c;你们是否对AI绘画充满好奇&#xff0c;却又对那些复杂的国外软件感到望而却步&#xff1f;别急&#xff0c;今天我要为大家介绍一款适合新手的国产PS AI插件——StartAI&#xff0c;它将为你的创作之路带来无限可能&#xff01; StartAI&…

大学网页制作作品1

作品须知&#xff1a;1.该网页作品预计分为5个页面&#xff08;其中1个登录页面&#xff0c;1个首页主页面&#xff0c;3个分页面&#xff09;&#xff0c;如需要可自行删改增加页面。&#xff08;总共约800行html,1200行css,100行js&#xff09; 2.此网页源代码只用于学习和模…

短视频最火的10个拍摄技巧,新手也能这样拍出大片效果

短视频越来越占据了人们的生活&#xff0c;不管是记录生活还是发个朋友圈是不是总感觉咱们自己拍出来的效果总是不如别人呢&#xff1f;更别说发短视频平台呢&#xff01;下面就分享10个拍摄技巧大家学着试试慢慢也能拍出大片效果。 不管你以后是否发展短视频平台&#xff0c;…

docker配置使用

Docker配置与使用指南 目录&#xff1a; 简介 安装Docker 基本命令 镜像管理 容器管理 数据卷管理 网络管理 Dockerfile编写 示例代码 简介 Docker是一个开源的应用容器引擎&#xff0c;可以让开发者将应用及其依赖包打包到一个轻量级的、可移植的容器中&#xff0c;…

免费的音频剪辑软件有哪些?分享9个实用的软件,自媒体人必备!

音频剪辑软件能够帮助我们对音视频文件实现个性化剪辑&#xff0c;包括分割、合并、添加音效、转换格式等。那么都有哪些免费好用的音频剪辑软件和方法&#xff0c;本文整理了电脑、手机、在线的音频剪辑方法&#xff0c;能够有效解决音频剪辑的需求&#xff0c;一起来看看吧&a…

本地电脑配置不足,对工业仿真计算有哪些影响?

工业仿真计算对电脑的要求相对较高&#xff0c;这主要是因为仿真过程涉及到大量的数据处理和复杂的计算任务。一个高效的工业仿真系统需要强大的计算能力和稳定的运行环境&#xff0c;以确保仿真的准确性和实时性。 工业仿真对电脑配置有哪些要求 首先&#xff0c;工业仿真计算…

mysql函数之lpad和rpad用于字符串填充

《LPAD》 定义用法 在mysql中&#xff0c;lpad是一个字符串函数&#xff0c;用于在字符串的左侧进行填充。 语法 LPAD(str, len, padstr)其中&#xff1a; str 表示要填充的字符串。len 表示填充后的字符串长度。padstr 表示用于填充的字符串。 如果str长度小于len&#…

基于STM32设计的智能家居远程调温系统(通过红外线控制空调)_75

文章目录 一、前言1.1 项目介绍【1】项目功能介绍【2】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】ESP8266工作模式配置1.3 设计的意义1.4 开发工具的选择1.5 系统框架图1.6 系统功能总结1.7 原理图二、硬件选型2.1 ESP8266-串口WIFI2.2 STM32F103C8T6开发板2.3 红外学…

python中的socket使用

目录 一. socket 基础 二. 创建一个 Socket 三. 服务器端 TCP 服务器示例&#xff1a; 四.客户端 TCP 客户端示例&#xff1a; 五. UDP 服务器和客户端 5.1 UDP 服务器示例&#xff1a; 5.2 UDP 客户端示例&#xff1a; 5.3 UDP非阻塞监听 5.3.1 服务端代码&#xf…

题目 2721: 蓝桥杯2022年第十三届决赛真题-背包与魔法

题目 2721: 蓝桥杯2022年第十三届决赛真题-背包与魔法 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;Problem ExplanationCode ExplanationSummary 参考代码&#xff1a;_题目2721_蓝桥杯2022年第十三届决赛真题_背包与魔法 错误经验吸取 原题链接&#xff1…

产品设计职责和量化衡量尺度

产品设计职责和量化衡量尺度 1. 源由2. 职责(Responsibilities)3. 量化矩阵(Quantify Work and Metrics)3. 具体方法(Specific Measures)4. 交付依据(Delivery Product Guidelines)5. 备忘(Memo)6. 补充 - Product Design Responsibilities and Quantitative Metrics6.1 Respon…

Hexo结合多个主题扩展为Gallery画廊并实现文章加密

文章目录 1. 初始化2. 安装加密3. 配置文件4. 创建Token5. 新建公开仓库6. 工作流7. 实现效果1. 加密2. 画廊B主题 可能参考的文章&#xff1a; 如何优雅的使用Github Action服务来将Hexo部署到Github Pages - Hexo 当前PC环境中有Node和Git。版本可以参考Hexo文档。 文章中…

ubuntu的不同python版本的pip安装及管理

ubuntu的不同python版本的pip安装及管理_ubuntu 安装两个pip-CSDN博客https://blog.csdn.net/qq_32277533/article/details/106770850

LRUCache

LRUCache是Android中实现内存缓存相关的组件类&#xff0c;当缓存满时其使用最近最少使用策略来淘汰相关的元素&#xff0c;以控制缓存大小。本文主要基于LRUCache相关源码分析LRUCache的创建、缓存的添加、获取、删除流程。 LRUCache创建 LRUCache的创建可以直接看其构造函数…

SpringBoot的Mybatis-plus实战之扩展功能

文章目录 一、枚举处理器第一步、定义枚举第二步、配置文件中设置 在学习mybatisPlus时会用到扩展功能&#xff0c;极大解放生产力&#xff0c;记录下来&#xff0c;方便备查。 一、枚举处理器 第一步、定义枚举 新建枚举类UserStatusEnum&#xff0c;其主要内容如下所示。 E…