在线支付系列【22】微信支付实战篇之集成服务商API
有道无术,术尚可求,有术无道,止于术。
文章目录
- 前言
- 1. 环境搭建
- 2. 特约商户进件
- 3. 统一下单
- 总结
前言
在上篇文档中,我们做好了接入前准备工作,接下来使用开源框架集成服务商相关API
。
一个简单的支付系统完成支付流程图如下所示:
1. 环境搭建
引入开源微信支付框架。
<dependency><groupId>com.github.binarywang</groupId><artifactId>wx-java-pay-spring-boot-starter</artifactId><version>4.4.8.B</version></dependency>
配置上篇文档中我们获取到的参数、秘钥、证书。
wx:pay:appId: wx7xxxxx # 服务商应用ID(公众号)mchId: xxxxx # 服务商收款账号apiV3Key: UDuLFDcmy5Eb6o0xxxxx # 服务商API V3密钥certSerialNo: 34345964330B66427E0D3D2882xxxxx # 服务商商户证书序列privateKeyPath: classpath:cert/apiclient_key.pem # 服务商apiclient_key.pem证书文件的绝对路径或者以classpath:开头的类路径privateCertPath: classpath:cert/apiclient_cert.pem # 服务商apiclient_cert.pem证书文件的绝对路径或者以classpath:开头的类路径
新建商户管理表、支付订单表等~
2. 特约商户进件
官方API文档
该支付系统,首先需要入驻子商户,可以集成微信提供的进件接口,这样自由度和管理更方便。
该框架的Applyment4SubService
接口实现类已经集成微信特约商户进件API
,我们只需要设置对应的请求参数对象即可,如果是直接集成微信SDK
,还需要封装参数、解析响应比较麻烦。
public interface Applyment4SubService {/*** 提交申请单API*/WxPayApplymentCreateResult createApply(WxPayApplyment4SubCreateRequest request) throws WxPayException;/*** 通过业务申请编号查询申请状态** @param businessCode 业务申请编号* 1、只能由数字、字母或下划线组成,建议前缀为服务商商户号。* 2、服务商自定义的唯一编号。* 3、每个编号对应一个申请单,每个申请单审核通过后生成一个微信支付商户号。* 4、若申请单被驳回,可填写相同的“业务申请编号”,即可覆盖修改原申请单信息。* 示例值:1900013511_10000*/ApplymentStateQueryResult queryApplyStatusByBusinessCode(String businessCode) throws WxPayException;/*** 通过申请单号查询申请状态*/ApplymentStateQueryResult queryApplyStatusByApplymentId(String applymentId) throws WxPayException;/*** 根据特约子商户ID查询结算账户*/SettlementInfoResult querySettlementBySubMchid(String subMchid) throws WxPayException;/*** 修改结算帐号*/String modifySettlement(String subMchid, ModifySettlementRequest request) throws WxPayException;}
示例代码如下:
@Operation(summary = "提交申请单")@GetMapping("/createApply")public R<String> createApply(@RequestParam(required = false) String applymentId) throws WxPayException {WxPayApplyment4SubCreateRequest request = new WxPayApplyment4SubCreateRequest();// 主体资料:主体类型、是否是金融机构、营业执照、登记证书、组织机构代码证、单位证明函照片、经营者/法人身份证件、最终受益人信息列表(UBO)、小微辅助证明材料(subjectType为小微商户时必填)WxPayApplyment4SubCreateRequest.SubjectInfo subjectInfo = WxPayApplyment4SubCreateRequest.SubjectInfo.builder().build().setFinanceInstitution(false).setBusinessLicenseInfo(null);// 省略.......request.setSubjectInfo(subjectInfo);// 补充材料WxPayApplyment4SubCreateRequest.AdditionInfo additionInfo=new WxPayApplyment4SubCreateRequest.AdditionInfo();additionInfo.setBusinessAdditionMsg("补充说明");additionInfo.setBusinessAdditionPics(null) ;// 补充材料additionInfo.setLegalPersonCommitment("法人开户承诺函");additionInfo.setLegalPersonVideo("法人开户意愿视频");request.setAdditionInfo(additionInfo);// 结算银行账户WxPayApplyment4SubCreateRequest.BankAccountInfo bankAccountInfo=new WxPayApplyment4SubCreateRequest.BankAccountInfo();bankAccountInfo.setBankAccountType(BankAccountTypeEnum.BANK_ACCOUNT_TYPE_CORPORATE); // 账户类型:对公银行账户bankAccountInfo.setAccountName("开户名称"); // 开户名称bankAccountInfo.setAccountBank("开户银行");bankAccountInfo.setBankAddressCode("开户银行省市编码");bankAccountInfo.setBankBranchId("开户银行联行号");bankAccountInfo.setBankName("开户银行全称(含支行)");bankAccountInfo.setAccountNumber("银行账号");request.setBankAccountInfo(bankAccountInfo);// 业务申请编号request.setBusinessCode("业务申请编号");// 经营资料request.setBusinessInfo(null); // 省略.......// 超级管理员信息request.setContactInfo(null);// 省略.......// 结算规则request.setSettlementInfo(null);// 省略.......// 调用微信APIApplyment4SubService applyment4SubService=new Applyment4SubServiceImpl(wxPayService);WxPayApplymentCreateResult apply = applyment4SubService.createApply(request);String applyMentId = apply.getApplymentId(); // 返回申请单IDreturn R.success(applyMentId);}@Operation(summary = "通过申请单号查询申请状态")@GetMapping("/queryApply")public R<ApplymentStateQueryResult> queryApply(@RequestParam(required = true) String applymentId) throws WxPayException {// 调用API 查询申请状态Applyment4SubService applyment4SubService=new Applyment4SubServiceImpl(wxPayService);ApplymentStateQueryResult result = applyment4SubService.queryApplyStatusByApplymentId(applymentId);return R.success(result);}
3. 统一下单
在EcommerceService
接口实现类中,集成了服务商下单API。多种支付方式时,使用同一个方法即可。
public interface EcommerceService {/*** <pre>* 服务商模式普通支付API(APP支付、JSAPI支付、H5支付、NATIVE支付).* 请求URL:https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi* 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/transactions_sl.shtml* </pre>** @param tradeType 支付方式* @param request 请求对象* @return 调起支付需要的参数 transactions result* @throws WxPayException the wx pay exception*/TransactionsResult partner(TradeTypeEnum tradeType, PartnerTransactionsRequest request) throws WxPayException;/*** <pre>* 普通查询订单API* 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/ecommerce/e_transactions/chapter3_5.shtml* </pre>** @param request 商户订单信息* @return 支付订单信息* @throws WxPayException the wx pay exception*/PartnerTransactionsResult queryPartnerTransactions(PartnerTransactionsQueryRequest request) throws WxPayException;/*** <pre>* 关闭普通订单API* 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/ecommerce/e_transactions/chapter3_6.shtml* </pre>** @param request 关闭普通订单请求* @throws WxPayException the wx pay exception* @return*/String closePartnerTransactions(PartnerTransactionsCloseRequest request) throws WxPayException;
}
示例代码如下:
@Operation(summary = "统一下单/(V3)")@PostMapping("/ecommerceNative")public R<?> ecommerceNative(OrderEntity mchOrder,String subMchId) throws Exception {try {// 1. 创建请求对象PartnerTransactionsRequest orderRequest=new PartnerTransactionsRequest();// 2. 根据订单系统传过来的订单信息组装支付参数,创建支付订单orderRequest.setSpMchid(subMchId); // 子商户号orderRequest.setDescription("示例值:Image形象店-深圳腾大-QQ公仔"); // 商品描述:示例值:Image形象店-深圳腾大-QQ公仔PartnerTransactionsRequest.Amount amount = new PartnerTransactionsRequest.Amount();amount.setTotal(1); // 订单金额信息orderRequest.setAmount(amount);orderRequest.setOutTradeNo(mchOrder.getOutTradeNo()); // 商户订单号,商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一orderRequest.setNotifyUrl("https://8da1-120-227-23-190.jp.ngrok.io/pay/wechat/notify"); // 通知地址// 3. 发起V3 服务商发起NATIVE支付EcommerceServiceImpl ecommerceService=new EcommerceServiceImpl(wxPayService);TransactionsResult result = ecommerceService.partner(com.github.binarywang.wxpay.bean.ecommerce.enums.TradeTypeEnum.NATIVE, orderRequest);log.info("NATIVE支付成功,返回二维码URL" + result.getCodeUrl());// 4. 省略后续操作return R.success(result);} catch (Exception e) {log.error("微信支付失败!,原因:{}", e.getMessage());e.printStackTrace();return R.fail();}}
总结
在weixin-java-pay
框架中,几乎所有的微信API
都帮我们集成好了,我们只需要设置对应的参数即可,甚至每个方法对应的官网API文档也贴上去了,好像实在也没什么可讲的~
相关文章:

在线支付系列【22】微信支付实战篇之集成服务商API
有道无术,术尚可求,有术无道,止于术。 文章目录前言1. 环境搭建2. 特约商户进件3. 统一下单总结前言 在上篇文档中,我们做好了接入前准备工作,接下来使用开源框架集成服务商相关API。 一个简单的支付系统完成支付流程…...

3.2 埃尔米特转置
定义 对于复矩阵,转置又不一样,常见的操作是共轭转置,也叫埃尔米特转置Hermitian transpose。埃尔米特转置就是对矩阵先共轭,再转置,一般来说用三种符号表示埃尔米特转置: 第一种符号是AHA^HAH,…...

Python爬虫之Scrapy框架系列(13)——实战ZH小说爬取数据入MySql数据库
目录:1 数据持久化存储,写入Mysql数据库①定义结构化字段:②重新编写爬虫文件:③编写管道文件:④辅助配置(修改settings.py文件):⑤navicat创库建表:⑥ 效果如下…...

MySQL篇02-三大范式,多表查询
数据入库时,由于数据设计不合理,会存在数据重复、更新插入异常等情况, 故数据库中表的设计遵循的设计规范:三大范式1.第一范式(1NF)要求数据库的每一列都是不可分割的原子数据项,即原子性。强调的是列的原子性,即数据库中每一列的…...

vue-cli3创建Vue项目
文章目录前言一、使用vue-cli3创建项目1.检查当前vue的版本2.下载并安装Vue-cli33.使用命令行创建项目二、关于配置前言 本文讲解了如何使用vue-cli3创建属于自己的Vue项目,如果本文对你有所帮助请三连支持博主,你的支持是我更新的动力。 下面案例可供…...

Linux perf probe 的使用(三)
文章目录前言一、Dynamic Tracing二、kprobes2.1 perf kprobe 的使用2.2 kprobe Arguments3.3 tcp_sendmsg()3.3.1 Kernel: tcp_sendmsg()3.3.2 Kernel: tcp_sendmsg() with size3.3.2 Kernel: tcp_sendmsg() line number and local variable三、uprobes的使用3.1 perf uprobe …...
python GUI编程 多窗口跳转
# 多窗口跳转例子from tkinter import *def main(): # 主窗体def goto(num):root.destroy() # 关闭主窗体if num 1:one() # 进入第1个窗体elif num 2:two() # 进入第2个窗体root Tk()root.geometry(300x150600200)root.title(登录窗口)but1 Button(root, text"进入…...

nuxt 学习笔记
这里写目录标题路由跳转NuxtLinkquery参数params参数嵌套路由tab切换效果layouts 文件夹强制约定放置所有布局文件,并以插槽的形式作用在页面中1.在app.vue里面2.component 组件使用Vue < component :is"">Vuex生命周期数据请求useFetchuseAsyncDat…...

Python编程自动化办公案例(1)
作者简介:一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页 目录 前言 一.使用库讲解 1.xlrd 2.xlwt 二.主要案例 1.批量合并 模板如下…...

一站式 Elasticsearch 集群指标监控与运维管控平台
上篇文章写了一下消息运维管理平台,今天带来的是ES的监控和运维平台。目前初创企业,不像大型互联网公司,可以重复的造轮子。前期还是快速迭代试错阶段,方便拿到市场反馈,及时调整自己的战略和产品方向。让自己活下去&a…...

C# 调用Python
一、简介 IronPython 是一种在 NET 和 Mono 上实现的 Python 语言,由 Jim Hugunin(同时也是 Jython 创造者)所创造。 Python是一种跨平台的计算机程序设计语言。 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python是…...
51单片机最强模块化封装(3)
文章目录 前言一、创建smg文件,添加smg文件路径二、smg文件编写三、模块化测试总结前言 本篇文章将带大家继续封装我们的代码。 这里我们会封装数码管的操作函数。 一、创建smg文件,添加smg文件路径 这里的操作就不过多解释了,大家自行看前面的文章即可。 51单片机模块化…...
【CSS 布局】水平垂直居中
CSS 布局-水平垂直居中 一、水平居中 创建一个父盒子,和子盒子 <div class"parent"><div class"child"></div> </div>基本样式如下 .parent {background-color: #fff; }.child {background-color: #999;width: 100p…...

【C++】类和对象--类的6个默认成员函数
目录1.类的6个默认成员函数2.构造函数2.1概念2.2特性3.析构函数3.1概念3.2特性4.拷贝构造函数4.1概念4.2特征5.赋值运算符重载5.1运算符重载5.2赋值运算符重载5.3前置和后置重载5.4流插入和流提取运算符重载6.const成员7.取地址重载和const取地址操作符重载1.类的6个默认成员函…...
常见面试题---------如何处理MQ消息丢失的问题?
如何处理MQ消息丢失的问题? RabbitMQ丢失消息分为如下几种情况: 生产者丢消息: 生产者将数据发送到RabbitMQ的时候,可能在传输过程中因为网络等问题而将数据弄丢了。 RabbitMQ自己丢消息: 如果没有开启RabbitMQ的持久化&#x…...
十四、Linux网络:高级IO
目录 五种IO模型 同步IO 阻塞IO 非阻塞IO 信号驱动IO IO多路转接 异步IO...
带你走进API安全的知识海洋
Part1什么是API API(Application Programming Interface,应用程序接口)是一些预先定义的接口(如函数、HTTP接口),或指软件系统不同组成部分衔接的约定。用来提供应用程序与开发人员基于某软件或硬件得以访…...

【Java】TCP的三次握手和四次挥手
三次握手 TCP三次握手是一个经典的面试题,它指的是TCP在传递数据之前需要进行三次交互才能正式建立连接,并进行数据传递。(客户端主动发起的)TCP之所以需要三次握手是因为TCP双方都是全双工的。 什么是全双工? TCP任何…...
JUC并发编程
1.什么是JUC java.util工具包、包、分类 业务:普通业务线程代码 Thread Runable: 没有返回值、效率相比Callable相对较低。 2.线程和进程 进程:一个程序,QQ.exe Music.exe 程序的集合 一个进程往往可以包含多个线程,至少包含一个…...

概率统计·假设检验【正态总体均值的假设检验、正态总体方差的假设检验】
均值假设检验定义 2类错误 第1类错误(弃真):当原假设H0为真,观察值却落入拒绝域,因而拒 绝H0这类错误是“以真为假” 犯第一类错误的概率显著性水平α第2类错误(取伪):当原假设H0不…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...

毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...