微信退款開發需要的步驟比較多,首先是按照官方文檔生成證書,下載下來是一個zip。有時候會很疑惑,這個證書怎麼用?實際上呢,就是發送接口的時候帶上證書就可了。看一個具體的例子吧,以JSAPI微信退款為例。1、首先是發起退款申請因為每次發起退款請求,都要帶上證書,如果直接從證書文件讀取内容,速度很慢,因此将證書内容存放于内存中。大緻如下:
@Getter
@Configuration
public class WxConfig {
/**
* 微信支付,證書存放父路徑 證書名稱:商戶id_cert.p12 商戶id_cert.pem 商戶id_key.pem
*/
@Value("${wx.apiCertLocation}")
private String apiCertLocation;
/**
* 從 商戶id_cert.p12文件讀取内容,放入字節數組。(不要每次都從io中獲取數據,太慢)
*/
private byte [] certData;
/**
* 将商戶id_cert.p12文件内容轉換成流
* @return
*/
public InputStream getCertStream() throws IOException {
if(certData==null||certData.length==0){
InputStream certStream = new FileInputStream(apiCertLocation mchId "_cert.p12");
this.certData = IOUtils.toByteArray(certStream);
certStream.close();
}
return new ByteArrayInputStream(this.certData);
}
}
下面就是發送帶證書的請求了:
InputStream certStream = wxConfig.getCertStream();
String xmlResult = requestWithApiCert(REFUND_URL,xmlStr,mchId(),certStream);
certStream.close();
具體的工具類:
/**
* 微信支付 帶API證書的請求
* @return
* @throws Exception
*/
public static String requestWithApiCert(String url, String data, String mchId,InputStream certStream) throws Exception {
BasicHttpClientConnectionManager connManager;
// 證書
char[] password = mchId.toCharArray();
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(certStream, password);
// 實例化密鑰庫 & 初始化密鑰工廠
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, password);
// 創建 SSLContext
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
sslContext,
new String[]{"TLSv1"},
null,
new DefaultHostnameVerifier());
connManager = new BasicHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslConnectionSocketFactory)
.build(),
null,
null,
null
);
HttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(connManager)
.build();
HttpPost httpPost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom().build();
httpPost.setConfig(requestConfig);
StringEntity postEntity = new StringEntity(data, "UTF-8");
httpPost.addHeader("Content-Type", "text/xml");
httpPost.setEntity(postEntity);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
return EntityUtils.toString(httpEntity, "UTF-8");
}
微信退款回調中,有一個req_info字段,需要解密才可以使用:
/**
* 注意此方法 如果報錯:Illegal key size or default parameters
一般需要到oracle官網下載local_policy.jar US_export_policy.jar
包進行替換,路徑:jdk安裝路徑/jre/lib/security
* @param reqInfo
* @param apiKey
* @return reqInfo的xml字符串
* @throws Exception
*/
public static String getReqInfoXml(String reqInfo,String apiKey) throws Exception{
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(apiKey.getBytes());
String keyMd5String = (new BigInteger(1, md5.digest())).toString(16).toLowerCase();
SecretKeySpec key = new SecretKeySpec(keyMd5String.getBytes(), "AES");
cipher.init(2, key);
return new String(cipher.doFinal(Base64.decodeBase64(reqInfo)));
}
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!