【uniapp微信小程序+springBoot(binarywang)
uniapp前端代码
<template><view><page-head :title="title"></page-head><view class="uni-padding-wrap"><view style="background:#FFF; padding:50rpx 0;"><view class="uni-hello-text uni-center font-lg text-danger">{{vipName}}</view><view class="uni-h1 uni-center uni-common-mt"><text class="rmbLogo">¥</text><input class="price" type="digit" :value="price" maxlength="5" @input="priceChange" /></view></view><view class="uni-btn-v uni-common-mt"><!-- #ifdef MP-WEIXIN || MP-QQ --><button type="primary" @click="weixinPay" :loading="loading">微信支付</button><!-- #endif --></view></view></view></view>
</template>
<script>export default {data() {return {title: 'request-payment',loading: false,typeId:0,vipName:'',price: 1,providerList: [],user:'',baseLocation: '',memberCardOrders:[],header: { 'Content-Type': 'application/x-www-form-urlencoded' }}},onLoad: function(e) {this.baseLocation = getApp().globalData.BaseUrl;this.user = uni.getStorageSync('user');if(e.id){this.typeId=e.id;}if(e.typeName){this.vipName=e.typeName;}if(e.currentPrice){this.price=e.currentPrice;}},methods: {//登录async login() {// #ifdef APP-PLUS || H5this.$loginForAppAndH5();// #endif// #ifdef MP-WEIXINthis.$loginForWeiXinApplet();// #endif},//微信支付weixinPay() {this.loading = true;uni.login({success: (e) => {let ticket = uni.getStorageSync('ticket'); //取出Cookieif (ticket) {this.header.Cookie = ticket;uni.request({url:this.baseLocation + '/api/client/pay/appletPaymentPay',header:this.header,data:{memberCardTypeId: this.typeId,payType: 'APPLETPAYMENT',orderAmount: this.price,memberCardTypeName: this.vipName,code:e.code},success: (res) => {if (res.data.code === 200) {let paymentData = res.data.payment;uni.requestPayment({timeStamp: paymentData.timeStamp,nonceStr: paymentData.nonceStr,package: paymentData.packageValue,signType: paymentData.signType,paySign: paymentData.paySign,success: (res) => {uni.showToast({title:'支付成功,即将跳转到会员中心...',icon:'none',duration:1000})uni.reLaunch({url:'membercenter'})},fail: (res) => {uni.showModal({content: "支付失败,原因为: " + res.errMsg,showCancel: false})return false;},complete: () => {this.loading = false;}})} else {uni.showModal({content: res.data.message,showCancel: false})return false;}},fail: (e) => {this.loading = false;uni.showModal({content: "支付失败,原因为: " + e.errMsg,showCancel: false})return false;}})}else{this.login(); }},fail: (e) => {this.loading = false;uni.showModal({content: "支付失败,原因为: " + e.errMsg,showCancel: false})return false;}})},//价格计算priceChange(e) {this.price = e.detail.value;}}}
</script><style>.rmbLogo {font-size: 40rpx;}button {background-color: #007aff;color: #ffffff;}.uni-h1.uni-center {display: flex;flex-direction: row;justify-content: center;align-items: flex-end;}.price {border-bottom: 1px solid #eee;width: 200rpx;height: 80rpx;padding-bottom: 4rpx;}.ipaPayBtn {margin-top: 30rpx;}
</style>
后端代码
<!--公众号(包括订阅号和服务号) -->
<dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-mp</artifactId><version>2.7.0</version>
</dependency>
<!--微信支付 -->
<dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-pay</artifactId><version>3.0.0</version>
</dependency>
<!--微信小程序 -->
<dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-miniapp</artifactId><version>3.0.0</version>
</dependency>
#微信小程序
wx.applet.appId=xxxxxxxxxxxxxxxx
wx.applet.appSecret=xxxxxxxxxxxxxxxx
package com.ltf.config;import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Data
@Component
@ConfigurationProperties(prefix = "wx.applet")
public class WeChatAppletProperties {/*** appId*/private String appId;/*** 公众平台***/private String appSecret;@Overridepublic String toString() {return ToStringBuilder.reflectionToString(this,ToStringStyle.MULTI_LINE_STYLE);}}
package com.ltf.controller;import com.ltf.common.ReqChanle;
import com.ltf.config.WeChatAppletProperties;
import com.ltf.config.WeChatPayProperties;
import com.ltf.dao.MemberCardOrdersDao;
import com.ltf.entity.MemberCardOrders;
import com.ltf.service.MemberCardOrdersService;
import com.ltf.service.MemberCardTrxorderDetailService;
import com.ltf.utils.HttpRequestUtil;
import com.ltf.utils.SingletonLoginUtils;
import com.ltf.utils.WebUtils;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;/*** 微信支付* @author xhz**/
@RestController
@RequestMapping(value = "/api/client/pay/")
public class WeChatPayController extends BaseController{private static final Logger logger = LoggerFactory.getLogger(WeChatPayController.class);@Autowiredprivate WxPayService wxPayService;@Autowiredprivate MemberCardOrdersService memberCardOrdersService;@Autowiredprivate MemberCardOrdersDao memberCardOrdersDao;@Autowiredprivate MemberCardTrxorderDetailService memberCardTrxorderDetailService;@Autowiredprivate WeChatAppletProperties weChatAppletProperties;/*** 1块钱转为 100 分* 元转分** @param bigDecimal 钱数目* @return 分*/private int yuanToFee(BigDecimal bigDecimal) {return bigDecimal.multiply(new BigDecimal(100)).intValue();}/*** 100分转为1块钱* 分转元* * @param price 钱数目* @return 元*/private String feeToYuan(Integer price) {return BigDecimal.valueOf(Long.valueOf(price)).divide(new BigDecimal(100)).toString();}/*** 小程序支付* @param request* @param memberCardTypeId* @param payType* @param orderAmount* @param memberCardTypeName* @param code* @return*/@SuppressWarnings("static-access")@GetMapping(value = "appletPaymentPay")@ResponseBodypublic JSONObject appletPaymentPay(HttpServletRequest request,@RequestParam("memberCardTypeId")String memberCardTypeId,@RequestParam("payType")String payType,@RequestParam("orderAmount")String orderAmount,@RequestParam("memberCardTypeName")String memberCardTypeName,@RequestParam("code")String code){try {Integer userId=SingletonLoginUtils.getLoginUserId(request);if(userId>0){Map<String, String> sourceMap = new HashMap<String, String>();sourceMap.put("memberCardTypeId", memberCardTypeId);// 会员卡类型idsourceMap.put("userId", userId+ "");//用户idsourceMap.put("reqchanle", ReqChanle.APLLET.toString());//用户请求来源sourceMap.put("payType", payType);// 支付类型sourceMap.put("reqIp", WebUtils.getIpAddr(request));// 用户ipsourceMap.put("orderAmount", orderAmount);// 订单原始金额,也是实际支付金额sourceMap.put("memberCardTypeName", memberCardTypeName);//会员卡类型名称Map<String, Object> res = memberCardOrdersService.addTrxorder(request,sourceMap);if(res.containsKey("msg")){return this.formatJSON(501, "会员卡订单创建失败!", res);}else{String param="appid="+weChatAppletProperties.getAppId()+"&secret="+weChatAppletProperties.getAppSecret()+"&js_code="+code+"&grant_type=authorization_code";String result=HttpRequestUtil.doJsonGet("https://api.weixin.qq.com/sns/jscode2session", param);if(result!=null&&!"".equals(result)){JSONObject jsonObject1=JSONObject.parseObject(result);if(jsonObject1.get("openid")!=null){WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();orderRequest.setAppid(weChatAppletProperties.getAppId());orderRequest.setBody(memberCardTypeName);orderRequest.setOutTradeNo(res.get("orderNo").toString());orderRequest.setTradeType("JSAPI");orderRequest.setTotalFee(yuanToFee(new BigDecimal(orderAmount)));String openId=jsonObject1.get("openid").toString();orderRequest.setOpenid(openId);// 获取微信支付用户的openIdorderRequest.setSpbillCreateIp(InetAddress.getLoopbackAddress().getHostAddress());orderRequest.setNotifyUrl("https://你的域名/api/client/pay/appletPaymentPayNotify");Object order = wxPayService.createOrder(orderRequest);res.put("payment", order);return this.formatJSON(200, "OK", res);}else{return this.formatJSON(500, "openId获取失败!",null);}}else{return this.formatJSON(500, "openId获取失败!",null);}}}else{return this.formatJSON(500, "当前登录已失效,请重新登录!",null);}} catch (Exception e) {logger.error("WeChatPayController.appletPaymentPay()----error", e);return this.formatJSON(500, "微信小程序支付时会员卡订单创建失败!",null);}}/**** @param xmlData 小程序支付返回的流* @return*/@RequestMapping(value = "appletPaymentPayNotify",method = {RequestMethod.GET,RequestMethod.POST})public String appletPaymentPayNotify(@RequestBody String xmlData){try {final WxPayOrderNotifyResult notifyResult = this.wxPayService.parseOrderNotifyResult(xmlData);//这里是存储我们发起支付时订单号的信息,所以取出来MemberCardOrders memberCardOrders=new MemberCardOrders();memberCardOrders.setOrderNo(notifyResult.getOutTradeNo());//根据订单号查询订单MemberCardOrders mco=memberCardOrdersDao.selectMemberCardOrdersByCondition(memberCardOrders);//验证商户id和价格,以防止篡改金额if(mco!=null){if(weChatPayProperties.getMchId().equals(notifyResult.getMchId())&¬ifyResult.getTotalFee().equals(yuanToFee(mco.getSumMoney()))){Map<String,Object> map=new HashMap<String,Object>();map.put("sumMoney", feeToYuan(notifyResult.getTotalFee()));//订单总金额map.put("outTradeNo", notifyResult.getTransactionId());//支付宝的交易号map.put("orderNo", notifyResult.getOutTradeNo());//商户系统的唯一订单号map.put("states", notifyResult.getResultCode());//交易状态map.put("payTime", notifyResult.getTimeEnd());//支付时间//修改会员卡订单信息String result1=memberCardOrdersService.updateMemberCardOrderInfoForNotify(map);if(result1.equals("error")){return WxPayNotifyResponse.fail("修改会员卡订单信息失败!");}//修改会员卡订单流水信息String result2=memberCardTrxorderDetailService.updateMemberCardTrxorderDetaiInfoForNotify(map);if(result2.equals("error")){return WxPayNotifyResponse.fail("修改会员卡订单流水信息失败!");}//成功后回调微信信息return WxPayNotifyResponse.success("回调成功!");}else{return WxPayNotifyResponse.fail("商户id和价格验证不通过!");}}else{return WxPayNotifyResponse.fail("订单号不存在!");}} catch (WxPayException e) {logger.error("WeChatPayController.appletPaymentPayNotify()----error", e);return WxPayNotifyResponse.fail("微信小程序支付回调有误!");}}}
相关文章:
【uniapp微信小程序+springBoot(binarywang)
uniapp前端代码 <template><view><page-head :title"title"></page-head><view class"uni-padding-wrap"><view style"background:#FFF; padding:50rpx 0;"><view class"uni-hello-text uni-cente…...
智能井盖的用处有哪些?好用在什么地方?
智能井盖是一种基于物联网技术的井盖系统,通过集成传感器、通信设备和数据处理功能,实现对井盖的实时监测、远程管理和智能化控制。WITBEE万宾的智能井盖传感器EN100-C2,只要在城市需要的井盖上面安装即可使用,一体式结构…...
微信小程序数据存储方式有哪些
在微信小程序中,数据存储方式有以下几种: 本地存储 本地存储是一种轻量级的数据存储方式,用于存储小量的数据,例如用户的配置信息、页面的状态等。微信小程序提供了 wx.setStorage() 和 wx.getStorage() 方法,用于将数…...
FTC局部路径规划代码分析
前置知识: costmap_2d::Costmap2DROS costmap; costmap_2d::Costmap2DROS 是一个ROS包中提供的用于处理2D成本地图的类。它是一个高级的接口,通常用于与ROS导航栈中的导航规划器和本地路径跟踪器等模块进行集成。 costmap 是一个指向 Costmap2DROS 对象的指针。通…...
SpringBoot集成Activiti7
SpringBoot集成Activiti7 SpringBoot版本使用2.7.16 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.16</version><relativePath/> <!-- lookup…...
25.1 MySQL SELECT语句
1. SQL概述 1.1 SQL背景知识 1946年, 世界上诞生了第一台电脑, 而今借由这台电脑的发展, 互联网已经成为一个独立的世界. 在过去几十年里, 许多技术和产业在互联网的舞台上兴衰交替. 然而, 有一门技术却从未消失, 甚至日益强大, 那就是SQL.SQL(Structured Query Language&…...
【VSCode】Windows环境下,VSCode 搭建 cmake 编译环境(通过配置文件配置)
除了之前的使用 VSCode 插件来编译工程外,我们也可以使用配置文件来编译cmake工程,主要依赖 launch.json 和 tasks.json 文件。 目录 一、下载编译器 1、下载 Windows GCC 2、选择编译器路径 二、配置 debug 环境 1、配置 lauch.json 文件 2、配置…...
useragent识别访问设备
背景需求 ruoyi框架,前后端分离。现在要在用户访问的时候根据不同的设备跳转到不同的登录页面。 教程 router/index.js 修改src/router/index.js,在这里增加自己的要跳转的页面 permission.js 在白名单中添加自己的登录页面 增加以下识别的代码 le…...
紫光同创FPGA实现UDP协议栈网络视频传输,带录像和抓拍功能,基于YT8511和RTL8211,提供2套PDS工程源码和技术支持
目录 1、前言免责声明 2、相关方案推荐我这里已有的以太网方案紫光同创FPGA精简版UDP方案紫光同创FPGA带ping功能UDP方案紫光同创FPGA精简版UDP视频传输方案 3、设计思路框架OV5640摄像头配置及采集数据缓冲FIFOUDP协议栈详解MAC层发送MAC发送模式MAC层接收ARP发送ARP接收ARP缓…...
【机器学习】逻辑回归
文章目录 逻辑回归定义损失函数正则化 sklearn里面的逻辑回归多项式逻辑回归 逻辑回归 逻辑回归,是一种名为“回归”的线性分类器,其本质是由线性回归变化而来的,一种广泛使用于分类问题中的广义回归算法。 线性回归是机器学习中最简单的的…...
DITA-OT 4.0新特性 - PDF themes,定制PDF样式的新方法
随着DITA-OT 4.0的发布,它提供了一种新的定制PDF样式方法,这种方法就是PDF theme。这篇文章来聊一聊这种定制PDF输出的新方法和实验结果。 在进入PDF theme细节之前,为各位读者梳理一下DITA-OT将DITA和Markdown发布成PDF的几种方法。 - 1 …...
MySQL 8.0 OCP认证精讲视频、环境和题库之四 多实例启动 缓存、事务、脏读
一、配置第一个mysqld服务 1、编辑选项文件,指定以下选项: [mysqld] basedir/mysql80 datadir/mysql80/data1 socket/mysql80/data1/mysqld.sock pid-file/mysql80/data1/mysqld.pid log-error/mysql80/dat…...
对代码感兴趣 但不擅长数学怎么办——《机器学习图解》来救你
目前,该领域中将理论与实践相结合、通俗易懂的著作较少。机器学习是人工智能的一部分,很多初学者往往把机器学习和深度学习作为人工智能入门的突破口,非科班出身的人士更是如此。当前,国内纵向复合型人才和横向复合型人才奇缺;具有…...
【EI会议征稿】第三届大数据、信息与计算机网络国际学术会议(BDICN 2024)
第三届大数据、信息与计算机网络国际学术会议(BDICN 2024) 2024 3rd International Conference on Big Data, Information and Computer Network 第三届大数据、信息与计算机网络国际学术会议(BDICN 2024)定于2024年1月12-14日在…...
【Arduino+ESP32+腾讯云+sg90】强制门户+腾讯云控制开关灯
作者有话说 博主对于Arduino开发并没有基础,但是为了实现更加方便的配网,这几天一直在尝试用ESP32-12F(因为手头刚好有一个,其他的也可以)来做远程开关灯!不知道大家是否注意到,上一篇利用STM32…...
windows中elasticsearch7中添加用户名密码验证
1.找到elsatic的bin目录输入cmd 2.生成ca证书 输入 elasticsearch-certutil ca 在es7根目录生成ca证书,输入密码时直接回车即可,否则后面会报错 Please enter the desired output file [elastic-stack-ca.p12]: #这里直接回车即可 Enter password for…...
linux安装达梦数据库(命令行安装)
安装达梦数据库 创建安装用户 1,创建安装用户组dinstall [rootdmDMServer1 ~]# groupadd -g 12345 dinstallgroupadd : 创建组 -g : 指定组id(GID) 12345: 指定的组名称 dinstall : 组名 2,创建安装用户dmdba [rootdmDMSe…...
Flutter——最详细(CustomScrollView)使用教程
CustomScrollView简介 创建一个 [ScrollView],该视图使用薄片创建自定义滚动效果。 [SliverList],这是一个显示线性子项列表的银子列表。 [SliverFixedExtentList],这是一种更高效的薄片,它显示沿滚动轴具有相同范围的子级的线性列…...
解决容器内deepspeed微调大模型报错
解决容器内deepspeed微调大模型报错:[launch.py:315:sigkill_handler] Killing subprocess 问题描述:解决办法 问题描述: 在容器中用deepspeed微调百川大模型2时,出现上述错误,错误是由于生成容器时,共享内…...
UE 插件模块引用
如Plugons中的模块A想要引用模块B: 1、模块A中的.uplugin文件加入↓ 2、模块A中的.Build.cs文件加入↓ 3、在模块A需要用到模块B的地方直接include 4、重新generate Project 5、重新编译 注意两个模块之间不能循环引用...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
Vue 3 + WebSocket 实战:公司通知实时推送功能详解
📢 Vue 3 WebSocket 实战:公司通知实时推送功能详解 📌 收藏 点赞 关注,项目中要用到推送功能时就不怕找不到了! 实时通知是企业系统中常见的功能,比如:管理员发布通知后,所有用户…...
性能优化中,多面体模型基本原理
1)多面体编译技术是一种基于多面体模型的程序分析和优化技术,它将程序 中的语句实例、访问关系、依赖关系和调度等信息映射到多维空间中的几何对 象,通过对这些几何对象进行几何操作和线性代数计算来进行程序的分析和优 化。 其中࿰…...
