微信支付退款结果通知(回调) AES-256-ECB解密 代码
微信支付中的退款后,微信那边需要回调。恶心的是需要我们解密。
给大家我的代码看看。
每个类都有一个主方法供大家测试用。
Base64Util
package com.xz.app.util;import java.util.Base64;/***import java.util.Base64;/*** @author jing.huang* @function jdk8支持* @date 2018年1月10日* @version*/
public class Base64Util {public static byte[] decode(String encodedText){final Base64.Decoder decoder = Base64.getDecoder();return decoder.decode(encodedText);}public static String encode(byte[] data){final Base64.Encoder encoder = Base64.getEncoder();return encoder.encodeToString(data);}/*** @param args*/public static void main(String[] args) {try {final Base64.Decoder decoder = Base64.getDecoder();final Base64.Encoder encoder = Base64.getEncoder();final String text = "字串文字";final byte[] textByte = text.getBytes("UTF-8");//编码final String encodedText = encoder.encodeToString(textByte);System.out.println(encodedText);//解码System.out.println(new String(decoder.decode(encodedText), "UTF-8"));} catch (Exception e) {e.printStackTrace();}// final Base64.Decoder decoder = Base64.getDecoder();
// final Base64.Encoder encoder = Base64.getEncoder();
// final String text = "字串文字";
// final byte[] textByte = text.getBytes("UTF-8");
// //编码
// final String encodedText = encoder.encodeToString(textByte);
// System.out.println(encodedText);
// //解码
// System.out.println(new String(decoder.decode(encodedText), "UTF-8"));}}
MD5
package com.xz.app.util;import java.security.MessageDigest;public class MD5 {private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7","8", "9", "a", "b", "c", "d", "e", "f"};/*** 转换字节数组为16进制字串* @param b 字节数组* @return 16进制字串*/public static String byteArrayToHexString(byte[] b) {StringBuilder resultSb = new StringBuilder();for (byte aB : b) {resultSb.append(byteToHexString(aB));}return resultSb.toString();}/*** 转换byte到16进制* @param b 要转换的byte* @return 16进制格式*/private static String byteToHexString(byte b) {int n = b;if (n < 0) {n = 256 + n;}int d1 = n / 16;int d2 = n % 16;return hexDigits[d1] + hexDigits[d2];}/*** MD5编码* @param origin 原始字符串* @return 经过MD5加密之后的结果*/public static String MD5Encode(String origin) {String resultString = null;try {resultString = origin;MessageDigest md = MessageDigest.getInstance("MD5");resultString = byteArrayToHexString(md.digest(resultString.getBytes()));} catch (Exception e) {e.printStackTrace();}return resultString;}public static void main(String[] args) {System.out.println("111"+MD5Encode("111"));}}
AESUtil
/*** */
package encode;import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;/*** @author jing.huang* @function* @date 2018年1月10日* @version */
public class AESUtil {/** * 密钥算法 */ private static final String ALGORITHM = "AES"; /** * 加解密算法/工作模式/填充方式 */ private static final String ALGORITHM_MODE_PADDING = "AES/ECB/PKCS5Padding"; /** * 生成key */ private static SecretKeySpec key = new SecretKeySpec(MD5.MD5Encode("2IBtBXdrqC3kCBs4gaceL7nl2nnFadQv").toLowerCase().getBytes(), ALGORITHM); /** * AES加密 * * @param data * @return * @throws Exception */ public static String encryptData(String data) throws Exception { // 创建密码器 Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING); // 初始化 cipher.init(Cipher.ENCRYPT_MODE, key); return Base64Util.encode(cipher.doFinal(data.getBytes())); } /** * AES解密 * * @param base64Data * @return * @throws Exception */ public static String decryptData(String base64Data) throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING); cipher.init(Cipher.DECRYPT_MODE, key); return new String(cipher.doFinal(Base64Util.decode(base64Data))); } public static void main(String[] args) throws Exception { //解密
// String req_info="Ih5osM/5IbPfHouVrUmwebd1yAW2Gys91jv006W1237sSi3z022KxHafLIDMrQLYiBttTadgvy2cbx6DnmwDIQ52lPWfo6pAAHt7Q9DjBIpDRQ7JsbEBlomoQP2ZkdNHnWscVYuFEVlItaSlkSlcKLdB4UwMduqDYseFsUUthz6htPeBu987zXS6dKrgIbRwOxt5RfPmk1sf0oVB2yU3UH0Ly8SzBjmN1jrh4qAaUkfH6VkeMJcsZSGchQn2VresxJTbGH++JE1UsXUF3gyYpweyxBPtHoKdaggsIONR20UKNxJYPJLnEOnfQF/Ipmk8/QmTVRK7iqfVLC9EA1Auma0AlKBjZlYqynUlF3y+E2ZzgWMUlvDHZVWDbzp/TcE0q+Ukc7yQ3HBsibDR474SPlLTkCWz1iydXzkVcLqJKamsh76Liv1a0hzu0sI3qasMAfmwU6/q7/N6quq031toO1GxqkVaxBRK7e64gSOx9ArxxVFgZ7WN+JPq2OH/pTKH8ToxHA0rtxN5+aAgZGkXiIOUiHtp4mjpRxqe34WK7C7Nr0DQyOVwsXT2TTegSgWGm34aa//ZYxHedubv2iX+E7K222lptg9IqHlMXBbwKFtKtIcal61+8ciz+sB1FBpqHchC+3whTqWv5ZANiHBzaOhbIbA/mKX2XZ6Cy0iYh+bL/8Y/Hvz/UnMGzor+2anIUeBAGRQmseL4jY+Qic46WLuEhDcarCaO4JgJSAOC+VmsdrER9TRum26PFwTQwtNpxkrKCiO9Gv36Ood5D8hXnLHUH+4nbsek8ouxkCcFXq4Us0mipB3i5ksQpt23LiJm9Ahxyvptp9Q41SytS48NXiz3IxTOqDdknowedZwAtJ/fhBlwiOHD9N+pECXuNBKLaCZcatGycr0/DPELiCF+MIRQ6V60wzaZD74TKRFULd1ljNsoQIAbuGaT40WMDY6a28jBHQ/IXnD4gvSvfeumwQzp3Q9PiPyFtF6JxH7RBRj9/lmQuQozJIPZCaCNVTBfWQOdcFaBnPLN0ZNvzjA93g6jcIxHzkXHmiGfh98vq2E=";String req_info = "m4NnwrtY0jhpDgNp65H1V/0OWMtSoTYhhY89MHbflhmnaHq9ZKjx9ABq6Jpg4SccA876HVy7J9P85NpdvCMNGInZ4fANDRE+YfZe4HeF+bbFj6JETcEFPpE9YW+bTbC0D+gl/otScJfvB2QUK7+EeBGPHN1EWX9zbr2Gw6AUaORdFk3mGxV5dtjuwWQrv5juzkXDs33Z2dUMslO+i3j0cTDHqwS4hptx2j6h2HvzgzltFbjo7nysU+4rArqJvrGW/9r18e1St9XgG21NALqixfaSmqetOR4zLVL4/+z3CEz8cg5r+/4GUOTf3XFmLCZ/wEkRQhKRNVibG0NFfiG3KnqArMJ/dheQHCd7qL+XX/ZV6tj8RLMgL7R6hOiR03Ljyikdxq9M3K9CTYgf03pHJd3geXX1LgXrLxc1flL6NW+zD3ZayGYpr1WpLsSMG7z8W5j1pme6cRj3n2+CwSFnOnOkxaFuLKoJAJIqM3gbC0eN++vY73RKphlI4zZqg6o5s3MXI6ju1yoi/ZQ+XbTg2JttsdbU0aySernKwkt0rYMf0j/Mcvo2axgHbI3w/iTm141WxHUjkQ+ga2X1pOWdGifGhSmMP8oGaA/WD5MAsK1qXX0eFvUWS/PTauCSTWq5Cmr8loA/KL3jgvB0nyR4mfccB+tPy4Ny7kzOlr/VNeb0ULf96R0AWFWCtdt8AmujAP0DYiM5FSmYLI0XRhpSDjnEbBM8+isNE1GlAVR3NzzemwQORihScovpAktbRSN/d3N+NgTjSoVDiJvCOxCs3thX9qt9iwYbA+/X/gv8lza2FZyIzwkQxGRcYl8JWKpXzNW8EWUNVnSLdHvQttDeV3CvgP/x579RGd6whyFYS6AaI0qw7oTjCFh2EHS/VzGvFuv166ZlVIJ4MNvg79O9h63ZOSE1LzVqEsVh8fDCfM2GgJ9aUdl95Djgunit4yIZOdoigR3f/BEHKrYCEham11rYohaAXs4XAXWihsV3WD5j4G/P+txvjAwujvf4HDwzHgFsmSml013U2mUiy+v4zw==";String B = AESUtil.decryptData(req_info); System.out.println(B); //加密String str = "<root>"+"<out_refund_no><![CDATA[2531340110812300]]></out_refund_no>"+"<out_trade_no><![CDATA[2531340110812100]]></out_trade_no>"+"<refund_account><![CDATA[REFUND_SOURCE_RECHARGE_FUNDS]]></refund_account>"+"<refund_fee><![CDATA[1]]></refund_fee>"+"<refund_id><![CDATA[50000505542018011003064518841]]></refund_id>"+"<refund_recv_accout><![CDATA[支付用户零钱]]></refund_recv_accout>"+"<refund_request_source><![CDATA[API]]></refund_request_source>"+"<refund_status><![CDATA[SUCCESS]]></refund_status>"+"<settlement_refund_fee><![CDATA[1]]></settlement_refund_fee>"+"<settlement_total_fee><![CDATA[1]]></settlement_total_fee>"+"<success_time><![CDATA[2018-01-10 10:31:24]]></success_time>"+"<total_fee><![CDATA[1]]></total_fee>"+"<transaction_id><![CDATA[4200000052201801101409025381]]></transaction_id>"+"</root>";System.out.println(encryptData(str));} }
注意:key要改为自己的key
/*** * 微信退款回调* @param* @param*/@ApiOperation(value = "微信退款回调", notes = "微信退款回调")@RequestMapping(value = "WXtrackRefunderrorrm2", method = RequestMethod.POST)@ResponseBodypublic void WXtrackRefunderrorrm2(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws Exception{logger.info("开始回调");InputStream inStream = httpRequest.getInputStream();ByteArrayOutputStream outSteam = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len = 0;while ((len = inStream.read(buffer)) != -1) {outSteam.write(buffer, 0, len);}String resultxml = new String(outSteam.toByteArray(), "utf-8");Map<String, String> params = WXPayUtil.xmlToMap(resultxml);outSteam.close();inStream.close();logger.info("here");if (params.get("return_code").equals("SUCCESS")) {logger.info("退款成功0");logger.info("退款成功1");String req_info = params.get("req_info");logger.info(req_info);// String resultStr = AESUtil.decryptData(req_error);// WXPayUtil.getLogger().error("refund:解密后的字符串:" + resultStr);// Map<String, String> aesMap = WXPayUtil.xmlToMap(resultStr);String afterDecrypt=AESUtil.decryptData(req_info);logger.info(afterDecrypt);Map<String, String> aesMap = WXPayUtil.xmlToMap(afterDecrypt);logger.info("退款成功1");/** 以下为返回的加密字段: **/// 商户退款单号 是 String(64) 1.21775E+27 商户退款单号String out_refund_no = aesMap.get("out_refund_no");// 退款状态 是 String(16) SUCCESS SUCCESS-退款成功、CHANGE-退款异常、REFUNDCLOSE—退款关闭String refund_status = aesMap.get("refund_status");// 商户订单号 是 String(32) 1.21775E+27 商户系统内部的订单号String out_trade_no = aesMap.get("out_trade_no");logger.info(refund_status);logger.info(out_trade_no);logger.info(out_refund_no);if (!WXPayConstants.SUCCESS.equals(refund_status)) {//这里写业务代码logger.info("退款成功");logger.info(params);}}}
从微信那边获得req_info后对其解密,在获得你的订单号等,来进行业务操作。
如果不行的话。请按下面的方法操作一下。
JAVA运行环境默认不允许256位密钥的AES加解密,解决方法就是修改策略文件
在官方网站下载JCE无限制权限策略文件
JDK7版本JCE下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
JDK8版本JCE下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt
如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件
如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件
实践:
以JDK8为例,系统为WIN10,替换上述security文件夹下\policy\limited文件夹和\policy\unlimited文件夹里面的local_policy.jar和US_export_policy.jar这两个文件。
若是在服务器上,则只有在security目录下有local_policy.jar和US_export_policy.jar,替换即可
感谢简书的推荐
链接:https://www.jianshu.com/p/6d3259e88b80
微信支付退款结果通知(回调) AES-256-ECB解密 代码相关推荐
- 微信支付退款结果通知解密 base64_decode / md5 / AES
转自 https://jishu8.net/tag/wxpay 微信支付退款结果通知解密步骤如下: 第一步,对商户密钥key进行MD5加密,得到32位小写加密串StringA key设置路径:微信商户 ...
- 微信支付回调 java_Java微信支付-退款成功异步回调验签
/** * 微信支付实现 * * @author: Sun * @create: 2019-10-10 17:54 * @version: v1.0 */ @Service @Slf4j public ...
- java微信支付异步通知_Java中微信支付退款异步通知解码
微信所有的支付结果都是加密处理的,他和订单支付成功的异步通知不一样. 他的基本返回是: SUCCESS 我们需要对req_info解码才能看到退款的明文 解码后会得到明文: 解密步骤如下: (1)对加 ...
- java aes 256 ecb解密_Java AES 256 解密
题目描述 我用JAVA在實行解密,參考了c#的範例,加密沒有問題 KEY和IV都是相同的 题目来源及自己的思路 相关代码 JAVA的代碼public static String decrypt(Str ...
- 微信小程序开发实战11_4 微信支付退款流程
当交易发生之后一年内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付金额退还给买家,微信支付将收到退款请求并且验证成功之后,将支付款按原路退还至买家账号上.使用该接口时的一些注意事项如下 ...
- Java 微信小程序笔记 二、 微信支付退款案例
一.前期准备工作: 上篇博客配置的一些参数和文件Jar包 都要用到 微信支付需要小程序和商户绑定 APP绑定微信商户平台获取商户id(mchID). 证书(商户后台下载). 支付签名密钥(商户后台设置 ...
- java 微信转账 ca_error_java,微信支付退款_微信支付退款接口调用证书出现错误,java,微信支付退款,ssl - phpStudy...
微信支付退款接口调用证书出现错误 PS:代码是copy腾讯提供的demo,但运行有问题,望大拿能够帮忙解决 加载证书时间出现如下错误: java.io.IOException: DER input, ...
- 微信接口java解密_java使用AES-256-ECB(PKCS7Padding)解密——微信支付退款通知接口指定解密方式...
1.场景 在做微信支付退款通知接口时,微信对通知的内容做了加密,并且指定用 AES256 解密,官方指定的解密方式如下: 2.导包 org.bouncycastle bcprov-jdk15on 1. ...
- java 中实现微信支付退款功能案例
微信支付功能做了太多,今天又做了支付.退款.查询.提现等等,顺便把支付和退款代码贴出来,希望对初学者有点帮助. 首先调用微信支付退款 API 地址 https://pay.weixin.qq.com/ ...
最新文章
- 硬分叉升级加速BCH相关应用研发
- 图论算法-图论的表示、分类及基本概念(系列1)
- 七、Sqoop架构,安装和基本使用
- 解决《Mobile绘制背景图片》中的问题
- PackagesNotFoundError: The following packages are not available from current channels:
- 赋能开发者,英特尔发布oneAPI 2022工具包
- ascii非打印控制字符表_C程序打印ASCII表/图表
- Redis流水线性能提高
- 减治法在查找算法中的应用(JAVA)--折半查找
- Bootstrap栅格系统研究
- Reading privileged memory with a side-channel
- LeetCode每日一题——猜数字游戏
- 闭包:学习Javascript闭包(Closure)
- 机载激光雷达原理与应用科普(二)
- Shopee平台不活跃商品清理规则更新
- js定义一个函数,返回所有水仙花数
- RTP 发送PS流工具(已经开源)
- 云帆加速:广电新媒体营收如何跑赢成本
- 【计算机毕业设计】java线上教学平台 springboot智慧教学系统
- 如何减少手机辐射?——七招减少手机对您的危害
热门文章
- 【裂缝检测】文献阅读笔记
- 程序人生-Hello‘s P2P From Program to Progress
- 哪里有什么平等--《动物农场》
- python利用百度云接口实现文字OCR功能
- 正向代理vs反向代理
- 给力!天猫旗舰店2.0版本快要来啦,多元化趣味互动玩转福利!
- NTC 测取温度(方法二)
- 程序员:“我今年 31 岁,工作 10 年,明天退休”
- P576线程P582多线程P583startP584Runnable创建线程P58子线程应用P587退出P588方法P591守护线程P592线程7大状态P593同步P594互斥锁P596释放锁P598
- 天猫店群自己做,营业额一直上不去,店群怎么做才能有高利润?