部分內容參考:https://blog.csdn.net/L_K_ong/article/details/90410085
這裏主要描述 退款回調信息內容:
微信申請退款接口文檔:
https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_4&index=4
微信退款通知接口文檔:
https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_16&index=10
【退款回調參數 】
{nonce_str=cc071fc5877f7d89b308be3d6e4f3c19,
req_info=LmCGMTk2/zKAR2pwxsg+NrzO8pQuSkfPDPyVnLO9Jyr8KcyrUoxBewHd+cH2MNXpYU1Ht+gEprP/EAg2JfC9qcpMkSOuOlbxw0a2we0bPXrYGMHGOGxZsyOcAqkmVV1NgaQoJjopQNQpjDcF8QWIw+CAxe9J7lYn4TYPKphtbnUKYrP3tcsKxuToKy8FSLTYREWOjxVqq37yoiQmTtaBE22SaRN4zAR1hbfn7HH1sZ4HAoWpRRa50ZP8Xk/uudhhiZ2B3KhPfVMb8/VGqKp360prF+BTsVSUH3sMPS58PvNx0KjbKiYC/VFyfstJN3VaKyR9zhuwoT5Enddr9au77BBpuGh21ZRY3LaXWmse5/2YHcmEP2v8tF6AZBNcm1m1CRjH3HynXLx9KrVviDlCrnujDasvaIIDGyz7f6n+2Q8EyarBEYzCg9WtLBbBWWP/MJUCfrVp9oQls7fJuNQijAqu5jDPGWmfLLNsPvsy1YNces1HoAJmDgpsAskYWrVdxvusgA41mUqV/22+OQhgxrsQJWk1ybdOXshrbUJSdI/3mowiIYpgFN3GyHb8omASp4+nMvmAnxQ6hobT+rmFhjJHMd8qR8iAVhttBWm8wariuWZsizr8lmLAPVILRrvl/awq+/pyoSnDrqJsyr4VvWL4tIADc96vnlAVicw8s/A7J/ZrvR/NGsD58OO1kDyzGtkCB3mzegUhBEm9phWR/csDEpxNYYOCajOiYczEe73FzNWy8CYrPRaRq0Ea/ZmDm6xBy+Gkp3h0MDqAV1huNzWjXTswBsCi3VNghUE/ddhZZ4M3XhgwAMglP0us7J3b8MFPYtvLPU7ZY3PavP6WAxB190gY3b9x32DC3F2hW77bw7xiGjoCQUA47bkCyiq3Q64KFko3Rarv9c+b/P2804kOI1+pPFN9bwCErm8CcpgK5YyV1OAO47U9bbNP+tybHtWIyoCJ0EYJmC38CVSt6TtWHAuYBlblweWqt+PsYC2H3xvV8aLCTlh2GwSW8PQfSvqaU00Uu81i2PWiMMBjaU9zqT+V6TZ5A4wVSgLBmBLMUg2icnzvVuLcq73cy0F/nWa2tPhK9qZp+exa1Q==,
appid=wx0000000004,
mch_id=1xxxxxxxxx2,
return_code=SUCCESS}
我們需要的參數都在req_info當中,包含了微信訂單號,商戶訂單號等信息,解析了req_info字段後,商戶才能知道這筆退款來自哪一個訂單。
官方文檔中解密流程:
在解碼之前需要需要調用如下代碼,Security.addProvider(new BouncyCastleProvider());使解碼器生效,這個加載過程還挺慢的,有時候要好幾秒,還好只需要加載一次就能一直使用。所以加在static代碼中。
static{
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null){
System.out.println("security provider BC not found");
Security.addProvider(new BouncyCastleProvider());
}
}
要使用BouncyCastleProvider類,需要額外引入jar包,pom依賴是這樣的:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.59</version>
</dependency>
第一步, base64解碼,得到byte數組。這個直接用java的Base64.decode就可以
//1,對加密串A做base64解碼,得到加密串B。
Base64.Decoder decoder = Base64.getDecoder();
byte[] base64ByteArr = decoder.decode(req_info);
第二步,對key做MD5加密,這一步也不是很複雜。
可在線生成之後拿來使用
第三步,使用PKCS7Padding 格式做AES-256-ECB解密。這一步坑略大。
java提供了
javax.crypto.spec. SecretKeySpec
javax.crypto. Cipher
這兩個類來應對AES解密,然而因爲某些原因,中國的JDK版本並不能支持256格式的AES解密,也就是所謂的PKCS7Padding,中國的JDK能支持的是128格式的AES解密,也就是PKCS5Padding,。
所以,我們需要網上下兩個jar包,替換我們機器上JDK目錄下的jar包,別下錯版本,JDK8版本的這兩個jar包下載地址:
https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
下載的jar有兩個:local_policy.jar和US_export_policy.jar
下載之後解壓裏面,有兩個jar包替換#JavaHome#\jre\lib\security\policy下的同名jar包,有可能這個目錄下還有倆文件夾,limited和unlimited,jar包在這兩個文件夾下,反正lib\security目錄下肯定是有同名文件的,替換了就好了。
替換jar包後java程序需要重啓。
暫時來看替換了這兩個jar包還不會引起什麼不好的影響。
//params爲退款回調參數
Map params = XMLUtil.doXMLParse(xmlMsg);
log.info("【退款回調參數 】"+params);
String req_info=params.get("req_info").toString();//回調加密字段
log.info("【req_info】 : "+req_info);
//1,對加密串A做base64解碼,得到加密串B。
Base64.Decoder decoder = Base64.getDecoder();
byte[] base64ByteArr = decoder.decode(req_info);
String md5_key = "123432445432;
SecretKey secretKey = new SecretKeySpec(md5_key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] resultbt = cipher.doFinal(base64ByteArr);
String result = new String(resultbt);
log.info("【req_info】 : "+result);
Map result_params = XMLUtil.doXMLParse(result);