当前位置: 首页 > news >正文

在线支付系列【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

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

3.2 埃尔米特转置

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

Python爬虫之Scrapy框架系列(13)——实战ZH小说爬取数据入MySql数据库

目录&#xff1a;1 数据持久化存储&#xff0c;写入Mysql数据库①定义结构化字段&#xff1a;②重新编写爬虫文件&#xff1a;③编写管道文件&#xff1a;④辅助配置&#xff08;修改settings.py文件&#xff09;&#xff1a;⑤navicat创库建表&#xff1a;⑥ 效果如下&#xf…...

MySQL篇02-三大范式,多表查询

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

vue-cli3创建Vue项目

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

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 文件夹强制约定放置所有布局文件&#xff0c;并以插槽的形式作用在页面中1.在app.vue里面2.component 组件使用Vue < component :is"">Vuex生命周期数据请求useFetchuseAsyncDat…...

Python编程自动化办公案例(1)

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.使用库讲解 1.xlrd 2.xlwt 二.主要案例 1.批量合并 模板如下&#xf…...

一站式 Elasticsearch 集群指标监控与运维管控平台

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

C# 调用Python

一、简介 IronPython 是一种在 NET 和 Mono 上实现的 Python 语言&#xff0c;由 Jim Hugunin&#xff08;同时也是 Jython 创造者&#xff09;所创造。 Python是一种跨平台的计算机程序设计语言。 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python是…...

51单片机最强模块化封装(3)

文章目录 前言一、创建smg文件,添加smg文件路径二、smg文件编写三、模块化测试总结前言 本篇文章将带大家继续封装我们的代码。 这里我们会封装数码管的操作函数。 一、创建smg文件,添加smg文件路径 这里的操作就不过多解释了,大家自行看前面的文章即可。 51单片机模块化…...

【CSS 布局】水平垂直居中

CSS 布局-水平垂直居中 一、水平居中 创建一个父盒子&#xff0c;和子盒子 <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丢失消息分为如下几种情况&#xff1a; 生产者丢消息&#xff1a; 生产者将数据发送到RabbitMQ的时候&#xff0c;可能在传输过程中因为网络等问题而将数据弄丢了。 RabbitMQ自己丢消息&#xff1a; 如果没有开启RabbitMQ的持久化&#x…...

十四、Linux网络:高级IO

目录 五种IO模型 同步IO 阻塞IO 非阻塞IO 信号驱动IO IO多路转接 异步IO...

带你走进API安全的知识海洋

Part1什么是API API&#xff08;Application Programming Interface&#xff0c;应用程序接口&#xff09;是一些预先定义的接口&#xff08;如函数、HTTP接口&#xff09;&#xff0c;或指软件系统不同组成部分衔接的约定。用来提供应用程序与开发人员基于某软件或硬件得以访…...

【Java】TCP的三次握手和四次挥手

三次握手 TCP三次握手是一个经典的面试题&#xff0c;它指的是TCP在传递数据之前需要进行三次交互才能正式建立连接&#xff0c;并进行数据传递。&#xff08;客户端主动发起的&#xff09;TCP之所以需要三次握手是因为TCP双方都是全双工的。 什么是全双工&#xff1f; TCP任何…...

JUC并发编程

1.什么是JUC java.util工具包、包、分类 业务&#xff1a;普通业务线程代码 Thread Runable: 没有返回值、效率相比Callable相对较低。 2.线程和进程 进程&#xff1a;一个程序&#xff0c;QQ.exe Music.exe 程序的集合 一个进程往往可以包含多个线程&#xff0c;至少包含一个…...

概率统计·假设检验【正态总体均值的假设检验、正态总体方差的假设检验】

均值假设检验定义 2类错误 第1类错误&#xff08;弃真&#xff09;&#xff1a;当原假设H0为真&#xff0c;观察值却落入拒绝域&#xff0c;因而拒 绝H0这类错误是“以真为假” 犯第一类错误的概率显著性水平α第2类错误&#xff08;取伪&#xff09;&#xff1a;当原假设H0不…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...