2024年Web前端最全微信小程序JSAPI支付 v3 版本 详解 附带源码_微信支付v3后端源码,2024前端大厂面试真题

最后

由于篇幅限制,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

v2与v3的区别

V2版接口和V3版接口实际上是基于两种接口标准设计的两套接口。 目前大部分接口已升级为V3接口,其余V2接口后续也将逐步升级为V3接口

在这里插入图片描述

总的来说,v3支付是对v2版本的升级,不过目前来看,v3的支付对接和实现对开发者更加友好,并且支付更加安全。

微信支付官方文档

请大家花点时间认真看下文档。指引文档,更新日志,sdk,api字典等,这些都很重要,避免在开发过程中,遇到很多不必要的麻烦。

v2的微信小程序支付我之前已经实现过一次了,可以看看 微信小程序支付详解

文章。

交互图

在这里插入图片描述

https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_4&index=3 请看交互图,其实交互是一样的,只是v3的支付接口不一致、大致的实现流程就这些,后台的大致流程为:

  1. 请求微信统一下单接口,获取预支付交易会话标识(prepay_id)
  2. 拿prepay_id 拼接参数,生成签名,给到前端拉起支付(JSAPI调起支付API)
  3. 支付成功后,处理支付回调方法

这里就是后端需要做处理的流程,中间会涉及到 数字证书,秘钥,签名等加密解密出来,以及自己业务处理。

代码实现

官方提供了工具和SDK。先获取官方的SDK,java版本的来做项目开发。

https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay6_0.shtml

wechatpay-apache-httpclient,适用于使用Apache HttpClient处理HTTP的Java开发者。
wechatpay-php(推荐)、wechatpay-guzzle-middleware,适用于PHP开发者。
wechatpay-go,适用于Go开发者

大家根据自己的语言去下载对应的SDK。并且好好看看sdk的使用方式。

maven依赖
   <dependency>
      <groupId>com.github.wechatpay-apiv3</groupId>
      <artifactId>wechatpay-apache-httpclient</artifactId>
      <version>0.2.2</version>
    </dependency>

配置类:
    @Bean
    public HttpClient wxHttpClient(
            @Value("${mchid}") String mchid,
            @Value("${mchSerialNo}") String mchSerialNo,
            PrivateKey merchantPrivateKey,
            AutoUpdateCertificatesVerifier autoUpdateCertificatesVerifier) {
        return WechatPayHttpClientBuilder.create()
                .withMerchant(mchid, mchSerialNo, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(autoUpdateCertificatesVerifier)).build();
    }

    /**
     * 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)
     */
    @Bean
    public AutoUpdateCertificatesVerifier autoUpdateCertificatesVerifier(
            PrivateKey merchantPrivateKey,
            @Value("${mchid}") String mchid,
            @Value("${mchSerialNo}") String mchSerialNo,
            @Value("${v3Key}") String v3Key) throws UnsupportedEncodingException {
        return new AutoUpdateCertificatesVerifier(
                new WechatPay2Credentials(mchid, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),
                v3Key.getBytes("utf-8"));
    }

    /**
     * 加载商户私钥(privateKey:私钥字符串)
     */
    @Bean
    public PrivateKey merchantPrivateKey(@Value("${privateKey}") String privateKey)
            throws UnsupportedEncodingException {
        return PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
    }

  static final int KEY_LENGTH_BYTE = 32;
  static final int TAG_LENGTH_BIT = 128;

  @Value("${v3Key}")
  private String weChatV3Key;

  public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext)
          throws GeneralSecurityException, IOException {
    try {
      Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

      SecretKeySpec key = new SecretKeySpec(weChatV3Key.getBytes(StandardCharsets.UTF_8), "AES");
      GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);

      cipher.init(Cipher.DECRYPT_MODE, key, spec);
      cipher.updateAAD(associatedData);

      return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8");
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
      throw new IllegalStateException(e);
    } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
      throw new IllegalArgumentException(e);
    }
  }

请求下单
  /**
     * 请求统一下单逻辑处理:
     */
    private WxPayOrderResult unifiedOrder(WxPayOrderRequest wxPayOrderRequest) throws IOException {
        HttpPost httpPost = new HttpPost(PAYUNIFIEDORDERURL);
        // 请求body参数
        StringEntity entity = new StringEntity(new Gson().toJson(wxPayOrderRequest), "UTF-8");
        entity.setContentType("application/json;charset=UTF-8");
        httpPost.setEntity(entity);
        httpPost.setHeader("Accept", "application/json;charset=UTF-8");
        HttpResponse response = httpClient.execute(httpPost);
        int code = response.getStatusLine().getStatusCode();
        String body = response.getEntity() == null ? null : EntityUtils.toString(response.getEntity());
        if (code != 200) {
            log.error("请求微信统一下单异常: code={}, body={}", code, body);


### 最后

本人分享一下这次字节跳动、美团、头条等大厂的面试真题涉及到的知识点,以及我个人的学习方法、学习路线等,当然也整理了一些学习文档资料出来是给大家的。知识点涉及比较全面,包括但不限于**前端基础,HTML,CSS,JavaScript,Vue,ES6,HTTP,浏览器,算法等等**

>**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

![](https://img-blog.csdnimg.cn/img_convert/f78bc1778941b561829478a7b1d9f169.webp?x-oss-process=image/format,png)

**前端视频资料:**
![](https://img-blog.csdnimg.cn/img_convert/566eebc62aab3fdebc52b49a6cb73dab.webp?x-oss-process=image/format,png)

等**

>**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

[外链图片转存中...(img-CpjFuqly-1714847321805)]

**前端视频资料:**
[外链图片转存中...(img-7j2iTbTh-1714847321806)]

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
JS JSP ASP .NET J2AM API接口和返回的版本 目前所有版本的JS JSP ASP .NET J2AM 都是提供源代码的,对于一些脚本语言来说,直接解压缩之后就可以使用了,不需要什么安装步骤。另外一些需要编译的语言,则提供了编译用的 shell 文件(Linux/Unix 下使用)和 bat 文件(Windows 下使用),或者直接提供编译好的二进制库文件。 不过为了让读者能够更清楚如何安装,我们还是对每种语言的安装都做详细的讲解,你可以在安装列表里找到你感兴趣的语言的安装方法。 示例 如果你已经把 JS JSP ASP .NET J2AM 安装好了,那么接下来就让我们开始第一个小程序吧。按照惯例,第一个演示程序几乎总是 HelloWorld,我们也不想打破这个惯例,不过对于 PHPRPC 来说,有服务器端就要有客户端,否则我们就没有什么好演示的啦,所以我们的第一个演示程序实际上是两个,一个是服务器端,另一个是客户端。我们都先用 PHP 语言来写好了。 服务器端 view plaincopy to clipboardprint? <?php include ("php/phprpc_server.php"); function HelloWorld() { return 'Hello World!'; } $server = new PHPRPC_Server(); $server->add('HelloWorld'); $server->start(); ?> 客户端 view plaincopy to clipboardprint? <?php include ("php/phprpc_client.php"); $client = new PHPRPC_Client('http://127.0.0.1/server.php'); echo $client->HelloWorld(); ?> 对于服务器端程序,我们应该将它命名为 server.php(这是因为客户端调用时用的是这个名字,而不是 PHPRPC 的什么规定),然后把它放在本地 Web 服务器的根目录下,并保证服务器可以正常运行 PHP 程序,之后在浏览器或命令行下运行客户端程序,你就可以看到结果了。 这两个程序几乎简单到无需解释的地步,所以如果你已经明白它们的意思,那么就可以直接跳过下面的解释,继续看后面的例子。 服务器端第 1 句是将 它的服务器端程序包含到你的程序里,之后的 2 - 4 句是定义一个远程调用的函数,你会发现它与本地函数没有任何区别。第 5 句是创建服务器端对象,第 6 句是添加要发布的方法,这里添加的就是刚刚定义的 HelloWorld 函数,在 PHP 中,添加的发布方法是函数名的字符串表示,在其它语言中可能略有不同。第 7 句是启动服务。 客户端就更简单了,第 1 句是将 它的客户端程序包含到你的程序里。第 2 句是创建客户端对象,其中的参数就是服务器端的地址。第 3 句是对远程方法(函数)的调用,之后通过 echo 将它显示出来。如果顺利的话,执行后你就会看到输出的 Hello World!。 上面的例子是发布的是函数,下面我们来看一下类中的静态方法如何发布: view plaincopy to clipboardprint? <?php include ("php/phprpc_server.php"); class Hello { static function HelloWorld() { return 'Hello World!'; } } $server = new PHPRPC_Server(); $server->add('HelloWorld', 'Hello'); $server->start(); ?> 这个服务器端只要它的名字与发布的地址与上面那个发布函数的例子一样的话,上面的那个客户端就可以得到同样的结果,也就是说,在客户端看来是没有任何区别的。 它并不是只可以在 PHP 中使用,它同样支持其它语言的服务器和客户端,而且还可以无差别的相互调用。 现在我们来看一下如何在 Java 中调用这个 PHP 的服务器方法: view plaincopy to clipboardprint? import org.phprpc.*; interface IHello { public String helloWorld(); } public class HelloWorld { public static void main ( String [] args ) { PHPRPC_Client client = new PHPRPC_Client("http://127.0.0.1/server.php"); IHello clientProxy = (IHello)client.useService(IHello.class); System.out.println(clientProxy.helloWorld()); } } 当我们把这个例子编译之后,在命令行中输入以下命令就可以看到执行结果了: java -classpath .;phprpc_client.jar HelloWorld 这个 Java 的客户端看上去比 PHP 的要稍微复杂一些,不过仍然很好理解。在 Java 客户端中,我们使用了接口来描述远程方法,之后我们通过 useService 方法返回一个远程代理对象,该对象实现了我们定义的接口,之后我们就可以直接调用远程方法 helloWorld 了。如果你比较细心的话,你还会发现我们在 PHP 中定义的方法和在 Java 中定义的接口的名字的大小写有点不同,但是仍然可以正常调用。是的,PHPRPC 发布的方法是不区分大小写的。所以不论你所使用的语言是否区分大小写,都可以按照自己(或语言)的习惯来定义方法名。 在本章的最后,我们再来看一下在 JavaScript 如何调用它的服务。顺便再强调一下,服务器端不止是可以用 PHP 来编写,你同样可以使用其它语言(比如 Java,.NET,Ruby,Python 等),这里我们只是以 PHP 为例而已。在这个例子中你还会看到如何使用加密传输。 view plaincopy to clipboardprint? <html> <head> <title>HelloWorld</title> [removed][removed] [removed] var client = new PHPRPC_Client('http://127.0.0.1/server.php', ['HelloWorld']); client.setEncryptMode(2); client.HelloWorld(function (result) { alert(result); }); [removed] </head> <body> </body> </html> 这个 JavaScript 是在网页中运行的,这里建议大家要把 head 和 body 标签都写全,即使它们对你来说看上去没有什么用处,但是在有些浏览器中,如果这些标签没有写全,或者写的不正确,程序就不能正确运行。 在这个例子中,我们会发现在创建 PHPRPC_Client 对象时,除了要写服务器地址以外,还要将远程方法的名字作为参数,因为远程方法可能不止一个,所以这个参数是数组类型的。 client.setEncryptMode(2); 这句是设置加密传输,参数 2 表示双向加密,就是参数和结果都加密(只不过这个 HelloWorld 比较特殊,它没有参数)。 接下来就是调用远程方法 HelloWorld 了,我们会发现它跟 PHP 和 Java 客户端的调用不太一样。是的,在 JavaScript 中远程调用都是采用异步方式的,也就是说要获得结果,需要用回调函数,回调函数作为远程方法的最后一个参数,回调函数也有四个参数,这里我们只使用第一个参数,也就是返回结果 result,通过 alert(result); 我们就可以在浏览器中看到最后弹出的 Hello World! 提示框了。 通过上面的例子,我们已经看到在 PHP、Java 和 JavaScript 这三种语言中使用 PHPRPC 都很简单,但因为语言的不同,在写法和用法上又有一些差别。不过你不用担心其它的语言跟它们也会有很大的差别,因为在接下来的章节中你很快就会发现其它语言跟这上面三种语言实现的写法和用法上的相似或相同之处了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值