Appearance
配置商户信息、证书、密钥等。将客户端对象构建到Bean中,方便后续使用。
我们可以使用官方提供的 SDK,帮助我们完成开发。实现了请求签名的生成和应答签名的验证。
xml
<!-- 微信支付 -->
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.4.2</version>
</dependency>
首先是application.yml,本地运行时正数序列号也就是pem文件,放置到项目根目录下,不是resource下是项目的跟目录下,或者使用绝对地址。
yaml
weixin:
appid: wx*************eec # appid
mch-serial-no: 5BB08B7*******7772F2*****8386A0 # 证书序列号
private-key-path: D:\code\javaCode\pem\apiclient_key.pem # 证书路径
mch-id: 16*****284 # 商户号
key: G6lFcTDd***********4o6uvHbr4 # api秘钥
domain: https://api.mch.weixin.qq.com # 微信服务器地址
notify-domain: https://xk857.mynatapp.cc # 回调,自己的回调地址
部署到centos后,要使用绝对地址了,可以参考:
yaml
weixin:
private-key-path: /usr/local/xxlm_apiclient_key.pem # 证书序列号,其他的不变只是pem文件位置改变
创建配置文件
java
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.Verifier;
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.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.Data;
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.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
@Configuration
@PropertySource("classpath:application.yml") //读取配置文件
@ConfigurationProperties(prefix = "weixin") //读取wxpay节点
@Data //使用set方法将wxpay节点中的值填充到当前类的属性中
public class WxPayConfig {
// 商户号
private String mchId;
// 商户API证书序列号
private String mchSerialNo;
// 商户私钥文件
private String privateKeyPath;
// APIv3密钥
private String key;
// APPID
private String appid;
// 微信服务器地址
private String domain;
// 接收结果通知地址
private String notifyDomain;
/**
* 获取商户的私钥文件
*
* @param filename 证书地址
* @return 私钥文件
*/
public PrivateKey getPrivateKey(String filename) {
try {
return PemUtil.loadPrivateKey(new FileInputStream(filename));
} catch (FileNotFoundException e) {
throw new DefaultException("私钥文件不存在");
}
}
/**
* 获取签名验证器
*/
@Bean
public Verifier getVerifier() {
// 获取商户私钥
final PrivateKey privateKey = getPrivateKey(privateKeyPath);
// 私钥签名对象
PrivateKeySigner privateKeySigner = new PrivateKeySigner(mchSerialNo, privateKey);
// 身份认证对象
WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);
// 获取证书管理器实例
CertificatesManager certificatesManager = CertificatesManager.getInstance();
try {
// 向证书管理器增加需要自动更新平台证书的商户信息
certificatesManager.putMerchant(mchId, wechatPay2Credentials, key.getBytes(StandardCharsets.UTF_8));
} catch (IOException | GeneralSecurityException | HttpCodeException e) {
e.printStackTrace();
}
try {
return certificatesManager.getVerifier(mchId);
} catch (NotFoundException e) {
e.printStackTrace();
throw new DefaultException("获取签名验证器失败");
}
}
/**
* 获取微信支付的远程请求对象
*
* @return Http请求对象
*/
@Bean
public CloseableHttpClient getWxPayClient() {
// 获取签名验证器
Verifier verifier = getVerifier();
// 获取商户私钥
final PrivateKey privateKey = getPrivateKey(privateKeyPath);
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create().withMerchant(mchId, mchSerialNo, privateKey)
.withValidator(new WechatPay2Validator(verifier));
return builder.build();
}
}