【畅购商城】微信支付之支付模块
目录
支付页面
接口
后端实现
前端实现
支付页面
步骤一:创建 flow3.vue组件

步骤二:引入第三方资源(js、css)
<script>
import TopNav from '../components/TopNav'
import Footer from '../components/Footer'export default {head: {title: '首页',link: [{rel:'stylesheet',href: '/style/success.css'},],script: []},components: {TopNav,Footer,},
}
</script>
接口
POST http://localhost:10010/order-service/pay
{"sn" : "1255513323915579400"
}

后端实现
步骤一:编写 PayRequest,用于封装数据

package com.czxy.changgou4.vo;import lombok.Data;/*** @author 桐叔* @email liangtong@itcast.cn*/
@Data
public class PayRequest {private Long sn;
}
步骤二:检查order服务,yml文件中是否有微信配置

sc:pay:appID: wx8397f8696b538317mchID: 1473426802key: T6m9iK73b0kn9g5v426MKfHQH7X8rKwbhttpConnectTimeoutMs: 5000httpReadTimeoutMs: 10000
步骤三:编写PayProperties,用于加载微信配置

package com.czxy.changgou4.config;import com.github.wxpay.sdk.WXPayConfig;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;import java.io.InputStream;/*** @author 桐叔* @email liangtong@itcast.cn*/
@Data
@ConfigurationProperties(prefix = "sc.pay")
public class PayProperties implements WXPayConfig {private String appID; // 公众账号IDprivate String mchID; // 商户号private String key; // 生成签名的密钥private int httpConnectTimeoutMs; // 连接超时时间private int httpReadTimeoutMs; // 读取超时时间@Overridepublic InputStream getCertStream() {//加载证书,需要通过账号中心生成return null;}}
步骤四:编写PayState,自定义支付状态

package com.czxy.changgou4.utils;import lombok.Getter;/*** 自定义支付状态,微信支持多种状态,此处统一四种:* SUCCESS—支付成功、NOTPAY—未支付、CLOSED—已关闭、PAYERROR--支付失败* @author 桐叔* @email liangtong@itcast.cn*/
@Getter
public enum PayState {NOT_PAY(0,"未支付"),SUCCESS(1,"支付成功"),CLOSED(2,"已关闭"),PAY_ERROR(3,"支付失败");PayState(int code,String desc) {this.code = code;this.desc = desc;}private int code; //自定义编码private String desc; //描述信息
}
步骤五:编写PayHelper,用于微信操作的工具类
package com.czxy.changgou4.utils;import com.czxy.changgou4.config.PayProperties;
import com.github.wxpay.sdk.WXPay;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Map;/*** @author 桐叔* @email liangtong@itcast.cn*/
@Component
@EnableConfigurationProperties(PayProperties.class)
public class PayHelper {private WXPay wxPay;@Beanpublic WXPay wxPay(PayProperties payProperties){if(wxPay == null){wxPay = new WXPay(payProperties);}return wxPay;}private static final Logger logger = LoggerFactory.getLogger(PayHelper.class);public PayHelper() {}public PayHelper(PayProperties payProperties) {wxPay = new WXPay(payProperties);}public String createPayUrl(Long sn) {String key = "pay.url." + sn;try {Map<String, String> data = new HashMap<>();// 商品描述data.put("body", "商城测试");// 订单号data.put("out_trade_no", sn.toString());//货币data.put("fee_type", "CNY");//金额,单位是分data.put("total_fee", "1");//调用微信支付的终端IP(商城的IP)data.put("spbill_create_ip", "127.0.0.1");//回调地址data.put("notify_url", "http://test.jingxi.com/wxpay/notify");// 交易类型为扫码支付data.put("trade_type", "NATIVE");//商品id,使用假数据data.put("product_id", "1234567");Map<String, String> result = this.wxPay.unifiedOrder(data);if ("SUCCESS".equals(result.get("return_code"))) {if("SUCCESS".equals(result.get("result_code"))){String url = result.get("code_url");return url;} else {logger.error("创建预交易订单失败,错误信息:{}", result.get("err_code_des"));return null;}} else {logger.error("创建预交易订单失败,错误信息:{}", result.get("return_msg"));return null;}} catch (Exception e) {logger.error("创建预交易订单异常", e);return null;}}/*** 查询订单状态* 交易状态参考:(trade_state)SUCCESS—支付成功REFUND—转入退款NOTPAY—未支付CLOSED—已关闭REVOKED—已撤销(付款码支付)USERPAYING--用户支付中(付款码支付)PAYERROR--支付失败(其他原因,如银行返回失败)* @param sn* @return*/public PayState queryOrder(Long sn) {Map<String, String> data = new HashMap<>();// 订单号data.put("out_trade_no", sn.toString());try {Map<String, String> result = this.wxPay.orderQuery(data);if("SUCCESS".equals(result.get("return_code"))){if("SUCCESS".equals(result.get("result_code"))) {String tradeState = result.get("trade_state");if ("SUCCESS".equals(tradeState)) {return PayState.SUCCESS;}if ("NOTPAY".equals(tradeState)) {return PayState.NOT_PAY;}if ("CLOSED".equals(tradeState)) {return PayState.CLOSED;}}}return PayState.PAY_ERROR;} catch (Exception e) {logger.error("查询订单状态异常", e);return PayState.PAY_ERROR;}}
}
步骤五:编写PayService,调用工具类,用于生成支付接口

package com.czxy.changgou4.service;import com.czxy.changgou4.vo.PayRequest;/*** @author 桐叔* @email liangtong@itcast.cn*/
public interface PayService {public String pay(PayRequest payRequest);
}
package com.czxy.changgou4.service.impl;import com.czxy.changgou4.service.PayService;
import com.czxy.changgou4.utils.PayHelper;
import com.czxy.changgou4.vo.PayRequest;
import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** @author 桐叔* @email liangtong@itcast.cn*/
@Service
public class PayServiceImpl implements PayService {@Resourceprivate PayHelper payHelper;@Overridepublic String pay(PayRequest payRequest) {//根据sn查询订单//获得微信支付路径String payUrl = payHelper.createPayUrl(payRequest.getSn());//返回支付路径return payUrl;}
}
步骤六:编写PayController,根据sn生产微信支付路径

package com.czxy.changgou4.controller;import com.czxy.changgou4.service.PayService;
import com.czxy.changgou4.vo.BaseResult;
import com.czxy.changgou4.vo.PayRequest;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** @author 桐叔* @email liangtong@itcast.cn*/
@RestController
@RequestMapping("/pay")
public class PayController {@Resourceprivate PayService payService;@PostMappingpublic BaseResult pay(@RequestBody PayRequest payRequest){//获得支付路径String payUrl = payService.pay(payRequest);//返回return BaseResult.ok("二维码生产成功").append("wxurl",payUrl);}}
前端实现
步骤一:修改apiclient.js文件,生成位置支付路径

pay : ( params ) => {return axios.post("/order-service/pay" ,params )}
步骤二:拷贝qrcode.min.js 用于生成二维码

步骤三:导入qrcode.min.js

script: [{ type: 'text/javascript', src: '/js/qrcode.min.js' }]
步骤四:页面加载成功,把微信支付路径生产二维码
data() {return {sn: this.$route.query.sn,}},async mounted() {let {data} = await this.$request.pay({"sn":this.sn})new QRCode( document.getElementById("qrcode") , data.other.wxurl )},
步骤五:确定二维码生成的位置

<p><div id="qrcode" style="width:256px;margin: 0 auto;"></div>
</p>
步骤六:优化,添加样式,
<style>#qrcode img {background-color: #fff;padding: 6px;}
</style>
相关文章:
【畅购商城】微信支付之支付模块
目录 支付页面 接口 后端实现 前端实现 支付页面 步骤一:创建 flow3.vue组件 步骤二:引入第三方资源(js、css) <script> import TopNav from ../components/TopNav import Footer from …...
网络安全专有名词详解_2
57.Webshell 就是以ASP、php、jsp、cgi等网页文件形式存在的一种命令执行环境,也叫做网页的后门,可以上传下载文件,查看数据库和执行任意的程序命令等。 58.跨站攻击 XSS,是指攻击者利用网站程序对用户输入过滤不足,输…...
【传感器技术与应用】第2章 基本电量传感器,电位器式传感器,电感式传感器,电容式传感器
注作者了解更多 我的其他CSDN专栏 毕业设计 求职面试 大学英语 过程控制系统 工程测试技术 虚拟仪器技术 可编程控制器 工业现场总线 数字图像处理 智能控制 传感器技术 嵌入式系统 复变函数与积分变换 单片机原理 线性代数 大学物理 热工与工程流体力学 数…...
【day20】集合深入探讨
模块19回顾 在深入探讨模块20之前,让我们回顾一下day19中的关键内容: Collection集合:单列集合的顶级接口,提供了add、addAll、clear、size、isEmpty、remove、toArray、contains等方法。迭代器(Iterator)…...
【英语语法】用must表对过去推测时,要用完成时must have been / must have done(不能直接用过去时)
文章目录 疑问解释1. 表达过去的推测2. 与时态一致3. 语法结构的限制4. 例子对比总结 疑问 This must have been a year-round activity as no structures have been found which would have been used to shelter animals in the winter. 为什么must表示对过去推测要用完成时&…...
数值计算期末考试重点(一)(黄云清版教材)
1.误差的分类 2.绝对误差和绝对误差限 3.绝对误差和绝对误差限 例题(课后习题1.2) 4.有效数字 例题(课后习题1.6) 5.算法的数值稳定性 例题(课后习题1.9) 这个手算比较艰难,还是给计算机算吧&am…...
使用 pushy 热更新后 sentry 不能正常显示源码
问题 使用 Android Studio 打包后,上传使用 sentry 官网命令打包的 sourcemap 文件,sentry能正常显示异常位置源码。 使用 pushy 热更新之后,sentry 不能正常显示异常位置的源代码。 如下图: 问题原因: 使用 pushy …...
IntelliJ IDEA 远程调试
IntelliJ IDEA 远程调试 在平时开发 JAVA 程序时,在遇到比较棘手的 Bug 或者是线上线下结果不一致的情况下,我们会通过打 Log 或者 Debug 的方式去定位并解决问题,两种方式各有利弊,今天就简要介绍下如何通过远程 Debug 的情况下…...
Java实现简单爬虫——爬取疫情数据
1.项目准备 在项目中使用到了jsoup和fastjson jsoup用于创建一个连接(绘画) 用于获取和解析HTML页面 而fastjson对数据进行一个格式化 在pom.xml导入坐标 <dependencies><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</a…...
大数据技术-Hadoop(一)Hadoop集群的安装与配置
目录 一、准备工作 1、安装jdk(每个节点都执行) 2、修改主机配置 (每个节点都执行) 3、配置ssh无密登录 (每个节点都执行) 二、安装Hadoop(每个节点都执行) 三、集群启动配置&a…...
04.HTTPS的实现原理-HTTPS的混合加密流程
04.HTTPS的实现原理-HTTPS的混合加密流程 简介1. 非对称加密与对称加密2. 非对称加密的工作流程3. 对称加密的工作流程4. HTTPS的加密流程总结 简介 主要讲述了HTTPS的加密流程,包括非对称加密和对称加密两个阶段。首先,客户端向服务器发送请求…...
flutter插件开发-ios
flutter插件开发是一个重要的技能,拓展flutter与原生的通信,将一些公用的东西封装,给不同的项目使用。 阅读前置: flutter基本通道调用 objective-c基础语法 ios项目基础知识 目录 1、创建一个插件项目2、项目结构3、编写原生代码…...
【AI日记】24.12.29 kaggle 比赛 2-17
【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 工作 参加:kaggle 比赛 Regression with an Insurance Dataset时间:6 小时 读书 书名:教育的本质时间:1 小时 律己 工作时间:优作息:…...
设计模式-创建型-工厂方法模式
什么是工厂方法模式? 工厂方法模式(Factory Method Pattern)是 创建型设计模式之一,目的是通过定义一个用于创建对象的接口,让子类决定实例化哪个类。简而言之,工厂方法模式通过延迟对象的创建过程到子类来…...
解决opencv在windows环境下读取中文图片名问题
在Windows系统下,cv2读取中文图片名时可能会报错,主要是因为OpenCV的imread函数在处理文件路径时,默认使用的是系统的编码格式,而Windows的默认编码可能与文件名的编码不匹配。具体原因包括: 编码不匹配:Wi…...
Apache Commons Pool :介绍与使用
Apache Commons Pool :介绍与使用 什么是 commons-pool2? commons-pool2 是 Apache Commons 提供的一个开源对象池实现框架。它旨在为应用程序提供通用的对象池支持,方便开发者管理资源(如数据库连接、网络连接等)复…...
sentinel-请求限流、线程隔离、本地回调、熔断
请求限流:控制QPS来达到限流的目的 线程隔离:控制线程数量来达到限流的目录 本地回调:当线程被限流、隔离、熔断之后、就不会发起远程调用、而是使用本地已经准备好的回调去提醒用户 熔断:熔断也叫断路器,当失败、或者…...
微信小程序 app.json 配置文件解析与应用
目录 一、什么是 app.json? 二、app.json 文件的基本结构 三、详细解析 app.json 配置项 1. pages:小程序页面路径配置 2. window:窗口样式配置 3. tabBar:底部标签栏配置 4. networkTimeout:网络请求超时配置 …...
C语言-共用体(联合体)
1.共用体(联合体) 1.共用体union是一个能在同一个存储空间存储不同类型数据的类型 2.共用体所占的内存长度等于其最长成员的长度。 3.同一内存段可以用来存放几种不同类型的成员,但每一瞬时只有一种起作用 4.共用体变量中起作用的成员是最后一次存放的成员ÿ…...
C++算法知识点
创建队列: 关于队列的一些常用方法: 创建栈: 将字符串换成整数:...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
