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 java.io.FileInputStream; import java.nio.charset.StandardCharsets; import java.security.PrivateKey; //@Configuration // @PropertySource("classpath: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 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(String privateKeyPath, String mchSerialNo, String mchId, String apiV3Key) { 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(String privateKeyPath, String mchSerialNo, String mchId, String apiV3Key) { log.info("获取httpClient"); //获取商户私钥 PrivateKey privateKey = getPrivateKey(privateKeyPath); WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create() .withMerchant(mchId, mchSerialNo, privateKey) .withValidator(new WechatPay2Validator(getVerifier(privateKeyPath, mchSerialNo, mchId, apiV3Key))); // ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient // 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新 CloseableHttpClient httpClient = builder.build(); return httpClient; } }