• 微信摇一摇红包


    微信摇一摇红包

    1、说明

    • 微信摇一摇红包官方说明地址:点击查看

    • 官方的说明不在赘述,有几点需注意:

    1. 摇一摇分为2种:

      1、普通红包,该红包只有1份,其中金额必须大于1元;如果小于1元,可以通过 红包预下单接口进行创建,但是,当创建红包活动的时候是不能够正确的添加的,会显示9001090错误即(录入的所有ticket都是无效ticket,可能原因为ticket重复使用,过期或金额不在1-1000元之间);一个用户只能领取一个;
      2、裂变红包,该红包可以分享给其他好友,分享的份数就是通过红包预下单接口创建的个数;其他好友可以领取。

    2. 接口注意事项:

      1、红包预下单接口 该接口可以每个字段必须填写;
      2、创建红包活动 该接口中的total数量需要大于在红包预下单设定的值,一般将total的值设置大些,这样在后续添加方便;
      3、创建红包活动,每一个用户该活动下只能领取1个红包,如果在进行摇一摇,虽然可以摇到页面,但是不能够摇到钱;
      4 、 录入红包信息,该接口中,ticket的值,就是红包的分数,与红包预下单创建的红包个数无关;需要特别注意;当只有一个ticket的值,被A用户领取了,那么B用户将不能够领取;若想要有多个用户领取,那么需要调用多次红包预下单该接口,用来创建ticket值,并赋予到红包活动中;

    2、 编写步骤

     1、编写`红包预下单接口`
     2、编写`创建红包活动`
     3、编写`录入红包信息`
    

    3、红包预下单接口

    /**
         * 接口名称:红包预下单接口<br>
         * @param
         *  total_amount  总金额--分<br>
         *  total_num 红包发放总人数<br>
         *  wishing 红包祝福语<br>
         *  remark 备注信息<br>
         *  act_name 活动名称<br>
         *  send_name 商户号名称<br>
         * @auto thero
         */
        public String createRedPackage(Integer total_amount,Integer total_num,String wishing,String remark,String act_name,String send_name){
            ShakeRedPacakge shakeRedPacakge = new ShakeRedPacakge();
            //随机字符串
            shakeRedPacakge.setNonce_str(CommonUtil.getNonceStr());
            //商户号
            shakeRedPacakge.setMch_id("商户号");
            //商户订单号
            String mch_billno = "商户号"+DateHelper.getFormatStringyyyyMMddHHmmss(new Date()) + ShakeRedPackageInter.createCode().toString();
            shakeRedPacakge.setMch_billno(mch_billno);
            //公众账号appid
            shakeRedPacakge.setWxappid("这里填写appid");
            //商户号名称
            shakeRedPacakge.setSend_name(send_name);
            //红包类型 NORMAL-普通红包;GROUP-裂变红包(可分享红包给好友,无关注公众号能力)
            shakeRedPacakge.setHb_type("NORMAL");
            //总金额--分
            shakeRedPacakge.setTotal_amount(total_amount);
            //红包发放总人数
            shakeRedPacakge.setTotal_num(total_num);
            //红包金额设置方式--全部随机
            shakeRedPacakge.setAmt_type("ALL_RAND");
            //红包祝福语
            shakeRedPacakge.setWishing(wishing);
            //活动名称
            shakeRedPacakge.setAct_name(act_name);
            //备注信息
            shakeRedPacakge.setRemark(remark);
            //授权商户号
            shakeRedPacakge.setAuth_mchid("1000052601");
            //授权商户APPID
            shakeRedPacakge.setAuth_appid("wxbf42bd79c4391863");
            //风控设置
            shakeRedPacakge.setRisk_cntl("NORMAL");
            
            //拼接签名
            List<String> signParam = new ArrayList<String>();
            signParam.add("nonce_str");
            signParam.add("mch_billno");
            signParam.add("mch_id");
            signParam.add("wxappid");
            signParam.add("send_name");
            signParam.add("hb_type");
            signParam.add("total_amount");
            signParam.add("total_num");
            signParam.add("amt_type");
            signParam.add("wishing");
            signParam.add("act_name");
            signParam.add("remark");
            signParam.add("auth_mchid");
            signParam.add("auth_appid");
            signParam.add("risk_cntl");
            Collections.sort(signParam);
            StringBuffer sb = new StringBuffer();
            for(int i =0 ;i < signParam.size(); i++){
                String temp = signParam.get(i);
                sb.append(temp+"=");
                if("nonce_str".equals(temp)){
                    sb.append(shakeRedPacakge.getNonce_str());
                    sb.append("&");
                    continue;
                }
                if("mch_billno".equals(temp)){
                    sb.append(shakeRedPacakge.getMch_billno());
                    sb.append("&");
                    continue;
                }
                if("mch_id".equals(temp)){
                    sb.append(shakeRedPacakge.getMch_id());
                    sb.append("&");
                    continue;
                }
                if("wxappid".equals(temp)){
                    sb.append(shakeRedPacakge.getWxappid());
                    sb.append("&");
                    continue;
                }
                if("send_name".equals(temp)){
                    sb.append(shakeRedPacakge.getSend_name());
                    sb.append("&");
                    continue;
                }
                if("hb_type".equals(temp)){
                    sb.append(shakeRedPacakge.getHb_type());
                    sb.append("&");
                    continue;
                }
                if("total_amount".equals(temp)){
                    sb.append(shakeRedPacakge.getTotal_amount());
                    sb.append("&");
                    continue;
                }
                if("total_num".equals(temp)){
                    sb.append(shakeRedPacakge.getTotal_num());
                    sb.append("&");
                    continue;
                }
                if("amt_type".equals(temp)){
                    sb.append(shakeRedPacakge.getAmt_type());
                    sb.append("&");
                    continue;
                }
                if("wishing".equals(temp)){
                    sb.append(shakeRedPacakge.getWishing());
                    sb.append("&");
                    continue;
                }
                if("act_name".equals(temp)){
                    sb.append(shakeRedPacakge.getAct_name());
                    sb.append("&");
                    continue;
                }
                if("remark".equals(temp)){
                    sb.append(shakeRedPacakge.getRemark());
                    sb.append("&");
                    continue;
                }
                if("auth_mchid".equals(temp)){
                    sb.append(shakeRedPacakge.getAuth_mchid());
                    sb.append("&");
                    continue;
                }
                if("auth_appid".equals(temp)){
                    sb.append(shakeRedPacakge.getAuth_appid());
                    sb.append("&");
                    continue;
                }
                if("risk_cntl".equals(temp)){
                    sb.append(shakeRedPacakge.getRisk_cntl());
                    sb.append("&");
                    continue;
                }
            }
            //加密
            sb = new StringBuffer(sb.toString().substring(0, sb.toString().length()-1));
            sb.append("&key=这里替换key值");
            System.out.println("要加密的密文为:"+sb.toString());
            String sign = MD5(sb.toString()).toUpperCase();
            shakeRedPacakge.setSign(sign);
            
            StringBuffer hbpreOrderxml = new StringBuffer();
            hbpreOrderxml.append("<xml>");
            hbpreOrderxml.append("<nonce_str><![CDATA["+shakeRedPacakge.getNonce_str()+"]]></nonce_str>");
            hbpreOrderxml.append("<sign><![CDATA["+shakeRedPacakge.getSign()+"]]></sign>");
            hbpreOrderxml.append("<mch_billno><![CDATA["+shakeRedPacakge.getMch_billno()+"]]></mch_billno>");
            hbpreOrderxml.append("<mch_id><![CDATA["+shakeRedPacakge.getMch_id()+"]]></mch_id>");
            hbpreOrderxml.append("<wxappid><![CDATA["+shakeRedPacakge.getWxappid()+"]]></wxappid>");
            hbpreOrderxml.append("<send_name><![CDATA["+shakeRedPacakge.getSend_name()+"]]></send_name>");
            hbpreOrderxml.append("<hb_type><![CDATA["+shakeRedPacakge.getHb_type()+"]]></hb_type>");
            hbpreOrderxml.append("<total_amount><![CDATA["+shakeRedPacakge.getTotal_amount()+"]]></total_amount>");
            hbpreOrderxml.append("<total_num><![CDATA["+shakeRedPacakge.getTotal_num()+"]]></total_num>");
            hbpreOrderxml.append("<amt_type><![CDATA["+shakeRedPacakge.getAmt_type()+"]]></amt_type>");
            hbpreOrderxml.append("<wishing><![CDATA["+shakeRedPacakge.getWishing()+"]]></wishing>");
            hbpreOrderxml.append("<act_name><![CDATA["+shakeRedPacakge.getAct_name()+"]]></act_name>");
            hbpreOrderxml.append("<remark><![CDATA["+shakeRedPacakge.getRemark()+"]]></remark>");
            hbpreOrderxml.append("<auth_mchid><![CDATA["+shakeRedPacakge.getAuth_mchid()+"]]></auth_mchid>");
            hbpreOrderxml.append("<auth_appid><![CDATA["+shakeRedPacakge.getAuth_appid()+"]]></auth_appid>");
            hbpreOrderxml.append("<risk_cntl><![CDATA["+shakeRedPacakge.getRisk_cntl()+"]]></risk_cntl>");
            hbpreOrderxml.append("</xml>");
            
            //发送请求
            String hbpreOrderResultXML = httpsRequestKeyStore(ShakeRedPackageConstants.HBPREORDER, HttpsRequestUtil.POST, new String(hbpreOrderxml.toString().getBytes()));
            return hbpreOrderResultXML;
        }
    

    4、 创建红包活动

        public JSONObject addlotteryinfo(JSONObject param){
            String token = AccessToken.getTokenFromDB();
            String url = ShakeRedPackageConstants.ADDLOTTERYINFO.replace("ACCESSTOKEN", token);
            JSONObject result = HttpsRequestUtil.httpsRequest(url, HttpsRequestUtil.POST, param.toString());
            log.info("@@@@@@@@@@@@@@@@@@创建红包活动:"+result);
            return result;
        }
    

    5、红包查询接口

        /**
         * 接口名称:红包查询接口<br>
         * @auto thero
         */
        public JSONObject querylottery(String lotteryid){
            String token = AccessToken.getTokenFromDB();
            String url = ShakeRedPackageConstants.QUERYLOTTERY.replace("ACCESSTOKEN", token).replace("LOTTERYID", lotteryid);
            JSONObject result = HttpsRequestUtil.httpsRequest(url, HttpsRequestUtil.GET, null);
            log.info("@@@@@@@@@@@@@@@@@@查询红包信息为:"+result);
            return result;
        }
    

    4、辅助工具类

       /**
        * 创建随机数,用来补充商户订单号补足的位数
         * @return
         */
    public static String createCode(){
            char[] codeSequence={'0','1','2','3','4','5','6','7','8','9' };
            Random random = new Random(); 
                  String rand ="";
            for (int i = 0; i < 2; i++) {
                    int r = random.nextInt(10);
                    rand+= codeSequence[r];
            }
            return rand;
       }
       /**
        * md5加密
     * @param s
     * @return
     */
    public final static String MD5(String s) {
           char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};       
           try {
               byte[] btInput = s.getBytes();
               // 获得MD5摘要算法的 MessageDigest 对象
               MessageDigest mdInst = MessageDigest.getInstance("MD5");
               // 使用指定的字节更新摘要
               mdInst.update(btInput);
               // 获得密文
               byte[] md = mdInst.digest();
               // 把密文转换成十六进制的字符串形式
               int j = md.length;
               char str[] = new char[j * 2];
               int k = 0;
               for (int i = 0; i < j; i++) {
                   byte byte0 = md[i];
                   str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                   str[k++] = hexDigits[byte0 & 0xf];
               }
               return new String(str);
           } catch (Exception e) {
               e.printStackTrace();
               return null;
           }
       }
       /**
         * 需要证书,并发送https请求
         * 
         * @param requestUrl
         * @param requestMethod
         * @param outputStr
         * @return
         */
        public static String httpsRequestKeyStore(String requestUrl,
                String requestMethod, String outputStr) {
            StringBuffer buffer = new StringBuffer();
            KeyStore keyStore = null;
            CloseableHttpClient httpclient = null;
            try {
                keyStore = KeyStore.getInstance("PKCS12");
                FileInputStream instream = new FileInputStream(new File(
                        "D:\byc\work4\weixin\security\apiclient_cert.p12"));
                keyStore.load(instream, "这里填写商户号".toCharArray());
                instream.close();
            } catch (KeyStoreException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (CertificateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                log.debug("HTTPS request data set to :{}.", outputStr);
                // SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
                SSLContext sslcontext = SSLContexts.custom()
                        .loadKeyMaterial(keyStore, "这里填写商户号".toCharArray())
                        .build();
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                        sslcontext,
                        new String[] { "TLSv1" },
                        null,
                        SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
                httpclient = HttpClients.custom().setSSLSocketFactory(sslsf)
                        .build();
    
                HttpPost httpPost = new HttpPost(requestUrl);
                  StringEntity  reqEntity  = new StringEntity(outputStr,"UTF-8");
                 // 设置类型
                 reqEntity.setContentType("application/x-www-form-urlencoded");
                 httpPost.setEntity(reqEntity);
    
                CloseableHttpResponse response = httpclient.execute(httpPost);
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    BufferedReader bufferedReader = new BufferedReader(
                            new InputStreamReader(entity.getContent(), "UTF-8"));
                    String text;
                    while ((text = bufferedReader.readLine()) != null) {
                        buffer.append(text);
                    }
    
                }
                EntityUtils.consume(entity);
            } catch (KeyManagementException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (UnrecoverableKeyException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (KeyStoreException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return buffer.toString();
        }
    

    5、实体bean以及常量类

    Lottery 活动对象
    
    package com.xunclouds.shake.domain;
    
    
    public class Lottery {
        /**
         * 抽奖活动名称(选择使用模板时,也作为摇一摇消息主标题),最长6个汉字,12个英文字母。
         * */
        private String title;
        /**
         * 抽奖活动描述(选择使用模板时,也作为摇一摇消息副标题),最长7个汉字,14个英文字母。
         * */
        private String desc;
        /**
         * 抽奖开关。0关闭,1开启,默认为1
         * */
        private Integer onoff;
        /**
         *抽奖活动开始时间,unix时间戳,单位秒
         * */
        private Long begin_time;
        
        /**
         * 抽奖活动结束时间,unix时间戳,单位秒,红包活动有效期最长为91天
         */
        private Long expire_time;
        /**
         * 红包提供商户公众号的appid,需与预下单中的公众账号appid(wxappid)一致
         */
        private String sponsor_appid;
        /**
         * 红包总数,红包总数是录入红包ticket总数的上限,因此红包总数应该大于等于预下单时红包ticket总数。
         */
        private Long  total;
        /**
         * 红包关注界面后可以跳转到第三方自定义的页面
         */
        private String jump_url;
        /**
         * 开发者自定义的key,用来生成活动抽奖接口的签名参数,长度32位。使用方式见sign生成规则
         */
        private String key;
        public String getTitle() {
            return title;
        }
        public void setTitle(String title) {
            this.title = title;
        }
        public String getDesc() {
            return desc;
        }
        public void setDesc(String desc) {
            this.desc = desc;
        }
        public Integer getOnoff() {
            return onoff;
        }
        public void setOnoff(Integer onoff) {
            this.onoff = onoff;
        }
        public Long getBegin_time() {
            return begin_time;
        }
        public void setBegin_time(Long begin_time) {
            this.begin_time = begin_time;
        }
        public Long getExpire_time() {
            return expire_time;
        }
        public void setExpire_time(Long expire_time) {
            this.expire_time = expire_time;
        }
        public String getSponsor_appid() {
            return sponsor_appid;
        }
        public void setSponsor_appid(String sponsor_appid) {
            this.sponsor_appid = sponsor_appid;
        }
        public Long getTotal() {
            return total;
        }
        public void setTotal(Long total) {
            this.total = total;
        }
        public String getJump_url() {
            return jump_url;
        }
        public void setJump_url(String jump_url) {
            this.jump_url = jump_url;
        }
        public String getKey() {
            return key;
        }
        public void setKey(String key) {
            this.key = key;
        }
        
    }
    
      PrizeBucket 录入红包对象
    
    package com.xunclouds.shake.domain;
    
    
    import net.sf.json.JSONArray;
    import net.sf.json.JSONObject;
    
    public class PrizeBucket {
        /**
         * 红包抽奖id,来自addlotteryinfo返回的lottery_id
         */
        private String lottery_id;
        /**
         * 红包提供者的商户号,,需与预下单中的商户号mch_id一致
         */
        private String mchid;
        /**
         * 红包提供商户公众号的appid,需与预下单中的公众账号appid(wxappid)一致
         */
        private String sponsor_appid;
        /**
         * 红包ticket列表,如果红包数较多,可以一次传入多个红包,批量调用该接口设置红包信息。每次请求传入的红包个数上限为100
         */
        private JSONArray prize_info_list;
        
        public String getLottery_id() {
            return lottery_id;
        }
        public void setLottery_id(String lottery_id) {
            this.lottery_id = lottery_id;
        }
        public String getMchid() {
            return mchid;
        }
        public void setMchid(String mchid) {
            this.mchid = mchid;
        }
        public String getSponsor_appid() {
            return sponsor_appid;
        }
        public void setSponsor_appid(String sponsor_appid) {
            this.sponsor_appid = sponsor_appid;
        }
        public JSONArray getPrize_info_list() {
            return prize_info_list;
        }
        public void setPrize_info_list(JSONArray prize_info_list) {
            this.prize_info_list = prize_info_list;
        }
        
    }
    
    
      ShakeRedPacakge 录入红包对象
    
    package com.xunclouds.shake.domain;
    
    
    /**
     * 红包预下单接口 实体bean
     * @author thero
     *
     */
    public class ShakeRedPacakge {
        /**
         * 参数:随机字符串
         * 备注:随机字符串,不长于32位
         * */
        private String nonce_str;
        /**
         * 签名
         * 生成签名方式查看签名算法
         * */
        private String sign;
        /**
         * 商户订单号
         * 商户订单号(每个订单号必须唯一)组成: mch_id+yyyymmdd+10位一天内不能重复的数字。接口根据商户订单号支持重入, 如出现超时可再调用。
         * */
        private String mch_billno;
        /**
         * 商户号
         * 红包提供者的商户号(微信支付分配的商户号)
         * */
        private String mch_id;
        /**
         * 公众账号appid
         * 红包提供者公众号的appid,对应头像展示在红包页面
         * */
        private String wxappid;
        /**
         * 商户名称
         * 红包提供者名称,展示在红包页面
         * */
        private String send_name;
        /**
         *红包类型
         *NORMAL-普通红包;GROUP-裂变红包(可分享红包给好友,无关注公众号能力)。
         * */
        private String hb_type;
        /**
         * 总金额
         * 总付款金额,单位分
         * */
        private Integer total_amount;
        /**
         * 红包发放总人数
         * 红包发放总人数,即总共有多少人可以领到该组红包(包括分享者)。普通红包填1,裂变红包必须大于1。
         * */
        private Integer total_num;
        /**
         * 红包金额设置方式
         * 红包金额设置方式,只对裂变红包生效。ALL_RAND—全部随机
         * */
        private String amt_type;
        /**
         * 红包祝福语
         * 红包祝福语,展示在红包页面
         * */
        private String wishing;
        /**
         * 活动名称
         * 活动名称,在不支持原生红包的微信版本中展示在红包消息
         * */
        private String act_name;
        /**
         * 备注
         * 备注信息,在不支持原生红包的微信版本中展示在红包消息
         * */
        private String remark;
        /**
         * 授权商户号
         * 用于发红包时微信支付识别摇周边红包,所有开发者统一填写摇周边平台的商户号:1000052601
         * */
        private String auth_mchid;
        /**
         * 授权商户APPID
         * 用于发红包时微信支付识别摇周边红包,所有开发者统一填写摇周边平台的appid:wxbf42bd79c4391863
         * */
        private String auth_appid;
        /**
         * 风控设置
         * 用于管控接口风险。具体值如下:NORMAL—正常情况;IGN_FREQ_LMT—忽略防刷限制,强制发放;IGN_DAY_LMT—忽略单用户日限额限制,强制发放;IGN_FREQ_DAY_LMT—忽略防刷和单用户日限额限制,强制发放;如无特殊要求,请设为NORMAL。若忽略某项风险控制,可能造成资金损失,请谨慎使用。
         * */
        private String risk_cntl;
        public String getNonce_str() {
            return nonce_str;
        }
        public void setNonce_str(String nonce_str) {
            this.nonce_str = nonce_str;
        }
        public String getSign() {
            return sign;
        }
        public void setSign(String sign) {
            this.sign = sign;
        }
        public String getMch_billno() {
            return mch_billno;
        }
        public void setMch_billno(String mch_billno) {
            this.mch_billno = mch_billno;
        }
        public String getMch_id() {
            return mch_id;
        }
        public void setMch_id(String mch_id) {
            this.mch_id = mch_id;
        }
        public String getWxappid() {
            return wxappid;
        }
        public void setWxappid(String wxappid) {
            this.wxappid = wxappid;
        }
        public String getSend_name() {
            return send_name;
        }
        public void setSend_name(String send_name) {
            this.send_name = send_name;
        }
        public String getHb_type() {
            return hb_type;
        }
        public void setHb_type(String hb_type) {
            this.hb_type = hb_type;
        }
        public Integer getTotal_amount() {
            return total_amount;
        }
        public void setTotal_amount(Integer total_amount) {
            this.total_amount = total_amount;
        }
        public Integer getTotal_num() {
            return total_num;
        }
        public void setTotal_num(Integer total_num) {
            this.total_num = total_num;
        }
        public String getAmt_type() {
            return amt_type;
        }
        public void setAmt_type(String amt_type) {
            this.amt_type = amt_type;
        }
        public String getWishing() {
            return wishing;
        }
        public void setWishing(String wishing) {
            this.wishing = wishing;
        }
        public String getAct_name() {
            return act_name;
        }
        public void setAct_name(String act_name) {
            this.act_name = act_name;
        }
        public String getRemark() {
            return remark;
        }
        public void setRemark(String remark) {
            this.remark = remark;
        }
        public String getAuth_mchid() {
            return auth_mchid;
        }
        public void setAuth_mchid(String auth_mchid) {
            this.auth_mchid = auth_mchid;
        }
        public String getAuth_appid() {
            return auth_appid;
        }
        public void setAuth_appid(String auth_appid) {
            this.auth_appid = auth_appid;
        }
        public String getRisk_cntl() {
            return risk_cntl;
        }
        public void setRisk_cntl(String risk_cntl) {
            this.risk_cntl = risk_cntl;
        }
        
    }
    
    
  • 相关阅读:
    Linux查看系统版本信息和设置远程终端登录
    Linux环境下安装JDK
    Windows10修改Tomcat服务端口和一台机器部署多个Tomcat
    [转]C#反射-Assembly.Load、LoadFrom与LoadFile进阶
    【转】C# lock的使用
    一个简单的C++程序及说明
    插入排序
    堆排序
    选择排序
    快速排序
  • 原文地址:https://www.cnblogs.com/babyhhcsy/p/4516632.html
Copyright © 2020-2023  润新知