微信支付APIv3

article/2025/7/14 11:49:07

文章目录

  • 微信支付
    • 之前我的密钥啥的都是放到配置文件里面以后可以再写一个文件
    • 基础支付APIv3介绍
    • 获取验签和HttpClient
      • APIv3证书与密钥使用说明
    • 微信支付的SDK工具
    • Native支付流程
    • 我们程序运行时的日志也可以使用log.debug
    • 在方法堆栈里面查看我们程序执行的方法调用顺序
    • 内网穿透
    • 微信支付相关的实体
    • 用户支付成功之后微信回调商户的通知接口,我们的商户自己的回调通知接口必须要进行验签
    • 用户支付成功之后微信回调商户的通知接口,一定要加锁,并且一定要处理微信发来的重复请求
    • 微信支付通知回调商户接口的时候携带的参数有密文需要我们自己解析
    • 如果用户支付成功之后微信一直没有回调商户接口,那么商户会主动调用微信的查询订单API去查询订单情况
    • 微信支付APIv3版本与微信支付APIv2版本的区别
    • 微信支付V3版本引入的SDK是何时被用到的?
    • 代码托管地址

微信支付

之前我的密钥啥的都是放到配置文件里面以后可以再写一个文件

之前,我做微信支付的时候,我把所有的商户号,商户证书序列号,商户证书私钥都放到了配置文件里面,以后像这类信息,可以和配置文件区分开,单独写一个文件,然后把它们放到这个文件里面,如下图:

在这里插入图片描述

在这里插入图片描述

然后我们如果想要取出来商户的相关信息,我们只需要通过WxPayConfig配置类的get方法就可以获取,如下图:

在这里插入图片描述

把我们的wxpay.properties变成SpringBoot的配置文件,如下图:

在这里插入图片描述

在这里插入图片描述

其实这些信息我们还是放到了配置文件里面,只不过取出来的时候,我们用的不再是@Value注解了,但其实我觉得还是使用@Value注解的这种方式比较简便。

基础支付APIv3介绍

内容:

1.引入支付参数

2.加载商户私钥

3.获取平台证书和验签器

4.获取HttpClient对象

5.Api字典和接口规则

6.内网穿透:微信向我们的开发服务器发送请求的时候,我们的开发服务器必须有一个微信可以访问的外网地址,而我们的开发服务器一般都是局域网环境的,是没有独立ip的,因此需要进行内网穿透,让微信那边可以访问到我们开发环境的接口。

7.API v3

获取验签和HttpClient

APIv3证书与密钥使用说明

微信地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay3_0.shtml,如下图:

img

解释上述流程:商户先使用自己的私钥对签名进行加密,然后微信端再用商户的公钥对签名解密并验证,然后微信端再拿自己的私钥对签名进行加密,接着商户端再拿微信的公钥进行解密,最上面这部分是典型的非对称加密,先拿自己的私钥加密,对方再拿我的公钥解密。

微信支付的SDK工具

在这里插入图片描述

社区源码如下图:

在这里插入图片描述

获取PrivateKey对象如下图:

在这里插入图片描述

如何获取证书对象,如下图:

在这里插入图片描述

对接微信支付SDKV3版本的时候,我们需要根据社区源码中的介绍写一个WxPayConfig配置类,用来做商户对接微信的前期准备(即自动的进行签名验证,加密解密和证书相关的操作),其实也就是需要在生成CloseableHttpClient对象之前,要自动的进行微信的验签,加密解密,敏感数据处理等一些列的操作,这样我们开发的时候就不用管这些细节了,微信的SDK已经自动的帮助我们处理了,如下图:

在这里插入图片描述

Native支付流程

官方网址:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_4.shtml,如下图:

img

我们程序运行时的日志也可以使用log.debug

在这里插入图片描述

在这里插入图片描述

在方法堆栈里面查看我们程序执行的方法调用顺序

在这里插入图片描述

在这里插入图片描述

注意我们Frames里面的方法堆栈,只有当我们打断点的时候可以看到,如果不打断点是看不到方法堆栈信息的,如下图:
在这里插入图片描述

内网穿透

当微信回调我们的时候,我们本地必须要有一个公网可以访问的地址,所以我们必须要使用内网穿透,如下图:

在这里插入图片描述

先去ngrok官网下载工具,如下图:

在这里插入图片描述

在这里插入图片描述

然后双击运行我们的额ngrok.exe内网穿透工具,如下图:

在这里插入图片描述

接着去官网找两条命令依次执行,如下图:
在这里插入图片描述

注意,必须要先创建一个用户,这样登录ngrok之后才可以获取到第一条命令的token的值,如下图:

在这里插入图片描述

这两条命令的运行结果如下图:

在这里插入图片描述

正常情况下我们得到的最后的外网地址,是可以在外网访问的,但是我这里却不能,不知道是什么原因,但是原理就是这个原理,知道这个思想原理就可以了。

后来我又发现了一个特别好用的内网穿透工具,叫做快解析

首先去官网注册账号,如下图:

在这里插入图片描述

然后点击免费下载,下载之后的结果如下图:

在这里插入图片描述

双击运行之后,配置内网映射,如下图:
在这里插入图片描述

最后就可以获取到内网穿透地址了,如下图:

在这里插入图片描述

然后在商户那里设置我们的外网地址,如下图:

在这里插入图片描述

微信支付相关的实体

微信支付包括用户方,商户方,和微信方。

所以对于一个用户在某个商户使用微信付款购买了某个商品之后,都会牵涉到那些数据库表呢?

  • 首先肯定是会有一个微信订单表的,每成功进行一次订单交易,微信方都需要记录这次订单的相关信息,包括本次的微信订单号用户的基本信息(包括手机号,姓名等)商户的基本信息(包括商户号等信息)用户购买的商品的基本信息(包括商品的名字,商品的金额,商品的数量等)
  • 对于商户来说,它也是要把这笔订单的信息存放到商户订单表中的,包括本次的商户订单号,用户购买的商品的基本信息(包括商品的名字,商品的金额,商品的数量等)用户的基本信息(包括手机号,姓名等)还有退款表(用户购买商品之后可能会退款,我们也需要用一个数据库记录,这里面要包括微信退款id,微信单号,商户订单号,商品退款理由等)
  • 所以关于微信支付,我现在能想到的数据库表有商户订单表,微信订单表,商品信息表,用户信息表这四个

在这里插入图片描述

商户方有商户方自己的商户订单表和商户退款表,所以商户方有商户的商户订单号和商户退款号;

微信方有微信方自己的微信订单表和微信退款表,所以微信方有微信的微信订单号和微信退款号。

用户支付成功之后微信回调商户的通知接口,我们的商户自己的回调通知接口必须要进行验签

微信支付流程中,当微信回调商户的接口的时候,要求这个商户的这个接口必须要对发来的请求进行验签,以确保这个请求是从微信发送过来的,而不是其他的黑客伪造的,如下图:

在这里插入图片描述

在这里插入图片描述

我们程序里的验签代码,如下图:

在这里插入图片描述

用户支付成功之后微信回调商户的通知接口,一定要加锁,并且一定要处理微信发来的重复请求

官网说明,如下图:

在这里插入图片描述

首先,**先来说一下为什么要在商户的微信回调接口中加锁?**因为你假如,现在有两个微信回调请求,同时到达,这个时候商户就会进行两次处理,而本来商户如果接收到微信发来的回调请求(请求中包含用户的支付成功信息),这个时候商户会给用户进行发货,但如果商户接收了两次这样的请求,它就会发两次货,这样就会造成资金损失。怎么加锁呢?如下图:

在这里插入图片描述

在这里插入图片描述

**再来说一下怎么处理微信重复的回调请求?**本来,在商户接收微信发来的第一个回调请求的时候,会更新订单状态,更新为支付成功,然后会存放一条日志,如下图:

在这里插入图片描述

但是如果微信回调商户,商户给微信返回的结果不对,(比如说由于网络延迟,商户返回给微信的结果超过了5秒钟,那么这个时候微信就会再次回调商户)那么微信重复再发送好多次回调请求,那么商户就会更新订单状态为支付成功(微信回调商户的时候,其实就是把用户支付成功的结果告诉商户,商户再去把它的订单表的订单状态修改为支付成功),更新很多次,这倒无所谓,尽管再更新结果都是一样的;但是对于支付日志就不一样了,会存放很多条重复的信息,这就会对结果产生影响了,所以为了解决这个问题,需要在商户的支付通知接口中验证一下订单状态,如果不是未支付状态就不再更新数据库了,如下图:

在这里插入图片描述

微信支付通知回调商户接口的时候携带的参数有密文需要我们自己解析

在这里插入图片描述

resource解密后的明文信息如下图:

在这里插入图片描述

解密代码如下图:

在这里插入图片描述

如果用户支付成功之后微信一直没有回调商户接口,那么商户会主动调用微信的查询订单API去查询订单情况

微信官方的流程图如下图:

在这里插入图片描述

我们程序中是把商户主动查询微信订单这部分功能写到了定时任务里面,如果商户那边的订单一直超时未支付,到一定的时间之后,商户会去主动的去微信官方查询这笔订单,然后再根据微信方返回结果中的订单状态进行相关的处理,比如如果微信那边返回的交易状态为成功,就更新商户订单状态为成功,如果微信那边返回的交易状态为失败,那么就让商户再向微信发送一个关闭订单的请求,并更新商户订单状态为关闭。

在这里插入图片描述

微信支付APIv3版本与微信支付APIv2版本的区别

在这里插入图片描述

目前微信的大部分功能都已经用V3版的接口实现了,但是仍然有一小部分功能还没有用V3版的接口实现,但是后续会陆续的使用V3版本的接口去实现,如下图:

在这里插入图片描述

对于V3版本来说,无论我们是给微信接口传递参数还是微信给我们的响应结果都是json格式的;但是对于V2版本来说,无论我们是给微信接口传递参数还是微信给我们的响应结果都是xml格式的;所以对于V3版本我们设计到的转换主要是map集合和json的转换,而对于V2版本我们涉及到的转换主要是map集合和xml的转换。

微信支付V3版本引入的SDK是何时被用到的?

首先我们的请求行和我们最后执行请求使用的类一个是HttpPost类,一个是CloseableHttpResponse类,这两个类都是我们SpringBoot项目中自带的类,不需要我们特别的引入,当商户调用微信的统一下单API接口的时候,是如何使用这两个类的呢?如下图:

在这里插入图片描述

而现在我们使用的无论是请求行对象还是执行请求的客户端对象,都不是微信支付V3版本为我们提供的SDK中的,如下图:

在这里插入图片描述

那么现在问题来了,我们既然引入了微信支付V3版本的SDK,那么我们是什么时候使用的这个SDK的呢?如下图:

在这里插入图片描述

而虽然引入了微信的这个SDK即wechatpay,但是我们在控制器方法中发起请求,执行请求并不是运用的这个方法,而是运用的我们SpringBoot项目自带的包,只不过我们执行wxPayClient.execute(httpPost)这个方法的时候会去调用我们微信的SDK,会调用wechatpay包里面的方法,进行签名验证,加解密等系列操作,为什么会这样呢?因为我们的wxPayClient变量其实是CloseableHttpClient类,而这个类我们已经加入到了IOC中,并且从IOC容器中得到这个CloseableHttpClient类的时候,会调用微信支付V3的SDK中的方法,如下图:

在这里插入图片描述

所以如果想使用微信支付V3版本,最关键的就是要写一个WxPayConfig配置类,对CloseableHttpClient对象进行前期准备,并且把微信支付相关的证书序列号,商户号,私钥,APIv3等一系列信息都给存到这个WxPayConfig配置类里面,如下:

package com.atguigu.paymentdemo2.config;import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.*;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;@Configuration
@PropertySource("classpath:wxpay.properties") //读取配置文件
@ConfigurationProperties(prefix="wxpay") //读取wxpay节点
@Data //使用set方法将wxpay节点中的值填充到当前类的属性中
@Slf4j
public class WxPayConfig {// 商户号private String mchId;// 商户API证书序列号private String mchSerialNo;// 商户私钥文件private String privateKeyPath;// APIv3密钥private String apiV3Key;// APPIDprivate String appid;// 微信服务器地址private String domain;// 接收结果通知地址private String notifyDomain;// APIv2密钥private String partnerKey;/*** 获取商户的私钥文件* @param filename* @return*/private PrivateKey getPrivateKey(String filename){try {return PemUtil.loadPrivateKey(new FileInputStream(filename));} catch (FileNotFoundException e) {throw new RuntimeException("私钥文件不存在", e);}}/*** 获取签名验证器* @return*/@Beanpublic Verifier getVerifier() throws HttpCodeException, GeneralSecurityException, IOException, NotFoundException {log.info("获取签名验证器");//获取商户私钥PrivateKey privateKey = getPrivateKey(privateKeyPath);// 获取证书管理器实例CertificatesManager certificatesManager = CertificatesManager.getInstance();// 向证书管理器增加需要自动更新平台证书的商户信息certificatesManager.putMerchant(mchId, new WechatPay2Credentials(mchId,new PrivateKeySigner(mchSerialNo, privateKey)), apiV3Key.getBytes(StandardCharsets.UTF_8));// ... 若有多个商户号,可继续调用putMerchant添加商户信息// 从证书管理器中获取verifierVerifier verifier = certificatesManager.getVerifier(mchId);return verifier;}/*** 获取http请求对象* @param verifier* @return*/@Bean(name = "wxPayClient")public CloseableHttpClient getWxPayClient(Verifier verifier){log.info("获取httpClient");//获取商户私钥PrivateKey privateKey = getPrivateKey(privateKeyPath);WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create().withMerchant(mchId, mchSerialNo, privateKey).withValidator(new WechatPay2Validator(verifier));// ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新CloseableHttpClient httpClient = builder.build();return httpClient;}/*** 获取HttpClient,无需进行应答签名验证,跳过验签的流程*/@Bean(name = "wxPayNoSignClient")public CloseableHttpClient getWxPayNoSignClient(){//获取商户私钥PrivateKey privateKey = getPrivateKey(privateKeyPath);//用于构造HttpClientWechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()//设置商户信息.withMerchant(mchId, mchSerialNo, privateKey)//无需进行签名验证、通过withValidator((response) -> true)实现.withValidator((response) -> true);// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新CloseableHttpClient httpClient = builder.build();log.info("== getWxPayNoSignClient END ==");return httpClient;}}

这样我们使用CloseableHttpClient执行请求的时候,如下图:

在这里插入图片描述

因为wxPayClient变量其实就是我们注入到IOC容器中的CloseableHttpRequest对象,所以在它执行execute方法的过程中就会进行和微信的验签,加解密,证书相关的一系列操作,这个时候它就会调用我们的微信支付V3版本的SDK的API了,如下图:
在这里插入图片描述

代码托管地址

https://gitee.com/xuanyuanzy/payment-demo.git


http://chatgpt.dhexx.cn/article/OWy7mLiA.shtml

相关文章

你了解过区块链的最新模式都有哪些呢?

热门项目 ①USDT跑分系统: 项目热度:***** 项目亮点: 1.使用全球主流稳定的结果货币USDT。 2.通道永不被封,资金永不被冻。 3.个人与个人之间的C2C点对点分散式交易。 4.高效,5分钟内迅速到账。 项目玩法: 500个usdt以上即可开启接单(相当于押金),静态跑一轮可得…

vpay平台模式开发 15天交付系统

近期迅速走进大家视野的Vpay是什么究竟是什么,有人说vpay是一个APP,有人说,是一个支付手段,接近一点的会说是一个模式,那究竟是什么模式?拆分?还是虚拟币?其实严谨来讲Vpay是 重新构建了连接方式,连接方…

vpay软件系统开发

“创新性强、前瞻性高,需要先行先试,但切忌‘一刀切’(陈琦:138-2848-7919可微)当天,互联网医疗企业丁香园创始人、董事长李天天在接受央视《新闻11》采访时表达了这样的观点,近两年的互联网圈子…

vpay模式软件开发 vpay系统

vpan它一方面通过数学和算法实现了全网的共识与信任(协议属性),另一方面通过代币保证了生态体系的价值激励(货币属性)。 区块链适合应用的领域是已经现存大量结构化数据,或者是容易形成结构化数据的领域。这点比较类似ai,只有数据线上化结构化…

V免签-PC监控端 Vpay监控 PC 4.3

V免签-PC监控端 介绍 V免签pc监控端更新界面 支持微信、支付宝双端监听 使用说明 下载软件配置域名、密钥 版本更新 持续更新中~~~ 下载地址:https://wwsl.lanzoul.com/iSSo30vzqm1g https://www.159e.cn/75.html Vpay监控 4.3 更新日志: 1.修复…

Vpay是什么?Vpay怎么玩?用Vpay有什么好处?Vpay系统开发

(1)Vpay是什么? Vpay是一个全面开放的完全去中心化的网络支付平台,跟支付宝和微信一样,不同的是,Vpay是基于区块链技术开发的,用户之间能顺利实现点对点交易,支付,跨境转…

web前端第二周学习

第二周学习 二十一、嵌套列表二十二、表格标签二十三、表格属性二十四、表单标签二十五、表单相关标签二十六、表格表单组合使用二十七、div与span二十八、CSS语法格式二十九、内联样式与内部样式三十、外部样式及两种写法三十一、CSS颜色表示法三十二、背景样式三十三、背景实…

小程序与云开发实战 36 讲

课程介绍 小程序依托微信超过 10 亿的海量用户,它无需安装即可使用的完美用户体验,已经成为商家竞相争夺的大蛋糕,同时,小程序开发快速、容易部署广受程序员的喜爱,作为程序员的我们,还有什么理由不学习小…

WEB3.0白皮书

I // Part1 新浪潮 // 那么 Web3.0 究竟是什么? TA 能给当今世界带来什么变化? TA 由哪 些技术组成? 如何实现 Web3.0? TA 能带来哪些机会? 我们能从中得到什么? Web3.0 是一个非常前沿的话题,充满了不确定性,也没有任何人能准确预测…

如何在 2021 年使用 WordPress 制作游戏网站

您想学习如何使用 WordPress 制作游戏网站吗? 游戏从未如此流行。拥有自己的游戏网站,您可以创建一个游戏社区,创建一个受欢迎的游戏博客,甚至赚取副业收入。 在本文中,我们将向您展示如何在没有任何技术技能的情况下…

第一批 00 后 Web3 创业者,和他们的「人间清醒」

当不少 80 后、90 后还在困惑,生怕赶不上这趟所谓的 Web3「革命快车」的时候,有一些 00 后早已「玩得飞起」。一位 00 后朋友说,「你们眼中的革命,是我生活的日常。」 然而,这个新赛道有的不止是「狂热」,…

小甲鱼零基础入门学习python笔记

小甲鱼老师零基础入门学习Python全套资料百度云(包括小甲鱼零基础入门学习Python全套视频全套源码全套PPT课件全套课后题及Python常用工具包链接、电子书籍等)请往我的资源(https://download.csdn.net/download/qq_32809093/13099592)查看 目…

web前端学习1-45集

web前端1-45集 第一集 课程划分1.HTMLCSS系列教程1之拨云见日2.HTMLCSS系列教程2之溯本求源3.HTMLCSS系列教程3之风声水起4.HTMLCSS系列教程4之巧夺天工如何学好web前端 第二集 拨云见日1. 什么是HTML、CSS:2. 代码跟网站的关系:3.写到哪里:4…

应用服务器语言,web服务器 语言

C语言进行CGI程序设计 也就是CGI程序接受Web浏览器发送给Web服务器的信息,进行处理,将响应结果再回送给Web服务器及Web浏览器。CGI程序一般完成Web网页中表单(Form)数据的处理、数据库查询和实现与传统应用系统的集成等工作。CGI程序可以用... 文章 技术让梦想更伟大-李肖遥 20…

web前端从入门到精通

web前端从入门到精通 HTMLCSS系列一、拨云见日如何创建.html文件--网页1.安装插件2.编辑器基本使用3.Chrome浏览器 (市场份额最大)4.深入了解网站开发5.web三大核心技术6.HTML基础结构与属性7.HTML初始代码8.HTML注释9.HTML语义化10.标题(h)与段落(p )11…

html5游戏视频UI框架,推荐几个精致的web UI框架

Aliceui是支付宝的样式解决方案,是一套精选的基于 spm 生态圈的样式模块集合,是 Arale 的子集,也是一套模块化的样式命名和组织规范,是写 CSS 的更好方式。 2.Amazeui Amaze UI 是一个轻量级、 Mobile first 的前端框架, 基于开源…

【蓝桥杯Web】2022年第十三届蓝桥杯Web大学组省赛真题解析(完整版)

🧑‍💼 个人简介:一个不甘平庸的平凡人🍬 🖥️ Nodejs专栏:Node.js从入门到精通 🖥️ TS知识总结:十万字TS知识点总结 👉 你的一键三连是我更新的最大动力❤️&#xff0…

万字详述 Web3 彻底颠覆品牌行业的底层叙事

序言 尽管 Web3 品牌是一个被普遍看好的方向,但目前缺乏一个从底层逻辑上完全不同于 Web2 的叙事逻辑,Web3 品牌在当前现状更多以营销策略的方式进行尝试,但是由于缺乏一个根本性的叙事,无法支撑品牌方真正的认可并将其上升到战略…

Web3 时代 传统品牌如何玩转 NFT 营销?

给你「老板看得懂,客户能买单」的 NFT 营销方案。 最近看了很多讲 Web3 怎么助力品牌营销的长文,收获颇丰。但分享给还在一线做品牌的小伙伴,收到的反馈却是:还是看不懂,你就直接告诉我咋搞,怎么搞&#x…

小程序 腾讯兔小巢 对接

小程序接第三方兔小巢 很久没有写生活记录了,今天写一篇关于小程序对接第三方兔小巢插件提示:记录美好时刻,把生活写成诗;有你的生活中,那必定是阳光明媚; 文章目录 小程序接第三方兔小巢前言一、什么是兔…