4.idea链接mysql
⚠️ 推荐一个插件一键生成CRUD
💰 MyBatisCodeHelperPro (Marketplace Edition)
🔗 打开链接好的数据库管理选择到对应的表右击
🦐 下面的选项卡里面的配置
- lombok 勾选 @Data
- 定制默认方法可以全部去掉
- mybatisPlus配置勾选 mybatisPlus3 和 idType选择为 ASSIGN_ID
- 其他的你看着来吧…
✅ 直接确定生成了一个CRUD 接下来将后面的三个表也一样的操作吧
👌 最终如此
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秘钥等等
完整
创建 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; } }
最终如此
四、测试项目
🥬 创建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
编写测试类 如下图
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); } }
🔥 启动项目
🐑 IDEA插件对标PostMan
Restful Fast Request
🚗 测试