02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)

目录

  • SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功
  • 基础支付API V3
    • 1、引入支付参数
      • 参数解释
        • 1-1、商户号:
        • 1-2、商户API证书序列号:
        • 1-3、商户私钥文件
        • 1-4、APIv3密钥
        • 1-5、APPID
        • 1-6、微信服务器地址
        • 1-7、接收结果通知地址
    • 2、读取支付参数
      • 2-1、测试支付参数的获取
    • 3、配置 Annotation Processor
      • 3-1、原因:
      • 3-2、方法:
    • 4、加载商户私钥
      • 4-1、复制商户私钥
      • 4-2、引入SDK
      • 4-3、获取商户私钥
      • 4-4、测试商户私钥的获取
    • 5、获取签名验证器和HttpClient
      • 5-1、APIv3证书与密钥使用说明
      • 5-2、获取签名验证器
      • 5-3、获取HttpClient对象
      • 5-4、WxPayConfig 代码(签名和验签)
    • 6、API字典和相关工具
      • 6-1、API 列表
      • 6-2、接口规则
      • 6-3、定义枚举
      • 6-4、添加工具类
    • 7、调用Native下单API
      • 7-1、需求:
      • 7-2、native 支付流程图:
      • 7-3、Native下单
        • 7-3-1、需求流程分析:
        • 7-3-2、代码:
          • 7-3-2-1、接口相关数据
          • 7-3-2-2、controller
          • 7-3-2-3、Service
          • 7-3-2-4、Impl
          • 7-3-2-5、测试结果:
          • 7-3-2-6、成功真实支付
        • 7-3-4、后端完整代码
          • WxPayController
          • WxPayService
          • WxPayServiceImpl
    • 8、前端代码分析
      • 8-1、获取商品列表数据分析
      • 8-2、选择课程的点击事件分析
      • 8-3、支付类型和确认支付分析
      • 8-4、前端支付二维码的展示分析

SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功

需求:
如图,实现流程:选择一个课程,点击支付,然后弹出一个支付二维码,用户扫描二维码进行支付。
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第1张图片

签名和验签的理解:
A发送一个请求给B,
A需要将请求的一些参数进行签名加密,
B接收到请求后,需要对签名进行验签,作用就是判断发过来的请求是否被篡改过。如果没篡改过,则可以正常使用该方法的参数。

签名生成流程

签名验证流程

基础支付API V3

1、引入支付参数

这些支付参数是视频制作者提供的
这是个配置文件

如图:这个 wxpay.private-key-path=apiclient_key.pem 是商户私钥文件路径,可以通过这个路径获取私钥文件
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第2张图片

参数解释

1-1、商户号:

就是商家的账号
属于学习视频的截图:
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第3张图片

1-2、商户API证书序列号:

在商户平台申请的API证书,有私钥和证书,证书里面封装了公钥
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第4张图片

1-3、商户私钥文件

商户的私钥文件加载到应用程序当中的目的主要是为了做签名,用私钥将请求进行签名,然后发请求的信息发送给微信的服务器端,微信的服务器端就会根据发来的请求中的 商户API证书的序列号 这个参数找到对应的证书,然后再从这个证书中解密出我们的公钥,然后用这个公钥对这个发来的加密的请求进行验签。

(公钥就存放在加密了的证书中)

这就是一个请求发送和接收的过程,对应的是一个签名和验签的过程。

签名:就是将请求加密
验签:就是用来判断这个请求有没有被篡改过,验签通过就是没被篡改过

现在这个是商户私钥的路径,通过这个路径获取商户私钥文件

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第5张图片

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第6张图片

1-4、APIv3密钥

这个密钥是一个对称加密的密钥

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第7张图片

1-5、APPID

在申请商户号的时候,同时申请的微信公众号,这个就是微信公众号的id

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第8张图片

1-6、微信服务器地址

远程向这个地址发起调用

向微信发起请求

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第9张图片

1-7、接收结果通知地址

微信向商户端发起请求

每个人的地址都是不一样的,记得修改

内网穿透用的
在这里插入图片描述

2、读取支付参数

创建一个配置文件来读取支付参数配置文件里面的数据

这个方法可以读取到配置文件的值。

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第10张图片

也可以通过这种方式来获取配置文件中的属性值,这个是其他的代码,仅作记录

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第11张图片

2-1、测试支付参数的获取

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第12张图片

能成功拿到配置文件的里面的属性值

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第13张图片

3、配置 Annotation Processor

可以帮助我们生成自定义配置的元数据信息,让配置文件和Java代码之间的对应参数可以自动定位,方

便开发。

3-1、原因:

如图,在idea 中,没有把这个wxpay 看成是一个spring的配置文件,虽然不影响程序运行,但是却少了很多功能,比如自动定位,就是点击配置文件的属性名,能自动定位到 WxPayConfig 配置文件的对应字段去。

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第14张图片

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第15张图片

3-2、方法:

实现配置文件能够自动定位的操作

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第16张图片

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第17张图片

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第18张图片

4、加载商户私钥

4-1、复制商户私钥

把商户私钥复制到项目根目录下:

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第19张图片

4-2、引入SDK

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

https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient

我们可以使用官方提供的 SDK,帮助我们完成开发。实现了请求签名的生成和应答签名的验证
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第20张图片

微信支付的SDK 依赖


    com.github.wechatpay-apiv3
    wechatpay-apache-httpclient
    0.3.0

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第21张图片

4-3、获取商户私钥

因为我们的私钥是存在一个文件的(apiclient_key.pem),所以用第一个示例方法

https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第22张图片
在 WxPayConfig 中写一个获取商户私钥文件的方法
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第23张图片

4-4、测试商户私钥的获取

在 PaymentDemoApplicationTests 测试类中添加如下方法,测试私钥对象是否能够获取出来。

(将前面的方法改成public的再进行测试)

在测试类里面测试

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第24张图片

5、获取签名验证器和HttpClient

5-1、APIv3证书与密钥使用说明

https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay3_0.shtml

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第25张图片

5-2、获取签名验证器

https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient (定时更新平台证书功能)

平台证书:平台证书封装了微信的公钥,商户可以使用平台证书中的公钥进行验签。

签名验证器:帮助我们进行验签工作,我们单独将它定义出来,方便后面的开发。

下图是学习视频的访问该网址的代码,但是现在打开该网址的代码已经改变了。

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第26张图片

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第27张图片

5-3、获取HttpClient对象

https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient (定时更新平台证书功能)

HttpClient 对象:是建立远程连接的基础,我们通过SDK创建这个对象

**HttpClient对象作用: **通过 WechatPayHttpClientBuilder 构造的 HttpClient,会自动的处理签名和验签,并进行证书自动更新。

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第28张图片

5-4、WxPayConfig 代码(签名和验签)

package cn.ljh.paymentdemo.config;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.ScheduledUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.Data;
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.nio.charset.StandardCharsets;
import java.security.PrivateKey;


@Configuration
@PropertySource("classpath:wxpay.properties") //读取配置文件
@ConfigurationProperties(prefix = "wxpay") //读取wxpay节点
@Data //使用set方法将wxpay节点中的值填充到当前类的属性中
public class WxPayConfig
{

    // 商户号
    private String mchId;

    // 商户API证书序列号
    private String mchSerialNo;

    // 商户私钥文件的路径
    private String privateKeyPath;

    // APIv3密钥
    private String apiV3Key;

    // APPID
    private String appid;

    // 微信服务器地址
    private String domain;

    // 接收结果通知地址
    private String notifyDomain;


    /**
     * 获取商户的私钥文件
     *
     * @param fileName 私钥文件的路径
     * @return PrivateKey
     */
    public PrivateKey getPrivateKey(String fileName)
    {
        try
        {
            return PemUtil.loadPrivateKey(
                    new FileInputStream(fileName));
        } catch (FileNotFoundException e)
        {
            throw new RuntimeException("私钥文件不存在", e);
        }
    }

    /**
     * 获取签名验证器
     *
     * @return 签名验证器
     */
    @Bean
    public ScheduledUpdateCertificatesVerifier getVerifer()
    {

        //获取商户私钥
        PrivateKey privateKey = getPrivateKey(privateKeyPath);

        //私钥签名对象
        PrivateKeySigner privateKeySigner = new PrivateKeySigner(mchSerialNo, privateKey);

        //身份认证对象
        WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);

        // 使用定时更新的签名验证器,不需要传入证书
        ScheduledUpdateCertificatesVerifier verifier = new ScheduledUpdateCertificatesVerifier(
                wechatPay2Credentials,
                apiV3Key.getBytes(StandardCharsets.UTF_8));

        return verifier;

    }

    /**
     * 获取HttpClient 请求对象:是建立远程连接的基础,我们通过SDK创建这个对象
     * 通过 WechatPayHttpClientBuilder 构造的 HttpClient,会自动的处理签名和验签,并进行证书自动更新
     *
     * @param verifier 签名验证器
     * @return HttpClient 请求对象,会自动的处理签名和验签,并进行证书自动更新
     */
    @Bean
    public CloseableHttpClient getWxPayClient(ScheduledUpdateCertificatesVerifier verifier)
    {

        //获取商户私钥
        PrivateKey privateKey = getPrivateKey(privateKeyPath);
        //用于构造HttpClient
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, mchSerialNo, privateKey)
                .withValidator(new WechatPay2Validator(verifier));

        // ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient

        // 通过 WechatPayHttpClientBuilder 构造的 HttpClient,会自动的处理签名和验签,并进行证书自动更新
        CloseableHttpClient httpClient = builder.build();

        return httpClient;
    }


}

6、API字典和相关工具

6-1、API 列表

https://pay.weixin.qq.com/docs/merchant/development/interface-rules/introduction.html

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第29张图片

我们的项目中要实现以下所有API的功能。
https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_7_3.shtml

Native支付API列表

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第30张图片

6-2、接口规则

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

微信支付 APIv3 使用 JSON 作为消息体的数据交换格式。

如上图,因为使用JSON作为数据交互的格式,不再使用XML , 所以在项目里面添加这个json处理的依赖

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第31张图片

6-3、定义枚举

为了开发方便,我们预先在项目中定义一些枚举。枚举中定义的内容包括接口地址,支付状态等信息。

就是我们去调用支付的一些 商户订单号查询订单、关闭订单、退款申请 的接口,这些都是微信支付平台提供的接口,因为会经常调用,所以把这些接口地址、状态等直接封装成枚举,方便调用。

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第32张图片

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第33张图片

6-4、添加工具类

将资料文件夹中的 util 目录复制到源码目录中,我们将会使用这些辅助工具简化项目的开发

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第34张图片

7、调用Native下单API

7-1、需求:

如图,选择一个课程,点击支付,然后弹出一个支付二维码,用户扫描二维码进行支付。
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第35张图片

7-2、native 支付流程图:

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第36张图片

完整流程
https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_4.shtml

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第37张图片

7-3、Native下单

7-3-1、需求流程分析:

生成订单–>调用统一下单的API,生成支付二维码–>生成预支付交易–>返回预支付交易链接
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第38张图片

下单的接口说明
https://pay.weixin.qq.com/docs/merchant/apis/native-payment/direct-jsons/native-prepay.html

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第39张图片

7-3-2、代码:
7-3-2-1、接口相关数据

由官方指定的一些要求和示例

【服务端】Native下单 的官方示例代码

https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_7_2.shtml

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第40张图片

native下单的接口说明

https://pay.weixin.qq.com/docs/merchant/apis/native-payment/direct-jsons/native-prepay.html

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第41张图片

要封装哪些请求参数,在这里看
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第42张图片

7-3-2-2、controller

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第43张图片

7-3-2-3、Service

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第44张图片

7-3-2-4、Impl

创建订单,调用native支付接口

这个是封装支付接口要的url:
在这里插入图片描述

这里才是执行调用该支付接口的方法:签名、验签和调用支付接口
在这里插入图片描述

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第45张图片
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第46张图片
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第47张图片
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第48张图片

7-3-2-5、测试结果:

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第49张图片

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第50张图片

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第51张图片

7-3-2-6、成功真实支付

在这里插入图片描述

7-3-4、后端完整代码

一些配置文件、枚举类就没列出来了,太多了

WxPayController
package cn.ljh.paymentdemo.controller;

import cn.ljh.paymentdemo.service.WxPayService;
import cn.ljh.paymentdemo.vo.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Map;

@CrossOrigin //跨域
@RestController
@RequestMapping("/api/wx-pay")
@Api(tags = "网站微信支付API") //swagger 注解
@Slf4j
public class WxPayController
{
    @Resource
    private WxPayService wxPayService;
    
    //调用统一下单API,生成支付二维码的链接和订单号
    //swagger注解
    @ApiOperation("调用统一下单API,生成支付二维码")
    @PostMapping("/native/{productId}")
    public R nativePay(@PathVariable Long productId) throws Exception
    {
        log.info("发起支付请求");
        //返回支付二维码的链接和订单号
        Map<String,Object> map = wxPayService.nativePay(productId);
        return R.ok().setData(map);
    }

}
WxPayService
package cn.ljh.paymentdemo.service;

import java.util.Map;

public interface WxPayService
{
    //调用统一下单API,生成支付二维码的链接和订单号
    Map<String, Object> nativePay(Long productId) throws  Exception;

}
WxPayServiceImpl
package cn.ljh.paymentdemo.service.impl;

import cn.ljh.paymentdemo.config.WxPayConfig;
import cn.ljh.paymentdemo.entity.OrderInfo;
import cn.ljh.paymentdemo.enums.OrderStatus;
import cn.ljh.paymentdemo.enums.wxpay.WxApiType;
import cn.ljh.paymentdemo.enums.wxpay.WxNotifyType;
import cn.ljh.paymentdemo.service.WxPayService;
import cn.ljh.paymentdemo.util.OrderNoUtils;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


//创建订单,调用 Native 支付接口
@Service
@Slf4j
public class WxPayServiceImpl implements WxPayService
{
    @Resource
    private WxPayConfig wxPayConfig;

    /* 原本应该注 入WxPayConfig 这个类,然后调用 getWxPayClient() 方法获取 HttpClient请求对象
     * 但是因为 getWxPayClient() 方法加了@Bean注解,交给了spring容器管理,所以项目启动的时候就会执行这个方法,
     * 就会存在返回值为 CloseableHttpClient 类型的 HttpClient请求对象
     * 所以这里可以直接注入这个 CloseableHttpClient 对象
     */
    @Resource
    private CloseableHttpClient wxPayClient;

    /**
     * 创建订单,调用 Native 支付接口
     *
     * @param productId 商品id
     * @return code_url 和 订单号
     * @throws Exception
     */
    //调用统一下单API,生成支付二维码的链接和订单号
    @Override
    public Map<String, Object> nativePay(Long productId) throws Exception
    {
        log.info("生成订单.....");

        //生成订单
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setTitle("test"); //订单标题
        orderInfo.setOrderNo(OrderNoUtils.getOrderNo()); //生成订单号
        orderInfo.setProductId(productId); //商品id
        orderInfo.setTotalFee(1); //单位是:分
        orderInfo.setOrderStatus(OrderStatus.NOTPAY.getType()); //支付状态
        //TODO: 需要将这个订单存到数据库

        /*
         * 官方提供的 Native下单 接口
         * 支持商户:【普通商户】
         * 请求方式:【POST】/v3/pay/transactions/native
         * 请求域名:【主域名】https://api.mch.weixin.qq.com
         * "https://api.mch.weixin.qq.com/v3/pay/transactions/native" 改成
         * wxPayConfig.getDomain().concat(WxApiType.NATIVE_PAY.getType())
         */

        log.info("调用统一下单API.....");

        //调用统一下单API---拷贝官网的实例代码进行修改---统一下单的接口地址
        HttpPost httpPost = new HttpPost(wxPayConfig.getDomain().concat(WxApiType.NATIVE_PAY.getType()));

        // 请求body参数---------调用接口需要的参数
        Gson gson = new Gson();
        //数据类型不固定,所以就不写泛型了
        Map paramsMap = new HashMap();
        //设置参数 --- 根据官网要求设置对应的参数
        paramsMap.put("appid", wxPayConfig.getAppid()); //公众号ID
        paramsMap.put("mchid", wxPayConfig.getMchId()); //直连商户号
        paramsMap.put("description", orderInfo.getTitle()); // 商品描述
        paramsMap.put("out_trade_no", orderInfo.getOrderNo()); //商户订单号
        paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(WxNotifyType.NATIVE_NOTIFY.getType())); //通知地址
        //订单金额有两个参数--嵌套数据
        Map amountMap = new HashMap();
        amountMap.put("total", orderInfo.getTotalFee()); //总金额
        amountMap.put("currency", "CNY"); //货币类型
        paramsMap.put("amount", amountMap); // 订单金额

        //将参数转成字符串
        String jsonParams = gson.toJson(paramsMap);

        log.info("支付的请求参数:" + jsonParams);

        //把参数设置到请求体当中
        StringEntity entity = new StringEntity(jsonParams, "utf-8");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);
        //希望得到的响应类型
        httpPost.setHeader("Accept", "application/json");

        //完成签名并执行请求
        CloseableHttpResponse response = wxPayClient.execute(httpPost);

        //这些就是对调用下单方法的响应结果的处理了
        try
        {
            //字符串形式的响应体
            String bodyAsString = EntityUtils.toString(response.getEntity());
            //响应状态码
            int statusCode = response.getStatusLine().getStatusCode();

            if (statusCode == 200)
            { //处理成功
                System.out.println("成功, 返回结果  = " + bodyAsString);
            } else if (statusCode == 204)
            { //处理成功,无返回Body
                System.out.println("成功");
            } else
            {
                System.out.println("下单失败, 响应码 = " + statusCode + ", 返回结果 = " + bodyAsString);
                throw new IOException("请求失败 request failed");
            }
            //如果下单成功,获取响应结果,   gson.fromJson()用于将 JSON 字符串转换为 Java 对象
            Map<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);
            //从返回的结果中获取二维码的url, 从官网看出 code_url 是 二维码的key
            String codeUrl = resultMap.get("code_url");
            //创建一个url和订单号的返回值
            Map<String, Object> map = new HashMap<>();
            map.put("codeUrl", codeUrl);
            map.put("orderNo", orderInfo.getOrderNo());
            return map;
        } finally
        {
            response.close();
        }
    }
}

8、前端代码分析

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第52张图片

8-1、获取商品列表数据分析

1、前端调用后端接口流程

后端返回的数据,主要的商品列表数据存在属性名为 productList 中,

前端的 created(){} 是页面加载的时候自动执行,

productApi 这个类里面有一个 list() 方法,

list()方法有url,一看就是在执行远程调用,就是在调用后端的 url: ‘/api/product/list’ 接口

then 就是回调函数,在then 方法中取出后端的响应数据,response 就是后端响应到前端的数据

response.data.productList 就是获取后端返回来的属性名为 productList 的值

data 就是response响应中的结果数据,因为response 还有其他一些数据。
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第53张图片

2、一些值赋予过程

this.productList 就是把获取到的值设置到 data 里面的 productList: []
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第54张图片

遍历的值就是从data里面获取的

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第55张图片

3、模块调用分析

基于上面继续分析:

import 引入模块分析,如图,也可以理解为在 index.vue 中调用 productApi 这个模块

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第56张图片

然后product.js 调用 request.js ,

request.js 引入 axios

如图:在 product.js 中,url 是调用后端的接口的具体路径,但是明显还少了主机地址,

就是http://localhost:端口号这些主机地址。

所以需要引入 request 模块,在这个request 模块中就初始化了所有远程ajax调用需要的请求的主机地址

然后为什么能实现ajax远程调用呢?

是因为在request模块中,又引入了 axios 模块,这个模块就是在vue中专门做发送ajax 请求的模块。

axios 模块是从哪里来的呢?

axios 是在 package.json 里面引入的,相当于 java 在 pom.xml 文件中引入所需依赖一样。

因为在 package.json 引入了 “axios”: “^0.24.0” 这个专门发送ajax的工具,所以前端才能实现ajax 调用,

所以可以在 request.js 中创建 axios 实例。

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第57张图片

如果远程调用数据失败,那么处理的方式就是这个拦截器。
02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第58张图片

8-2、选择课程的点击事件分析

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第59张图片

8-3、支付类型和确认支付分析

都是点击触发点击事件

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第60张图片

远程调用都是一样的,跟获取商品列表数据一样

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第61张图片

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第62张图片

8-4、前端支付二维码的展示分析

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第63张图片

02、SpringBoot + 微信支付 -->基础支付API V3 -->网页弹出二维码支付功能 并能 真实支付成功(Native下单API)_第64张图片

你可能感兴趣的:(#,SpringBoot,集成,微信支付,SpringBoot,Vue,Native,下单,API)