在线支付系列【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不…...
如何预测机组设备健康状态?你可能需要这套解决方案
1. 应用场景随机振动[注1]会发生在工业物联网的各个场景中,包括产线机组设备的运行、运输设备的移动、试验仪器的运行等等。通过分析采集到的振动信号可以预估设备的疲劳年限、及时知晓设备已发生的异常以及预测未来仪器可能发生的异常等等。本篇教程会提供给有该方…...
C++类和对象:面向对象编程的核心。| 面向对象还编什么程啊,活该你是单身狗。
👑专栏内容:C学习笔记⛪个人主页:子夜的星的主页💕座右铭:日拱一卒,功不唐捐 文章目录一、前言二、面向对象编程三、类和对象1、类的引入2、类的定义Ⅰ、声明和定义在一起Ⅱ、声明和定义分开Ⅲ、成员变量命…...
CUDA虚拟内存管理
CUDA中的虚拟内存管理 文章目录CUDA中的虚拟内存管理1. Introduction2. Query for support3. Allocating Physical Memory3.1. Shareable Memory Allocations3.2. Memory Type3.2.1. Compressible Memory4. Reserving a Virtual Address Range5. Virtual Aliasing Support6. Ma…...
线程池小结
什么是线程池 线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们前面学过的实现了Runnable或Callable接口的实例对象; 为什么使用线程池 …...
vue3状态管理模式 Pinia
状态管理库 Pinia是Vue的专属状态管理库,它允许你跨组件或页面共享状态 1:安装与使用pinia 1.1 安装语法:npm install pinia1.2 创建一个pinia(根存储)并将其传递给应用程序 import { createApp } from vue import…...
python基于django的自媒体社区交流平台
自媒体社区平台采用python技术,基于django框架,mysql数据库进行开发,实现了以下功能: 本系统主要包括管理员,用户,商家和普通管理员四个角色组成,主要包括以下功能: 1;前台:首页、需求通告、优质案例、帮助中心、意见反馈、个人中心、后台管理…...
Python中类和对象(2)
1.继承 Python 的类是支持继承的:它可以使用现有类的所有功能,并在无需重新编写代码的情况下对这些功能进行扩展。 通过继承创建的新类称为 “子类”,被继承的类称为 “父类”、“基类” 或 “超类”。 继承语法是将父类写在子类类名后面的…...
SpringMvc入门
Spring与Web环境的集成 1.ApplicationContext应用上下文的获取方式 分析 之前获取应用上下文对象每次都是从容器中获取,编写时都需要new ClasspathXmlApplicationContext(Spring配置文件),这样的弊端就是配置加载多次应用上下文就创建多次。 在Web项目…...
设计模式之单例模式(C++)
作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 一、单例模式是什么? 单例模式是一种创建型的软件设计模式,在工程项目中非常常见。通过单例模式的设计&am…...
贪心算法(基础)
目录 一、什么是贪心? (一)以教室调度问题为例 1. 问题 2. 具体做法如下 3. 因此将在这间教室上如下三堂课 4. 结论 (二)贪心算法介绍 1. 贪心算法一般解题步骤 二、最优装载问题 (一…...
快速搭建网站 优帮云/谷歌独立站seo
在我们生活中,对于账户的自动登录已经很常见了,所以利用过滤器实现这个功能。主要介绍用户的自动登录和取消自动登录,以及实现一天自动登录或者n天实现自动登录,当用户ip被加入到黑名单之后,直接利用过滤器返回一个警告…...
公司的网站怎么做推广/百度竞价推广计划
该工具类是用于操作Java.lang.String类的。 StringUtils类与String类的区别在于:此类是null安全的,即如果输入参数String为null,则不会抛出NullPointerException异常,代码更健壮。以函数isEmpty为例子:存在字符串strin…...
关键词优化怎样/丽水百度seo
转自:https://www.pinlue.com/article/2021/05/2918/4511619339951.html...
网站色调设计方案/广州网站建设
目录 1、安装编译依赖环境 2、源码获得: 3、配置编译参数 4、 编译安装 5、基本配置 6、测试 7、pip安装 1、安装编译依赖环境 sudo apt-get install build-essential checkinstall libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk…...
现在建网站还能赚钱吗/万能导航网
2019独角兽企业重金招聘Python工程师标准>>> 高性价比深度学习神器!阿里云GPU实例V100 最深度评测 在 GTC 2017 大会上,NVIDIA 的 CEO 黄仁勋正式发布了其新一代旗舰计算卡 Tesla V100,但是一项技术从发布到真正使用到生产环境中&…...
泉州哪个公司网站做的好/冯耀宗seo视频教程
本文详细介绍了十大排序算法,包括算法的思路,代码以及特点如果你觉得对你有帮助,记得双击屏幕哦~小伙伴们好~ 我想大家学习算法之旅的开端就是各种排序算法吧,的确,排序算法广泛的应用性以及它的简洁基础等性质是初学者…...