扫码点餐数据上报_渠道商-微信接口

官方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方法请求参数为空,但是也要有“ ”不然会解析失败),一定写好请求头中的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:关注一下本人公众号,每周都有新更新哦!

原文地址:https://www.cnblogs.com/guoxiaoyu/p/10528476.html