从零玩转系列之微信支付实战基础框架搭建2

简介: 从零玩转系列之微信支付实战基础框架搭建

4.idea链接mysql

447e3ed4849a30aab83ecc96b7c9040.png

⚠️ 推荐一个插件一键生成CRUD

💰 MyBatisCodeHelperPro (Marketplace Edition)

a99280e952f239a36b2f409ac60f250.png

🔗 打开链接好的数据库管理选择到对应的表右击

d126d074f4d01b3fa22be72b43c42e1.png

2c7ba45efccca285cd4364903532634.png

🦐 下面的选项卡里面的配置

  1. lombok 勾选 @Data
  2. 定制默认方法可以全部去掉
  3. mybatisPlus配置勾选 mybatisPlus3 和 idType选择为 ASSIGN_ID
  4. 其他的你看着来吧…

✅ 直接确定生成了一个CRUD 接下来将后面的三个表也一样的操作吧

91be24c4b15ee268209da4d264b7148.png

👌 最终如此

013f5b871e2fdfc64343e3771038cdc.png

5. 微信配置-基础支付API V3

1.引入支付参数配置

  • 在resources当中创建wechat文件夹
  • 创建 wxpay.properties 复制到wechat当中
# 商户ID
wxpay.mch-id=xxxxx
# 商户平台号
wxpay.mch-serial-no=xxxxx
# 商户证书
wxpay.private-key-path=wechat/apiclient_key.pem
# 微信平台证书
wxpay.platformCertPath=wechat/wechatpay_2694B2E0B2719A25EE1063EE02CFC78EE035E8CF.pem
# 下载地址参考: https://github.com/wechatpay-apiv3/CertificateDownloader
# 商户api v3
wxpay.api-v3-key=xxxxx
# 小程序appid
wxpay.appid=xxxxx
# 小程序密钥
wxpay.secret=xxxxx
wxpay.domain=https://api.mch.weixin.qq.com
# 本地使用内网穿透代理回调
wxpay.notify-domain=https://x x x x x x x x x x x x/wx-api
# 商户apiv2
wxpay.partner-key=xxxxxxxxxxxxx

下载微信平台证书

java -jar CertificateDownloader.jar -k ${apiV3key} -m ${mchId} -f ${mchPrivateKeyFilePath} -s ${mchSerialNo} -o ${outputFilePath}
示例:
java -jar CertificateDownloader-1.2.0-jar-with-dependencies.jar 
-k=商户v3key 
-m=商户ID 
-f=/Users/yangbuyi/Documents/workPath/workPath/wx-play-demo/src/main/resources/apiclient_key.pem 
-s=商户证书序列号 
-o=/Users/yangbuyi/Documents/workPath/workPath/wx-play-demo/src/main/resources
解释:
java -jar CertificateDownloader-1.2.0-jar-with-dependencies.jar 
-k=这是对应配置文件当中的 APIV3Key(wxpay.api-v3-key)商户APIV3Key
-m=这是对应配置文件当中的 mchID (wxpay.mch-id) 商户ID 
-f=这是对应配置文件当中到 商户证书 apiclient_key.pem  (绝对路径地址)
-s=这是对应配置文件当中的 mchSerialNo(wxpay.mch-serial-no)商户平台证书序列号
-o=这是将生成的文件输出到哪个目录下面 (绝对路径地址)

这个文件定义了之前我们准备的微信支付相关的参数,例如商户号、APPID、API秘钥等等

完整

30866addda205a8c4c4ba30286eef8b.png

创建 WxPayConfig 类

存放在config目录

package com.yby6.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 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.FileNotFoundException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
@Configuration
@PropertySource("classpath:wechat/wxpay.properties") //读取配置文件
@ConfigurationProperties(prefix = "wxpay") //读取wxpay节点
@Data //使用set方法将wxpay节点中的值填充到当前类的属性中
@Slf4j
public class WxPayConfig {
    // 商户号
    private String mchId;
    // 商户API证书序列号
    private String mchSerialNo;
    // 商户私钥文件
    private String privateKeyPath;
    // 微信平台证书
    private String platformCertPath;
    // APIv3密钥
    private String apiV3Key;
    // APPID
    private String appid;
    // app secret
    private String secret;
    // 微信服务器地址
    private String domain;
    // 接收结果通知地址
    private String notifyDomain;
    // APIv2密钥
    private String partnerKey;
    /**
     * 获取商户的私钥文件
     */
    public PrivateKey getPrivateKey(String filename) {
        try {
            InputStream inputStream = getClass().getClassLoader().getResourceAsStream(filename);
            if (inputStream == null) {
                throw new FileNotFoundException("私钥文件不存在");
            }
            return PemUtil.loadPrivateKey(inputStream);
        } catch (Exception e) {
            throw new RuntimeException("私钥文件不存在", e);
        }
    }
    /**
     * 获取签名验证器
     */
    @Bean
    public ScheduledUpdateCertificatesVerifier getVerifier() {
        log.info("构建签名验证器");
        log.info("mchId: {}", mchId);
        log.info("mchSerialNo: {}", mchSerialNo);
        log.info("privateKeyPath: {}", privateKeyPath);
        log.info("apiV3Key: {} , {}", apiV3Key , apiV3Key.length());
        log.info("appid: {}", appid);
        log.info("domain: {}", domain);
        log.info("notifyDomain: {}", notifyDomain);
        log.info("partnerKey: {} , {}", partnerKey , partnerKey.length());
        //获取商户私钥
        PrivateKey privateKey = getPrivateKey(privateKeyPath);
        //私钥签名对象
        PrivateKeySigner privateKeySigner = new PrivateKeySigner(mchSerialNo, privateKey);
        //身份认证对象
        WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);
        // 使用定时更新的签名验证器,不需要传入证书 -> 它会帮助我们下载最新的证书不会进行过期
        return new ScheduledUpdateCertificatesVerifier(wechatPay2Credentials, apiV3Key.getBytes(StandardCharsets.UTF_8));
    }
    /**
     * 获取http请求对象
     */
    @Bean(name = "wxPayClient")
    public CloseableHttpClient getWxPayClient(ScheduledUpdateCertificatesVerifier verifier) {
        log.info("获取httpClient");
        //获取商户私钥
        PrivateKey privateKey = getPrivateKey(privateKeyPath);
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                // 设置商户信息
                .withMerchant(mchId, mchSerialNo, privateKey)
                // 设置验签器
                .withValidator(new WechatPay2Validator(verifier));
        // ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient
        // 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
        return builder.build();
    }
    /**
     * 获取HttpClient,无需进行应答签名验证,跳过验签的流程
     */
    @Bean(name = "wxPayNoSignClient")
    public CloseableHttpClient getWxPayNoSignClient() {
        //获取商户私钥
        PrivateKey privateKey = getPrivateKey(privateKeyPath);
        //用于构造HttpClient
        WechatPayHttpClientBuilder 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;
    }
}

最终如此

2e2694ae4f72cd5982be0182741c69e.png

四、测试项目

🥬 创建Controller

package com.yby6.controller;
import cn.hutool.json.JSONUtil;
import com.yby6.config.WxPayConfig;
import com.yby6.service.WxPayService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author Yang Shuai
 * Create By 2023/6/8
 */
@RestController
@RequestMapping
@RequiredArgsConstructor
public class WechatController {
    private final WxPayConfig wxPayConfig;
    @GetMapping("/index")
    public String index() {
        return "ok";
    }
    @PostMapping("getMchId")
    public Object getMchId() {
        return wxPayConfig.getMchId();
    }
}

查看配置的微信正式是否ok

编写测试类 如下图

b8602a2a7b93455555358ed2cfb1cea.png

package com.yby6;
import cn.hutool.core.util.ArrayUtil;
import com.yby6.config.WxPayConfig;
import jakarta.annotation.Resource;
import org.apache.http.impl.client.CloseableHttpClient;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.security.PrivateKey;
import java.time.Duration;
import java.time.Instant;
@SpringBootTest
class WxPlayDemoApplicationTests {
    @Resource
    private WxPayConfig wxPayConfig;
    @Resource
    private CloseableHttpClient wxPayClient;
    @Resource
    private CloseableHttpClient wxPayNoSignClient;
    /**
     * 获取商户的私钥
     */
    @Test
    void testGetPrivateKey() {
        //获取私钥路径
        String privateKeyPath = wxPayConfig.getPrivateKeyPath();
        //获取私钥
        PrivateKey privateKey = wxPayConfig.getPrivateKey(privateKeyPath);
        System.out.println(privateKey);
        System.out.println(wxPayClient);
        System.out.println(wxPayNoSignClient);
    }
}

🔥 启动项目

c0c07b4196e3b88f3e2bccdd11c25f8.png

🐑 IDEA插件对标PostMan

Restful Fast Request

73e64055721073598cf2ce141e2a337.png

🚗 测试

4ef266401f8787f644d6e54260da47c.png

👋 下一章项目实战之微信支付接口搭建…

相关文章
|
7天前
|
人工智能 开发框架 机器人
AstrBot:轻松将大模型接入QQ、微信等消息平台,打造多功能AI聊天机器人的开发框架,附详细教程
AstrBot 是一个开源的多平台聊天机器人及开发框架,支持多种大语言模型和消息平台,具备多轮对话、语音转文字等功能。
2029 13
AstrBot:轻松将大模型接入QQ、微信等消息平台,打造多功能AI聊天机器人的开发框架,附详细教程
|
6月前
|
移动开发 小程序 JavaScript
开源的微信小程序框架
【8月更文挑战第22天】开源的微信小程序框架
299 65
|
4月前
|
JavaScript 小程序 开发者
uni-app开发实战:利用Vue混入(mixin)实现微信小程序全局分享功能,一键发送给朋友、分享到朋友圈、复制链接
uni-app开发实战:利用Vue混入(mixin)实现微信小程序全局分享功能,一键发送给朋友、分享到朋友圈、复制链接
746 0
|
6月前
|
人工智能 搜索推荐 安全
从零到一:微信机器人开发的实战心得
从零到一:微信机器人开发的实战心得
398 2
|
7月前
|
移动开发 开发框架 前端开发
微信门户开发框架-使用指导说明书(2)--基于框架的开发过程
微信门户开发框架-使用指导说明书(2)--基于框架的开发过程
|
7月前
|
存储 开发框架 小程序
微信门户开发框架-使用指导说明书
微信门户开发框架-使用指导说明书
|
7月前
|
开发框架 前端开发 JavaScript
在微信框架模块中,基于Vue&Element前端的事件和内容的管理
在微信框架模块中,基于Vue&Element前端的事件和内容的管理
|
7月前
|
开发框架 移动开发 前端开发
在微信框架模块中,基于Vue&Element前端的后台管理功能介绍
在微信框架模块中,基于Vue&Element前端的后台管理功能介绍
|
7月前
|
小程序 安全 搜索推荐
【微信小程序开发实战项目】——个人中心页面的制作
本文介绍了如何设计和实现一个网上花店的微信小程序,包括个人中心、我的订单和我的地址等功能模块。个人中心让用户能够查看订单历史、管理地址和与客服互动。代码示例展示了`own.wxml`、`own.wxss`和`own.js`文件,用于构建个人中心界面,包括用户信息、订单链接、收藏、地址、客服和版本信息。我的订单部分展示了订单详情,包括商品图片、名称、销量、价格和订单状态,用户可以查看和管理订单。我的地址功能允许用户输入和编辑收货信息,包括联系人、性别、电话、城市和详细地址。每个功能模块都附有相应的WXML和WXSS代码,以及简洁的样式设计。
386 0
【微信小程序开发实战项目】——个人中心页面的制作
|
7月前
|
小程序 开发者
uniapp实战 —— 开发微信小程序的调试技巧
uniapp实战 —— 开发微信小程序的调试技巧
613 1

热门文章

最新文章