扫码点餐数据上报_渠道商-微信接口
官方api文档:https://files.cnblogs.com/files/guoxiaoyu/扫码点餐数据上报API_渠道商_v1.3.rar
使用算法:加密解密都不是使用的商户平台的API秘钥,一定要使用微信给自己的证书,一个是p12、cert.pem、key.pem(这个是自己使用方法的私钥ps:记得将里面的头和尾没用的信息去掉,只要里面的字符串把换行也去掉就可以),只有在下载证书后用的是apiV3秘钥解密密文的。ps:如果没有记得v3秘钥让微信给自己开通白名单,自己踩了个坑
1、sha256withrsa
/** * 加签 * * @param signData 需要签名的源数据 * @param privateKey 私钥(base64加密) * @return 加签后的签名 */ public static String sign(String signData, String privateKey) { try { PKCS8EncodedKeySpec PKCS8Key = new PKCS8EncodedKeySpec(org.apache.commons.codec.binary.Base64.decodeBase64(privateKey .getBytes())); KeyFactory key = KeyFactory.getInstance("RSA"); PrivateKey priKey = key.generatePrivate(PKCS8Key); Signature signature = Signature.getInstance("sha256withrsa"); signature.initSign(priKey); signature.update(signData.getBytes("UTF-8")); byte[] signed = signature.sign(); return new String(Base64.encodeBase64(signed)); } catch (Exception e) { e.printStackTrace(); } return null; }
2、AEAD_AES_256_GCM
1 /** 2 * 三个都是接口所给 3 * @param aad associatedData 固定字符串 4 * @param iv nonce 随机字符串 5 * @param cipherText cipherText 密文 6 * @return 7 * @throws Exception 8 */ 9 private static String aesgcmDecrypt(String aad, String iv, String cipherText) { 10 try { 11 final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE"); 12 SecretKeySpec key = new SecretKeySpec(AES_KEY.getBytes(), "AES");//AES_KEY为APIV3秘钥--如果秘钥错误,解密时会返回tag mismatch 13 GCMParameterSpec spec = new GCMParameterSpec(128, iv.getBytes()); 14 cipher.init(Cipher.DECRYPT_MODE, key, spec); 15 cipher.updateAAD(aad.getBytes()); 16 return new String(cipher.doFinal(Base64.getDecoder().decode(cipherText))); 17 } catch (Exception e) { 18 return "fail"; 19 } 20 }
3、sha256withrsa
1 /** 2 * 签名字符串 3 * 4 * @param content 需要签名的字符串 5 * @param sign 客户签名结果 6 * @param publicKeypath 公钥cert证书文件地址 ,也可以自己写纯证书字符串,方法自己可以截取 7 * @return 验签结果 8 */ 9 public static boolean verify(String content, String sign, String publicKeypath) { 10 try { 11 File cert = new File(publicKeypath); 12 FileInputStream fileInputStream = new FileInputStream(cert); 13 byte[] PublicKeyBytes = new byte[Integer.valueOf(String.valueOf(cert.length()))]; 14 fileInputStream.read(PublicKeyBytes); 15 X509Certificate certificate = X509Certificate.getInstance(PublicKeyBytes); 16 PublicKey pubKey = certificate.getPublicKey(); 17 System.out.println(new String(org.apache.commons.codec.binary.Base64.encodeBase64(pubKey.getEncoded()))); 18 Signature signature = Signature.getInstance("sha256withrsa"); 19 signature.initVerify(pubKey); 20 signature.update(content.getBytes("UTF-8")); 21 return signature.verify(org.apache.commons.codec.binary.Base64.decodeBase64(sign)); 22 } catch (Exception e) { 23 return false; 24 } 25 }
如果这些算法完事之后就是自己真正的业务逻辑了,以post接口方式为例(get方法请求参数为空,但是也要有“\n”不然会解析失败),一定写好请求头中的Auth串,写对了才可以将数据给微信方
1 HttpPost post = new HttpPost(HTTP_ADDRESS); 2 //生产签名串 3 long currentTimeMillis = System.currentTimeMillis()/1000; 4 String randomUUID = UUID.randomUUID().toString().replaceAll("-", ""); 5 StringBuffer signStr = new StringBuffer(); 6 signStr.append(HTTP_METHOD_SIGN).append(END_SYMBOL_SIGN) 7 .append(URL_SIGN).append(END_SYMBOL_SIGN) 8 .append(currentTimeMillis).append(END_SYMBOL_SIGN) 9 .append(randomUUID).append(END_SYMBOL_SIGN) 10 .append(paramJson).append(END_SYMBOL_SIGN); 11 //签名 12 String signature = RSAUtils.sign(signStr.toString(), privateKey); 13 //授权串 14 StringBuffer authStr = new StringBuffer(); 15 authStr.append(AUTHORIZATION_TYPE).append(" ").append("mchid=\"") 16 .append(MERCHANT_ID).append("\",nonce_str=\"").append(randomUUID) 17 .append("\",signature=\"").append(signature).append("\",timestamp=\"") 18 .append(currentTimeMillis).append("\",serial_no=\"").append(CER_SERIAL_NO).append("\""); 19 20 post.setHeader("Authorization", authStr.toString()); 21 post.setHeader("Content-Type", "application/json"); 22 post.setHeader("User-Agent", "curl/7.54.0"); 23 post.setHeader("Accept", "application/json"); 24 post.setEntity(new StringEntity(paramJson, Consts.UTF_8));
写个接口踩了好几个坑,比如秘钥写错、微信没有开白名单自己却不知道、参数写的不规范导致微信验签老失败。希望大家可以少才几个坑
有什么问题,博客回复太慢,可以加一下本人微信:请备注问题,谢谢!
编写不易,转载请写明出处,谢谢;
ps:关注一下本人公众号,每周都有新更新哦!