退款需要证书的支持、先去微信商户平台下载证书
一、RSA加密遇到的问题: DER input, Integer tag error
解决办法:
密钥(证书)不对,更换密钥(证书)
二、 {return_msg=0参数格式错误, return_code=FAIL}
返回这个信息没有指定是哪个参数格式的错误,只是显示[CDATA[0参数格式错误],这个时候我们要检查一下退款的金额是格式是否正确,退款金额一定要为正整数。一般出现参数格式错误的时候,我们需要去检查自己参入的参数格式是否正确,具体参数参照支付退款接口文
三、实例:
签名~~~~~签名~~~~~签名~~~~~签名~~~~~签名~~~~~签名~~~~~
然后~~~~~~~~
下面有证书请求工具,调用方法:
String httpRequest = wxHttpRequest.httpsRequest(applyRefundUrl, WXPayUtil.mapToXml(wxPayRefundMap), certPath, wxConfig.getMchId());
证书请求工具:https://www.jb51.net/article/148207.htm
package cn.sky999.util;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;
import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.security.*;
import java.security.cert.CertificateException;
@Component("wxHttpRequest")
public class WxHttpRequest {
//连接超时时间,默认10秒
private int socketTimeout = 10000;
//传输超时时间,默认30秒
private int connectTimeout = 30000;
//请求器的配置
private RequestConfig requestConfig;
//HTTP请求器
private CloseableHttpClient httpClient;
/**
* 加载证书
* @param certPath
* @throws IOException
* @throws KeyStoreException
* @throws UnrecoverableKeyException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
private void initCert(String certPath, String mchId) throws IOException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException {
//拼接证书的路径
//path = path + WxConfigure.certLocalPath;
KeyStore keyStore = KeyStore.getInstance("PKCS12");
//加载本地的证书进行https加密传输
FileInputStream instream = new FileInputStream(new File(certPath));
try {
keyStore.load(instream, mchId.toCharArray()); //加载证书密码,默认为商户ID
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} finally {
instream.close();
}
// Trust own CA and all self-signed certs
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, mchId.toCharArray()) //加载证书密码,默认为商户ID
.build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[]{"TLSv1"},
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
httpClient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
//根据默认超时限制初始化requestConfig
requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
}
/**
* 通过Https往API post xml数据
* @param requestUrl API地址
* @param xmlObj 要提交的XML数据对象
* @param certPath 当前目录,用于加载证书
* @return
* @throws IOException
* @throws KeyStoreException
* @throws UnrecoverableKeyException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public String httpsRequest(String requestUrl, String xmlObj, String certPath, String mchId) throws IOException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException {
//加载证书
initCert(certPath, mchId);
String result = null;
HttpPost httpPost = new HttpPost(requestUrl);
//得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
StringEntity postEntity = new StringEntity(xmlObj, "UTF-8");
httpPost.addHeader("Content-Type", "text/xml");
httpPost.setEntity(postEntity);
//设置请求器的配置
httpPost.setConfig(requestConfig);
try {
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "UTF-8");
} catch (ConnectionPoolTimeoutException e) {
System.out.println("http get throw ConnectionPoolTimeoutException(wait time out)");
} catch (ConnectTimeoutException e) {
System.out.println("http get throw ConnectTimeoutException");
} catch (SocketTimeoutException e) {
System.out.println("http get throw SocketTimeoutException");
} catch (Exception e) {
System.out.println("http get throw Exception");
} finally {
httpPost.abort();
}
return result;
}
}