微信小程序> 微信退款,微信小程序微信退款注意事项及退款通知信息解密

微信退款,微信小程序微信退款注意事项及退款通知信息解密

浏览量:701 时间: 来源:默认S
1.商户退款单号(out_refund_no)必须唯一,如果不唯一微信端返回的错误提示是“支付单号校验不一致”,需要注意。2.退款解密算法注意操作密钥。在此记录下解密代码。(1)对加密串A做base64解码,得到加密串B(2)对商户key做md5,得到32位小写key(key设置路径:微信商户平台(pay.weixin.qq.com)–账户设置–API安全–密钥设置)3)用key对加密串B做AES-256-ECB解密(PKCS7Padding)
Base64Utils.java
publicclassBase64Utils{
privatestaticchar[]base64EncodeChars=newchar[]{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/',};
privatestaticbyte[]base64DecodeChars=newbyte[]{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1};
privateBase64Utils(){}
/将字节数组编码为字符串@paramdata/publicstaticStringencode(byte[]data){StringBuffersb=newStringBuffer();intlen=data.length;inti=0;intb1,b2,b3;
while(ilen){b1=data[i++]&0xff;if(i==len){sb.append(base64EncodeChars[b12]);sb.append(base64EncodeChars[(b1&0x3)4]);sb.append("==");break;}b2=data[i++]&0xff;if(i==len){sb.append(base64EncodeChars[b12]);sb.append(base64EncodeChars[((b1&0x03)4)|((b2&0xf0)4)]);sb.append(base64EncodeChars[(b2&0x0f)2]);sb.append("=");break;}b3=data[i++]&0xff;sb.append(base64EncodeChars[b12]);sb.append(base64EncodeChars[((b1&0x03)4)|((b2&0xf0)4)]);sb.append(base64EncodeChars[((b2&0x0f)2)|((b3&0xc0)6)]);sb.append(base64EncodeChars[b3&0x3f]);}returnsb.toString();}
/解密@paramstr/publicstaticbyte[]decode(Stringstr)throwsException{byte[]data=str.getBytes("GBK");intlen=data.length;ByteArrayOutputStreambuf=newByteArrayOutputStream(len);inti=0;intb1,b2,b3,b4;
while(ilen){
/b1/do{b1=base64DecodeChars[data[i++]];}while(ilen&&b1==-1);if(b1==-1){break;}
/b2/do{b2=base64DecodeChars[data[i++]];}while(ilen&&b2==-1);if(b2==-1){break;}buf.write((b12)|((b2&0x30)4));
/b3/do{b3=data[i++];if(b3==61){returnbuf.toByteArray();}b3=base64DecodeChars[b3];}while(ilen&&b3==-1);if(b3==-1){break;}buf.write(((b2&0x0f)4)|((b3&0x3c)2));
/b4/do{b4=data[i++];if(b4==61){returnbuf.toByteArray();}b4=base64DecodeChars[b4];}while(ilen&&b4==-1);if(b4==-1){break;}buf.write(((b3&0x03)6)|b4);}returnbuf.toByteArray();}}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113Md5Util.java
publicclassMd5Util{/MD5加密字符串@paramsource要加密的字符串@return/publicstaticStringgetMD5(Stringsource){Strings=null;charhexDigits[]={//用来将字节转换成16进制表示的字符'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};try{java.security.MessageDigestmd=java.security.MessageDigest.getInstance("MD5");if(source==null||"".equals(source)){returnnull;}md.update(source.getBytes());bytetmp[]=md.digest();//MD5的计算结果是一个128位的长整数,//用字节表示就是16个字节charstr[]=newchar[162];//每个字节用16进制表示的话,使用两个字符,//所以表示成16进制需要32个字符intk=0;//表示转换结果中对应的字符位置for(inti=0;i16;i++){//从第一个字节开始,对MD5的每一个字节//转换成16进制字符的转换bytebyte0=tmp[i];//取第i个字节str[k++]=hexDigits[byte04&0xf];//取字节中高4位的数字转换,////为逻辑右移,将符号位一起右移str[k++]=hexDigits[byte0&0xf];//取字节中低4位的数字转换}s=newString(str);//换后的结果转换为字符串
}catch(Exceptione){e.printStackTrace();}returns;}
/MD5加密byte数据@paramsource要加密字符串的byte数据@return/publicstaticStringgetMD5(byte[]source){Strings=null;charhexDigits[]={//用来将字节转换成16进制表示的字符'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};try{java.security.MessageDigestmd=java.security.MessageDigest.getInstance("MD5");md.update(source);bytetmp[]=md.digest();//MD5的计算结果是一个128位的长整数,//用字节表示就是16个字节charstr[]=newchar[162];//每个字节用16进制表示的话,使用两个字符,//所以表示成16进制需要32个字符intk=0;//表示转换结果中对应的字符位置for(inti=0;i16;i++){//从第一个字节开始,对MD5的每一个字节//转换成16进制字符的转换bytebyte0=tmp[i];//取第i个字节str[k++]=hexDigits[byte04&0xf];//取字节中高4位的数字转换,////为逻辑右移,将符号位一起右移str[k++]=hexDigits[byte0&0xf];//取字节中低4位的数字转换}s=newString(str);//换后的结果转换为字符串
}catch(Exceptione){e.printStackTrace();}returns;}}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778Encrypt.java
publicclassEncrypt{publicstaticbooleaninitialized=false;
publicstaticfinalStringALGORITHM="AES/ECB/PKCS7Padding";
/@paramStringstr要被加密的字符串@parambyte[]key加/解密要用的长度为32的字节数组(256位)密钥@returnbyte[]加密后的字节数组/publicstaticbyte[]Aes256Encode(Stringstr,byte[]key){initialize();byte[]result=null;try{Ciphercipher=Cipher.getInstance(ALGORITHM,"BC");SecretKeySpeckeySpec=newSecretKeySpec(key,"AES");//生成加密解密需要的Keycipher.init(Cipher.ENCRYPT_MODE,keySpec);result=cipher.doFinal(str.getBytes("UTF-8"));}catch(Exceptione){e.printStackTrace();}returnresult;}
/@parambyte[]bytes要被解密的字节数组@parambyte[]key加/解密要用的长度为32的字节数组(256位)密钥@returnString解密后的字符串/publicstaticStringAes256Decode(byte[]bytes,byte[]key){initialize();Stringresult=null;try{Ciphercipher=Cipher.getInstance(ALGORITHM,"BC");SecretKeySpeckeySpec=newSecretKeySpec(key,"AES");//生成加密解密需要的Keycipher.init(Cipher.DECRYPT_MODE,keySpec);byte[]decoded=cipher.doFinal(bytes);result=newString(decoded,"UTF-8");}catch(Exceptione){e.printStackTrace();}returnresult;}
publicstaticvoidinitialize(){if(initialized)return;//Security.addProvider(newBouncyCastleProvider());Security.addProvider(neworg.bouncycastle.jce.provider.BouncyCastleProvider());initialized=true;}}---------------------作者:FunHours2016来源:CSDN原文:https://blog.csdn.net/a250787181/article/details/79005227版权声明:本文为博主原创文章,转载请附上博文链接!

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

产品经理

手机 : 13312967497

擅长 : 小程序流量变现

扫码领取礼包

热门模板

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎