微信提现到零钱V3接口的对接java实现
最近项目需要实现用微信提现到零钱的功能,但是发现微信支付接口已经升级V3版本,那么也就意味着之前微信支付的通用方法和SDK都是不可用的了,需要重新对应V3的SDK。微信的文档已经对接流程是很让人头大的,这里已经无力吐槽了,直接总结我的对接流程以及体验吧!
微信提现到零钱V3接口对接,我把它分为两项工作:1、微信支付平台证书下载,2、微信提现到零钱V3接口。
这里列举一些关键代码,完整代码参考《微信提现到零钱V3接口的对接java实现demo》。
微信平台支付证书下载
因为微信支付平台证书是实时在变化,所以需要我们实现每隔一段时间就要去下载获取最新的证书(这个设计本人觉得确实很奇葩,好喜欢支付宝的简单与友好!)。
我是用定时程序每个小时下载一次,下载后把最新的微信平台支付证书号存到本地数据库里,如下面代码示例(此代码参照了微信官方实例代码)。
//定时任务
@Component("wxpayCertDownTask")
@Lazy(false)
public class wxpayCertDownTask {
@Autowired
private ISysSetService sysSetService;
private boolean isTest = Constant.PROGRAM_MODE;
@Scheduled(cron = "${wechatpay.cert.down.task}")
public void startWxpayCertDown() {
CertificateDownloader downloader = new CertificateDownloader();
downloader.startDownWachatPayCert();
if (StringUtils.isNotEmpty(downloader.getWechatpayCertSerialNo())) {
//...省略部分代码...
System.out.println("---微信平台支付证书序列号---:" + downloader.getWechatpayCertSerialNo());
sysSetService.updateSysSet(s);//更新保存微信平台支付证书序列号
}
}
}
//下载器的定义
@Data
public class CertificateDownloader {
//证书解密的密钥
private String apiV3key;
//商户号
private String merchantId;
//商户私钥文件
private String privateKeyFilePath;
//商户证书序列号
private String serialNo;
//证书保存路径
private String outputFilePath;
//微信支付平台证书,用于验签
private String wechatpayCertificatePath;
//微信支付平台证书序列号
private String wechatpayCertSerialNo;
private static final String CertDownloadPath = "https://api.mch.weixin.qq.com/v3/certificates";
private List<PlainCertificateItem> downloadCertificate() throws IOException, GeneralSecurityException {
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(merchantId, serialNo,
PemUtil.loadPrivateKey(new FileInputStream(privateKeyFilePath)));
if (wechatpayCertificatePath == null) {
//不做验签
builder.withValidator(response -> true);
} else {
List<X509Certificate> certs = new ArrayList<>();
certs.add(PemUtil.loadCertificate(new FileInputStream(wechatpayCertificatePath)));
builder.withWechatpay(certs);
}
HttpGet httpGet = new HttpGet(CertDownloadPath);
httpGet.addHeader("Accept", "application/json");
try (CloseableHttpClient client = builder.build()) {
CloseableHttpResponse response = client.execute