从零玩转系列之微信支付实战基础框架搭建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

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

相关文章
|
2月前
|
机器人 数据安全/隐私保护 Python
企业微信自动回复软件,企业微信自动回复机器人,python框架分享
企业微信机器人包含完整的消息处理流程,支持文本消息自动回复、事件处理、消息加密解密等功能
|
2月前
|
JSON 机器人 API
微信机器人自动回复插件,vx自动回复机器人脚本助手,python框架分享
这个微信机器人系统包含三个主要模块:主程序基于itchat实现微信消息监听和自动回复功能
|
2月前
|
JSON 机器人 数据安全/隐私保护
微信自动聊天机器人, 微信自动回复机器人,python框架分享
这个微信机器人实现包含主程序、配置文件、工具函数和测试脚本四个模块。主程序使用itchat库
|
4月前
|
JSON 监控 小程序
微信百度字节小程序包过大解决方案(实战经验总结)-优雅草卓伊凡|果果|小无
微信百度字节小程序包过大解决方案(实战经验总结)-优雅草卓伊凡|果果|小无
245 14
微信百度字节小程序包过大解决方案(实战经验总结)-优雅草卓伊凡|果果|小无
|
3月前
|
人工智能 监控 数据可视化
微信养号脚本插件,全自动化工具,【autojs实现框架】
这是一套微信养号自动化脚本,包含主脚本`wechat_auto.js`和配置文件`config.json`。脚本实现自动浏览朋友圈、订阅号新闻文章及指定公众号历史文章三大功能,支持自定义滚动次数、阅读时长与运行时间等参数。特点包括随机化操作、多种浏览模式交替及完善的日志记录。配套UI模块提供可视化控制界面,方便监控任务状态与调整参数。下载地址:https://www.pan38.com/share.php?code=n6cPZ,提取码:8888(仅供学习参考)。
|
7月前
|
人工智能 开发框架 机器人
AstrBot:轻松将大模型接入QQ、微信等消息平台,打造多功能AI聊天机器人的开发框架,附详细教程
AstrBot 是一个开源的多平台聊天机器人及开发框架,支持多种大语言模型和消息平台,具备多轮对话、语音转文字等功能。
4293 15
AstrBot:轻松将大模型接入QQ、微信等消息平台,打造多功能AI聊天机器人的开发框架,附详细教程
|
7月前
|
小程序 测试技术 数据安全/隐私保护
微信公众号接口测试实战指南
微信公众号接口测试是确保系统稳定性和功能完整性的重要环节。本文详细介绍了测试全流程,包括准备、工具选择(如Postman、JMeter)、用例设计与执行,以及常见问题的解决方法。通过全面测试,可以提前发现潜在问题,优化用户体验,确保公众号上线后稳定运行。内容涵盖基础接口、高级接口、微信支付和数据统计接口的测试,强调了功能验证、性能优化、安全保护及用户体验的重要性。未来,随着微信生态的发展,接口测试将面临更多挑战和机遇,如小程序融合、AI应用和国际化拓展。
|
移动开发 小程序 JavaScript
开源的微信小程序框架
【8月更文挑战第22天】开源的微信小程序框架
679 65
|
11月前
|
JavaScript 小程序 开发者
uni-app开发实战:利用Vue混入(mixin)实现微信小程序全局分享功能,一键发送给朋友、分享到朋友圈、复制链接
uni-app开发实战:利用Vue混入(mixin)实现微信小程序全局分享功能,一键发送给朋友、分享到朋友圈、复制链接
1651 0
|
人工智能 搜索推荐 安全
从零到一:微信机器人开发的实战心得
从零到一:微信机器人开发的实战心得
928 2

热门文章

最新文章