From 764d883b5ea3bdc06abbec548b6df0511e567978 Mon Sep 17 00:00:00 2001
From: linwe <872216996@qq.com>
Date: Tue, 03 Sep 2024 09:46:05 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/binlog' into binlog

---
 src/main/java/org/springblade/common/config/WxPayConfig.java |  188 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 188 insertions(+), 0 deletions(-)

diff --git a/src/main/java/org/springblade/common/config/WxPayConfig.java b/src/main/java/org/springblade/common/config/WxPayConfig.java
new file mode 100644
index 0000000..c55037b
--- /dev/null
+++ b/src/main/java/org/springblade/common/config/WxPayConfig.java
@@ -0,0 +1,188 @@
+package org.springblade.common.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.FileInputStream;
+import java.nio.charset.StandardCharsets;
+import java.security.PrivateKey;
+
+
+@Configuration
+@ConfigurationProperties(prefix = "wxpay") //读取wxpay节点
+@Data //使用set方法将wxpay节点中的值填充到当前类的属性中
+@Slf4j
+public class WxPayConfig {
+
+	// 商户号
+	private String mchId;
+
+	// 商户API证书序列号
+	private String mchSerialNo;
+
+	// 商户私钥文件
+	private String privateKeyPath;
+
+	private String privateCertPath;
+
+	// APIv3密钥
+	private String apiV3Key;
+
+	// APPID
+	private String appid;
+
+	// 微信服务器地址
+	private String domain;
+
+	// 接收结果通知地址
+	private String notifyDomain;
+
+	// APIv2密钥
+	private String partnerKey;
+
+	/**
+	 * 获取商户的私钥文件
+	 *
+	 * @param filename
+	 * @return
+	 */
+	private PrivateKey getPrivateKey(String filename) {
+
+		try {
+			// FileInputStream fileInputStream = new FileInputStream(filename);
+			// log.info("文件内容:" + fileInputStream);
+			return PemUtil.loadPrivateKey(getFileInputStream(filename));
+		} catch (Exception e) {
+			log.info("私钥文件不存在", e);
+			throw new RuntimeException("私钥文件不存在", e);
+		}
+	}
+
+
+	/**
+	 * 获取商户的文件
+	 *
+	 * @param filename
+	 * @return
+	 */
+	public static FileInputStream getFileInputStream(String filename) {
+
+		try {
+			FileInputStream fileInputStream = new FileInputStream(filename);
+			return fileInputStream;
+		} catch (Exception e) {
+			log.info("读取文件不存在", e);
+			throw new RuntimeException("读取文件不存在", e);
+		}
+	}
+
+	/**
+	 * 获取商户的文件
+	 *
+	 * @return
+	 */
+	// @Bean
+	// public KeyStore keyStore() {
+	// 	try {
+	// 		InputStream certStream = WxPayConfig.class.getClassLoader().getResourceAsStream(privateCertPath);
+	// 		KeyStore ks = KeyStore.getInstance("PKCS12");
+	// 		ks.load(certStream, mchId.toCharArray());
+	// 		return ks;
+	// 	} catch (Exception e) {
+	// 		log.info("读取文件不存在", e);
+	// 		throw new RuntimeException("读取文件不存在", e);
+	// 	}
+	// }
+
+
+	/**
+	 * 获取签名验证器
+	 *
+	 * @return
+	 */
+//	@Bean
+	public ScheduledUpdateCertificatesVerifier getVerifier() {
+
+		log.info("获取签名验证器");
+
+		//获取商户私钥
+		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;
+	}
+
+
+	/**
+	 * 获取http请求对象
+	 *
+	 * @param verifier
+	 * @return
+	 */
+//	@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,会自动的处理签名和验签,并进行证书自动更新
+		CloseableHttpClient httpClient = builder.build();
+
+		return httpClient;
+	}
+
+	/**
+	 * 获取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;
+	}
+
+
+}
+

--
Gitblit v1.9.3