zoukankan      html  css  js  c++  java
  • 扫码点餐数据上报_渠道商-微信接口

    官方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:关注一下本人公众号,每周都有新更新哦!

  • 相关阅读:
    selenium+phantomjs爬取bilibili
    使用 python 开发 Web Service
    OBIEE 立方刷新的问题
    解析OracleOLAP使用MView刷新Cube
    Codeforces Round #755 (Div. 2, based on Technocup 2022 Elimination Round 2)(CF1589)题解
    Codeforces Round #754 (Div. 2)(CF1605)题解
    完美解读Linux中文件系统的目录结构
    C#中获取程序当前路径的集中方法
    30个优秀.net在线学习资源站点
    如何删除windows service(转帖)
  • 原文地址:https://www.cnblogs.com/guoxiaoyu/p/10528476.html
Copyright © 2011-2022 走看看