• 微信企业红包api接入


      项目描述:基于微信浏览器的H5页面,接入微信支付接口和微信红包接口

    一、接入前准备条件

    1.微信公众号

      需要基于已认证的微信公众号承载该H5页面。该条件默认已具备,本文重点为红包接口。

    2.微信支付商户平台

    2.1官方api文档,发放前准备事项,详细阅读!

    https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_3&index=2

    2.2重点内容解读

      1、在满足开通红包权限的前提条件下,在开通该权限时,微信支付平台需要操作人下载对应安全控件及证书,保证操作环境安全性!

      2、充值微信支付账号,大概意思是将银行中的钱预存到平台作为红包金池,已发放的红包金额将从该池中扣减。操作步骤见api文档。

      3、openid是微信用户在该公众号下的唯一标识,与微信号1对1映射,微信出于用户隐私考虑,使用虚拟id去关联微信用户,所以无法获取微信号。有这方面想法的同学趁早放弃...所以我们支付或发送红包使用openid即可。

      4、本文使用红包接口调用的方式实现红包发放功能,api文档中第五条相关参数设置可以略过!

    二、红包api接入

    1.官方api文档,发放普通红包

    https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3

    2.重点内容解读

    2.1证书问题

      根据证书使用说明.txt中的描述,JAVA后端为例,使用的证书是.p12格式

      

      windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的商户ID(如:10010000),在发送POST请求时一定要携带该证书的信息在请求中,具体见代码:

     1 /**
     2      *  url 请求url       
     3         xmlParam 请求参数       
     4         keyStorePath  本地证书路径
     5      */
     6     public static Map getMwebUrl(String url, String xmlParam, String keyStorePath) {
     7          StringBuffer message = new StringBuffer();
     8          String jsonStr = null;
     9           Map map = new HashMap();   
    10          try {
    11                 //商户id,证书的默认密码
    12                 String mchId = PropertyUtil.MERID;
    13                 KeyStore keyStore  = KeyStore.getInstance("PKCS12");
    14                //本地证书
    15                 FileInputStream instream = new FileInputStream(new File(keyStorePath));
    16                 keyStore.load(instream, mchId.toCharArray());
    17                 SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchId.toCharArray()).build();
    18                 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
    19                 CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
    20                 //注意这里是post
    21                 HttpPost httpost = new HttpPost(url);
    22                 httpost.setEntity(new StringEntity(xmlParam, "UTF-8"));
    23                 System.out.println("executing request" + httpost.getRequestLine());
    24                 CloseableHttpResponse response = httpclient.execute(httpost);
    25                
    26                 try {
    27                     HttpEntity entity = response.getEntity();
    28                     System.out.println(response.getStatusLine());
    29                     if (entity != null) {
    30                         System.out.println("Response content length: " + entity.getContentLength());
    31                         BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(),"UTF-8"));
    32                         //以下为返回参数的处理,根据需求自行修改
    33                         String text;
    34                         while ((text = bufferedReader.readLine()) != null) {
    35                             message.append(text);
    36                         }
    37                         jsonStr = message.toString();
    38                         map = XMLUtils.parseXmlToList(jsonStr);
    39                     }
    40                     EntityUtils.consume(entity);
    41                 } catch (IOException e) {
    42                     e.printStackTrace();
    43                 } finally {
    44                     response.close();
    45                 }
    46             } catch (Exception e1) {
    47                 e1.printStackTrace();
    48             } 
    49             return map;
    50     }

    2.2请求参数问题

      2019年8月该api请求必填参数为12个,详见api文档,这里只有签名sign字段需要说明,其余字段非常直观!

    签名

    详见签名生成算法,以下为sign参数生成代码,仅供参考

     1 /**
     2     parameters 将所有非空参数装载进SortedMap
     3 */
     4 public static String createSign(SortedMap<String,Object> parameters){
     5         StringBuffer sb = new StringBuffer();
     6         //所有参与传参的参数按照accsii排序(升序)
     7         Set es = parameters.entrySet();
     8         Iterator it = es.iterator();
     9         while(it.hasNext()) {
    10             Map.Entry entry = (Map.Entry)it.next();
    11             String k = (String)entry.getKey();
    12             Object v = entry.getValue();
    13             //不能包含sign属性及key属性,不需要CDATA模板
    14             if(null != v && !"".equals(v)
    15                     && !"sign".equals(k) && !"key".equals(k)) {
    16                 sb.append(k + "=" + v + "&");
    17             }
    18         }
    19         //商户平台设置的密钥key
    20         //◆ key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
    21         sb.append("key=" + PropertyUtil.SIGNKEY );
    22         String sign = "";
    23         try {
    24             //MD5加密及中文支持,并转换成全大写
    25             sign = MD5Utils.getMessageDigest(sb.toString().getBytes("utf-8")).toUpperCase();
    26         } catch (UnsupportedEncodingException e) {
    27             e.printStackTrace();
    28         }
    29         return sign;
    30     }

      补充 :nonce_str参数,随机字符串的生成算法

     1 import java.security.MessageDigest;
     2 public class MD5Utils {
     3     public final static String getMessageDigest(byte[] buffer) {
     4         char hexDigits[] = 
     5         { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
     6         try {
     7             MessageDigest mdTemp = MessageDigest.getInstance("MD5");
     8             mdTemp.update(buffer);
     9             byte[] md = mdTemp.digest();
    10             int j = md.length;
    11             char str[] = new char[j * 2];
    12             int k = 0;
    13             for (int i = 0; i < j; i++) {
    14                 byte byte0 = md[i];
    15                 str[k++] = hexDigits[byte0 >>> 4 & 0xf];
    16                 str[k++] = hexDigits[byte0 & 0xf];
    17             }
    18             return new String(str);
    19         } catch (Exception e) {
    20             return null;
    21         }
    22     }
    23 }

    三、总结

      在接触微信系列的内容之前,接收各种对微信api的吐槽,但是接触了之后发现,他们说的还真对...(甩梗,咳咳)相较阿里的api腾讯的参数描述、步骤指引等不够明确,但仍在可接受的范围之内,退一步讲,以前我没得选,现在也没得选!

  • 相关阅读:
    PHP中的call_user_func()与call_user_func_array()简单理解
    PHP实现多继承
    PHP实现多继承 trait 语法
    PHP几种常见魔术方法与魔术变量解析
    tp5 的nginx配置
    PHP 扩展 trie-tree, swoole过滤敏感词方案
    PHP Ajax跨域问题解决办法
    附加个人作业
    学完软工的感受
    团队介绍
  • 原文地址:https://www.cnblogs.com/lijizhi/p/11422569.html
Copyright © 2020-2023  润新知