linwe
2024-09-03 764d883b5ea3bdc06abbec548b6df0511e567978
src/main/java/org/springblade/common/config/WxPayConfig.java
New file
@@ -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;
   }
}