微信支付

文档地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1 

 封装的工具类

package com.qf.fmall.utils;import cn.hutool.core.util.XmlUtil;
import cn.hutool.http.HttpRequest;
import org.apache.shiro.crypto.hash.Md5Hash;import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;public class WeixinPayUtils {public static final  String orderSubmit="https://api.mch.weixin.qq.com/pay/unifiedorder";public static final  String orderQueryUrl="https://api.mch.weixin.qq.com/pay/orderquery";public static final String appkey="sbNCm1JnevqI36LrEaxFwcaT0hkGxFnC";public static void main(String[] args) {String s = weixinPay("sadsadasa", "wqeqweqeq");System.out.println(s);}public static String weixinPay(String oid,String describe){//1. 组织请求map,必传字段如下//这里可有序可以无序,但是计算签名的时候必须有序,规定!按Key排序TreeMap<String, String> treeMap = new TreeMap<>();treeMap.put("appid","wx632c8f211f8122c6");//商户的应用IDtreeMap.put("mch_id","1497984412"); //商户号treeMap.put("notify_url","http://47.118.45.73:8080/pay/callback"); // 商户提供的回调地址String randomstr = UUID.randomUUID().toString().replaceAll("-", ""); //生成随机数treeMap.put("nonce_str",randomstr); // 长度32个字符的随机字符串,干扰项treeMap.put("body",describe); // 订单描述信息treeMap.put("out_trade_no",oid); // 订单编号treeMap.put("total_fee","1");  // 1 分钱treeMap.put("trade_type","NATIVE"); // 支付类型treeMap.put("fee_type","CNY"); // 币种treeMap.put("sign_type","MD5"); // 签名算法//计算签名String tempString = treeMap.toString().replace("{", "").replace("}", "").replace(", ","&")+"&key="+appkey;String sign = new Md5Hash(tempString).toHex().toUpperCase();treeMap.put("sign",sign);//map转XML字符串String xml = XmlUtil.mapToXmlStr(treeMap);//用Hutool工具类发送post请求String result = HttpRequest.post(orderSubmit).body(xml).execute().body();// xml str ----> mapMap<String, Object> resultMap = XmlUtil.xmlToMap(result);String url = (String) resultMap.get("code_url");return  url;}public static String queryStatus(String orderId) {//1. 组织请求map,必传字段如下//这里可有序可以无序,但是计算签名的时候必须有序,规定!按Key排序TreeMap<String, String> treeMap = new TreeMap<>();treeMap.put("appid","wx632c8f211f8122c6");//商户的应用IDtreeMap.put("mch_id","1497984412"); //商户号String randomstr = UUID.randomUUID().toString().replaceAll("-", ""); //生成随机数treeMap.put("nonce_str",randomstr); // 长度32个字符的随机字符串,干扰项treeMap.put("out_trade_no",orderId); // 订单编号treeMap.put("sign_type","MD5"); // 签名算法//计算签名String tempString = treeMap.toString().replace("{", "").replace("}", "").replace(", ","&")+"&key="+appkey;String sign = new Md5Hash(tempString).toHex().toUpperCase();treeMap.put("sign",sign);//map转XML字符串String xml = XmlUtil.mapToXmlStr(treeMap);//用Hutool工具类发送post请求String result = HttpRequest.post(orderQueryUrl).body(xml).execute().body();// xml str ----> mapMap<String, Object> resultMap = XmlUtil.xmlToMap(result);String trade_state = (String) resultMap.get("trade_state");return  trade_state;}
}

controller

package com.qf.fmall.controller;import com.qf.fmall.common.ResultVo;
import com.qf.fmall.entity.Orders;
import com.qf.fmall.service.IOrdersService;
import com.qf.fmall.utils.FmallConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.Arrays;
import java.util.HashMap;/*** <p>* 订单  前端控制器* </p>** @author jmj* @since 2023-08-24*/
@RestController
@RequestMapping("/order")
@CrossOrigin
@Slf4j
public class OrdersController {@Autowiredprivate IOrdersService ordersService;@PostMapping("/add")public ResultVo add(Integer[] cids,@RequestBody Orders orders) throws Exception {log.info("入参为:cid={},orders={}", Arrays.toString(cids),orders);HashMap<String,Object> map= ordersService.addOrder(cids,orders);return ResultVo.vo(FmallConstants.SUCCESS_CODE,FmallConstants.SUCCESS_MSG,map);}@GetMapping("/status/{orderId}")public ResultVo status(@PathVariable("orderId") String orderId){log.info("入参为:orderId={}",orderId);String s=   ordersService.status(orderId);log.info("传回来的状态:{}",s);return ResultVo.vo(FmallConstants.SUCCESS_CODE,FmallConstants.SUCCESS_MSG,s);}}

service

package com.qf.fmall.service.impl;import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qf.fmall.entity.*;
import com.qf.fmall.mapper.OrdersMapper;
import com.qf.fmall.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.fmall.utils.WeixinPayUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;/*** <p>* 订单  服务实现类* </p>** @author jmj* @since 2023-08-24*/
@Service
@Slf4j
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {@Autowiredprivate IShoppingCartService shoppingCartService;@Autowiredprivate IProductSkuService iProductSkuService;@Autowiredprivate IProductService iProductService;@Autowiredprivate IOrderItemService iOrderItemService;@Transactional(rollbackFor = Exception.class)@Overridepublic synchronized HashMap<String, Object> addOrder(Integer[] cids, Orders orders) throws Exception {//1. 查询用户购物车中的对应的商品套餐库存量是否还足够List<Map<String, Object>> shoppingcars = shoppingCartService.listMaps(new QueryWrapper<ShoppingCart>().select("sku_id  skuId, SUM(`cart_num`) `sum`").in("cart_id", cids).groupBy("sku_id"));log.info("查出来的购物车按ID分类计算的集合为{}",shoppingcars);TreeSet<String> productIds = new TreeSet<>();//查出购物车中所有的productIdfor (Map<String, Object> shoppingcar : shoppingcars) {ProductSku one = iProductSkuService.getOne(new QueryWrapper<ProductSku>().eq("sku_id", shoppingcar.get("skuId")));productIds.add(one.getProductId());Integer stock = one.getStock();Double cartNum = (Double) shoppingcar.get("sum");if (cartNum>stock){throw new Exception("库存不足,购买失败");}
//             减少库存one.setStock((stock-cartNum.intValue()));iProductSkuService.updateById(one);}//过了这个循环没有抛异常,就可以往下走,说明库存够//2. 生成唯一的订单编号String orderId = UUID.randomUUID().toString().replace("-", "");orders.setOrderId(orderId);//3. 生成订单主表(orders表)中的数据orders.setCreateTime(new Date());//创建时间orders.setUpdateTime(new Date());//修改时间// 产品名称:untitled用逗号隔开//先查Product产品IDStringBuilder builder = new StringBuilder();for (String productId : productIds) {//查出每个产品中的名字,放到字符串缓冲流中,并用逗号拼接builder.append(iProductService.getOne(new QueryWrapper<Product>().eq("product_id",productId)).getProductName());builder.append(",");}//删除最后一个逗号,拼接转化为字符串String untitled = builder.deleteCharAt(builder.length() - 1).toString();orders.setUntitled(untitled);// 订单的状态,初始值1,待付款 statusorders.setStatus("1");//待付款// 逻辑删除状态,初始值为0 delete_statusorders.setDeleteStatus(0);log.info("生成的order对象为:{}",orders);//将对象添加到订单表里this.save(orders);//4. 生成订单明细表的数据 (OrderItem表)//有几个cid就有几个定单ArrayList<OrderItem> orderItems = new ArrayList<>();for (Integer cartId : cids) {OrderItem orderItem = new OrderItem();String orderItemId = UUID.randomUUID().toString().replace("-", "");//设置32位随机数作为ItemId 放入orderItem对象里orderItem.setItemId(orderItemId);//订单Id注入orderItem.setOrderId(orders.getOrderId());//查一下购物车 idShoppingCart shoppingCart = shoppingCartService.getOne(new QueryWrapper<ShoppingCart>().eq("cart_id", cartId));ProductSku productSku = iProductSkuService.getOne(new QueryWrapper<ProductSku>().eq("sku_id", shoppingCart.getSkuId()));Product product = iProductService.getOne(new QueryWrapper<Product>().eq("product_id", productSku.getProductId()));//查一下产品对象//注入产品IDorderItem.setProductId(productSku.getProductId());orderItem.setProductName(product.getProductName());orderItem.setProductImg(productSku.getSkuImg());orderItem.setSkuId(productSku.getSkuId());orderItem.setSkuName(productSku.getSkuName());orderItem.setProductPrice(new BigDecimal(productSku.getSellPrice()));orderItem.setBuyCounts(Integer.parseInt(shoppingCart.getCartNum()));orderItem.setTotalAmount(new BigDecimal(productSku.getSellPrice()*Integer.parseInt(shoppingCart.getCartNum())));//转换时间SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");orderItem.setBasketDate(format.parse(shoppingCart.getCartTime()));orderItem.setIsComment(0);log.info("每个订单详情对象:{}",orderItem);//保存到集合orderItems.add(orderItem);}//5. 保存订单到数据库log.info("添加到数据库的订单集合对象:{}",orderItems);iOrderItemService.saveBatch(orderItems);//清空购物车List<Integer> list = Arrays.asList(cids);shoppingCartService.removeBatchByIds(list);//6. 跟微信支付平台交互,获取可以支付的urlString url = WeixinPayUtils.weixinPay(orders.getOrderId(),orders.getUntitled());log.info("url:{}",url);//7. 组织返回的map数据HashMap<String, Object> map = new HashMap<>();map.put("orderId",orders.getOrderId());map.put("productNames",orders.getUntitled());map.put("payUrl",url);return map;}@Overridepublic String status(String orderId) {//1.掉微信支付的查询订单状态接口,获取订单状态String status= WeixinPayUtils.queryStatus(orderId);//2.如果支付成功了,需要修改订单表中的订单状态和支付时间if (status.equals("SUCCESS")){Orders orders = new Orders();orders.setOrderId(orderId);orders.setStatus("2");updateById(orders);return "2";}return "-1";}}

封装工具类

pom

<!--   微信支付 sdk (sdk用来简化调用的工具包)   --><dependency><groupId>com.github.wxpay</groupId><artifactId>wxpay-sdk</artifactId><version>0.0.3</version></dependency></dependencies>

 WxSdkUtils

package com.qf.fmall2302.wxpay;import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConfig;import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;public class WxSdkUtils {public String getPayUrl(String orderid,String desc,Long amount) throws Exception {// 创建sdk的核心对象WXPay wxPay = new WXPay(new MyWxConfig());HashMap<String, String> map = new HashMap<>();String randomstr = UUID.randomUUID().toString().replaceAll("-", "");map.put("nonce_str",randomstr); // 长度32个字符的随机字符串,干扰项map.put("body",desc); // 订单描述信息map.put("out_trade_no",orderid); // 订单编号map.put("total_fee","1");  // 1 分钱map.put("trade_type","NATIVE"); // 支付类型map.put("fee_type","CNY"); // 币种map.put("notify_url","http://47.118.45.73:8080/pay/callback"); // 商户提供的回调地址map.put("sign_type","MD5"); // 签名算法Map<String, String> result = wxPay.unifiedOrder(map);return result.get("code_url");}public static String queryStatus(String orderid) throws Exception {WXPay wxPay = new WXPay(new MyWxConfig());HashMap<String, String> map = new HashMap<>();map.put("out_trade_no",orderid);Map<String, String> result = wxPay.orderQuery(map);return result.get("trade_state");}public static void main(String[] args) throws Exception {String orderid = "202308241617987";WXPay wxPay = new WXPay(new MyWxConfig());HashMap<String, String> map = new HashMap<>();map.put("out_trade_no",orderid);Map<String, String> result = wxPay.orderQuery(map);System.out.println(result);}}

MyWxConfig implements WXPayConfig 

package com.qf.fmall2302.wxpay;import com.github.wxpay.sdk.WXPayConfig;import java.io.InputStream;public class MyWxConfig implements WXPayConfig {public static final String appid = "wx632c8f211f8122c6";public static final String mch_id = "1497984412";public static final String appkey = "sbNCm1JnevqI36LrEaxFwcaT0hkGxFnC";@Overridepublic String getAppID() {return appid;}@Overridepublic String getMchID() {return mch_id;}@Overridepublic String getKey() {return appkey;}@Overridepublic InputStream getCertStream() {return null;}@Overridepublic int getHttpConnectTimeoutMs() {return 0;}@Overridepublic int getHttpReadTimeoutMs() {return 0;}
}

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

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

相关文章

【keepalived双机热备与 lvs(DR)】

目录 一、概述 1.简介 2.原理 3.作用 二、安装 1.配置文件 2.配置项 三、功能模块 1.core 2.vrrp 3.check 四、配置双机热备 1.master 2.backup 五、验证 1.ping验证 2.服务验证 六、双机热备的脑裂现象 七、keepalivedlvs&#xff08;DR&#xff09; 1.作…

性能测试告诉你 mysql 数据库存储引擎该如何选?

简介 数据库存储引擎&#xff1a;是数据库底层软件组织&#xff0c;数据库管理系统&#xff08;DBMS&#xff09;使用数据引擎进行创建、查询、更新和删除数据。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能&#xff0c;使用不同的存储引擎&#xff0c;还可以…

Wireshark数据抓包分析之互联网控制报文协议_ICMP

一、实验目的: 通过使用wireshark抓取的ICMP数据包对这个ICMP控制报文进行分析 二、预备知识&#xff1a; 1.ICMP协议概述&#xff1a;ICMP是Internet Control Message Protocol的缩写&#xff0c;即互联网控制报文协议。它是TCP/IP协议族的一个子协议&#xff0c;用于IP主机、…

HDLBits-Verilog学习记录 | Verilog Language-Vectors

文章目录 11.vectors | vector012.vectors in more detail | vector113.Vector part select | Vector214.Bitwise operators | Vectorgates15.Four-input gates | Gates416.Vector concatenation operator | Vector317.Vector reversal 1 | Vectorr18. Replication operator | …

SD-WebUI和ComfyUI的局域网访问设置!

如何通过局域网访问AI绘画软件&#xff0c;这是星球成员提的一个问题&#xff0c;而且两个软件都问到了&#xff0c;我也回答过了。现在把内容整理一下发出来&#xff0c;大家可能用得着。 SD-WebUI和ComfyUI这两个AI绘画工具都是通过浏览器来使用&#xff0c;但是默认情况下并…

Request对象和response对象

一、概念 request对象和response对象是通过Servlet容器&#xff08;如Tomcat&#xff09;自动创建并传递给Servlet的。 Servlet容器负责接收客户端的请求&#xff0c;并将请求信息封装到request对象中&#xff0c;然后将request对象传 递给相应的Servlet进行处理。类似地&…

低代码赋能| 智慧园区项目开发痛点及解决方案

智慧园区是一个综合体&#xff0c;集技术开发、产业发展和学术研究于一体。作为未来智慧城市建设的核心&#xff0c;智慧园区充当着“产业大脑”和“指挥中心”的角色。它通过整合园区内的制造资源和第三方服务能力&#xff0c;实现园区各组成部分的协调运作、良性循环和相互促…

【数学建模】清风数模中正课4 拟合算法

拟合算法 在插值算法中&#xff0c;我们得到的曲线一定是要经过所有的函数点的&#xff1b;而用拟合所得到的曲线则不一样&#xff0c;拟合问题中&#xff0c;不需要得到的曲线一定经过给定的点。 拟合的目的是寻求一个函数曲线&#xff0c;使得该曲线在某种准则下与所有的数…

TCP可靠性机制

确认号/序列号/ACK TCP帮助确保数据的准确传递。为了做到这一点&#xff0c;其使用了一些特殊的标记和信息&#xff0c;其中包括序号、确认号和ACK字段。 其中&#xff0c;它将每个字节的数据都进行了编号. 即为序列号. 序列号&#xff1a;就像给书中的每一页都编了号码一样&a…

EMR电子病历系统 SaaS电子病历编辑器源码 电子病历模板编辑器

EMR&#xff08;Electronic Medical Record&#xff09;指的是电子病历。它是一种基于电子文档的个人医疗记录&#xff0c;可以包括病人的病史、诊断、治疗方案、药物处方、检查报告和护理计划等信息。EMR采用计算机化的方式来存储、管理和共享这些信息&#xff0c;以便医生和医…

RISC-V中国峰会 | 256核服务器高调亮相,谁与争锋?

8月23日&#xff0c;第三届RISC-V中国峰会&#xff08;RISC-V Summit China 2023&#xff09;在北京香格里拉饭店正式开幕&#xff0c;来自世界各地的行业精英汇聚一堂&#xff0c;为RISC-V生态系统建言献策&#xff0c;凝心聚力&#xff01; 中国工程院院士倪光南、RISC-V国际…

高等数学(上)【基础学科、极限部分】

学习【高等数学&#xff08;上&#xff09;】6小时从0基础直追满绩&#xff01;_哔哩哔哩_bilibili 高数基础 高等数学无非分为三个部分&#xff1a;极限、导数&#xff08;微分&#xff09;和积分——构成了微积分 高等数学学的就是 微积分&#xff0c;整体其实只是一个思想 …

K8S cluster with multi-masters on Azure VM

拓扑参考&#xff1a; 在 Azure VM 实例上部署 KubeSphere 基础模板 需要修改 IP 地址和 VM Image的可以在模板中修改。 {"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","contentVersion": &q…

达梦数据库分区表介绍

概述 本文将对达梦数据库分区表概念、创建、维护进行介绍。 1.分区表概念 1.1 分区表使用场景 近几年&#xff0c;随着移动支付快速发展&#xff0c;银行交易系统中【移动小微支付场景】使用越来越多&#xff0c;系统中流水账单表数据量巨大&#xff0c;往往上TB。 为了提高…

Embedding 向量生成GPT数据使用相关

如果使用python3.6的版本&#xff0c;使用pycharm创建工程&#xff0c;那么默认会使用 docx包&#xff0c;这样运行程序会爆异常&#xff0c;突然想起以前请教的一个大神&#xff0c;想当 初&#xff0c;这个问题困扰了我 两天时间&#xff0c;在此记录一下&#xff1a; pytho…

Linux上实现分片压缩及解压分片zip压缩包 - 及zip、unzip命令详解

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

AI夏令营第三期 - 基于论文摘要的文本分类与关键词抽取挑战赛笔记

赛题&#xff1a;基于论文摘要的文本分类与关键词抽取 背景&#xff1a;高效的从海量医学文献中提取疾病诊断和治疗关键信息 任务&#xff1a;通过论文摘要判断论文是否为医学文献 样例 数据集&#xff1a;csv文件&#xff0c;字段&#xff1a;标题、作者、摘要、关键词 评价指…

Bootstrap的类container与类container-fluid有什么区别?

阅读本文前建议先阅读下面两篇博文&#xff1a; 怎么样通过Bootstrap已经编译好(压缩好)的源码去查看符合阅读习惯的源码【通过Source Map(源映射)文件实现】 在CSS中&#xff0c;盒模型中的padding、border、margin是什么意思&#xff1f; 以下是Bootstrap的类 container 的盒…

wireshark进行网络监听

一、实验目的&#xff1a; 1&#xff09;掌握使用CCProxy配置代理服务器&#xff1b; 2&#xff09;掌握使用wireshark抓取数据包&#xff1b; 3&#xff09;能够对数据包进行简单的分析。 二、预备知识&#xff1a; 包括监听模式、代理服务器、中间人攻击等知识点&#xf…

ElementUI中的日历组件加载无效的问题

在ElementUI中提供了一个日历组件。在某些场景下还是比较有用的。只是在使用的时候会有些下坑&#xff0c;大家要注意下。   官网提供的信息比较简介。我们在引入到项目中使用的时候可以能会出现下面的错误提示。 Unknown custom element: <el-calendar> - did you …