微信公众号-申请退款结果通知-Java

  • 应用场景
  1. 当商户申请的退款有结果后,微信会把相关结果发送给商户,商户需要接收处理,并返回应答
  2. 特别说明:退款结果对重要的数据进行了加密,商户需要用商户秘钥进行解密后才能获得结果通知的内容
  • 解密方式,步骤如下
  1. 对加密串A做base64解码,得到加密串B
  2. 对商户key做md5,得到32位小写key* ( key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 )
  3. 用key*对加密串B做AES-256-ECB解密(PKCS7Padding
  • 接口链接
  1. 在申请退款接口中上传参数“notify_url”以开通该功能
  2. 如果链接无法访问,商户将无法接收到微信通知
  3. 通知url必须为直接可访问的url,不能携带参数
  • 引入jar包
<dependency>
       <groupId>org.bouncycastle</groupId>
       <artifactId>bcprov-jdk16</artifactId>
       <version>1.46</version>
</dependency>
  • 代码如下
//接收微信退款通知的数据流
InputStream inStream = request.getInputStream();
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
   outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
//微信退款通知返回串
String resultStr = new String(outSteam.toByteArray(), "utf-8");
//将返回串转换成 Map
Map<String, String> xmlToMap = WxPayUtils.xmlToMap(resultStr);
//在return_code为SUCCESS的时候有返回 req_info
if ("SUCCESS".equals(xmlToMap.get("return_code"))) {
      String reqInfo = xmlToMap.get("req_info");// 退款返回加密信息
      //对商户key做md5
      String keyMd5 = WxPayUtils.MD5(WxPayConstants.KEY).toLowerCase();
      //对加密串req_info做base64解码
      String decodeReqInfo = Base64.decodeBase64(reqInfo);
      //PKCS7Padding填充方式
      Security.addProvider(new BouncyCastleProvider());
    
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");  
      cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyMd5.getBytes(), "AES"));
        
      byte[] decoded = cipher.doFinal(data);
      //获取解密后的返回串,这个才是真正需要的数据
      String decryptInfo = new String(decoded, "UTF-8");
      //将返回串转换成 Map
      Map<String, String> reqInfoMap = WxPayUtils.xmlToMap(decryptInfo);
      //后面的逻辑自己处理
      ...
}

猜你喜欢

转载自my.oschina.net/u/3694704/blog/1791931