测试系统:WIN10 x64
IDE工具:netbeans
JDK版本:1.8
直接上解决方案:
/**
* 获取微信支付的退款结果
*
* @param socketAgreement 安全套接字协议(当前微信支持的安全套接字协议为“PKCS12”【20200713091509】)
* @param certificatePath 证书的系统绝对路径(按微信建议,最好不能随便被外网访问的路径)
* @param certificatePassword 证书密码(默认为商户号)
* @param url 退款路径
* @param data 发送的XML数据
* @return 申请退款的结果
* @throws Exception
*/
public static String getWXPayRefundResult(
String socketAgreement,
String certificatePath,
String certificatePassword,
String url,
String data
) throws Exception {
String result = null;
SSLConnectionSocketFactory sslcsf;
try (FileInputStream fis = new FileInputStream(certificatePath)) {
KeyStore keyStore;
SSLContext sslc;
SSLContextBuilder sslcb;
socketAgreement = StringUtils.isBlank(socketAgreement) ? "PKCS12" : socketAgreement; // 默认为“PKCS12”
keyStore = KeyStore.getInstance(socketAgreement); // 创建密钥和证书储存器
keyStore.load(fis, certificatePassword.toCharArray()); // 加载证书以及该证书的密码
sslcb = SSLContexts.custom(); // 创建一个SSL上下文构造器
sslc = sslcb.loadKeyMaterial(keyStore, certificatePassword.toCharArray()).build(); // 构造器加载储存器并构建
sslcsf = new SSLConnectionSocketFactory(
sslc,
new String[]{"TLSv1", "TLSv1.1", "TLSv1.2"},
null,
new DefaultHostnameVerifier()
); // 创建SSL连接工厂
}
try (CloseableHttpClient chc = HttpClients.custom().setSSLSocketFactory(sslcsf).build()) {
HttpPost post = new HttpPost(url); // 创建连接
post.setEntity(new StringEntity(new String(data.getBytes()))); // 写入数据
CloseableHttpResponse chr = chc.execute(post); // 提交数据
// 读取返回结果
try (InputStreamReader isr = new InputStreamReader(chr.getEntity().getContent(), "UTF-8");
BufferedReader br = new BufferedReader(isr)) {
String line;
while ((line = br.readLine()) != null) {
result += line;
}
}
}
return result;
}
坑点:
- 微信支付的退款必须使用证书,这个证书的下载和安装过程参考:(https://jingyan.baidu.com/article/ed2a5d1f02ad0649f6be179d.html)
- 直接访问退款地址的人几乎都会看到这句话(这里简单说了这个退款必须经过SSL进行连接):
400 Bad Request No required SSL certificate was sent
-
证书最好不要外网可以访问的位置~
-
如果你的网络有严重的掉包,最好设置一下超时,默认超时一般不会挂。对,没被D/DOS的情况下~,再或者你的机器真的太...,基于这样的问题,你最好还是先进行压力测试,看看你这机器的瓶颈在哪~
-
部分代码来自httpclient官网API:(HttpClient - HttpClient SSL Guide)
-
经常做接口的最好把httpclient吃一遍,你会发现真的很好用~