前言

用户邀请朋友购买公众号产品,购买成功之后工会总好将给邀请人指定百分比的佣金,通过公众号红包的形式下发的邀请人;
此处整理将相关代码都集中在了一起,真正开发中建议此写法;
代码中的相关参数如有不明白可参阅官方文档

公众号发送红包

此功能实现需公众号开通微信支付功能;
并采集微信商户平台信息,商户号,支付秘钥及证书申请下载

public class TextJkx {
    private static final Logger LOGGER = LoggerFactory.getLogger(WinxinUtil.class);
    // 发放红包接口URL
    private static final String REDENVELOPE_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
    // 证书路径
    private static final String CERTIFICATE_URL = "C:\\tuikuan\\cert\\apiclient_cert.p12";
    // 商户号
    private static final String MCH_ID = "mch_id";
    // 公众号appid
    private static final String APPID = "appid";
    // 支付秘钥
    private static final String PAY_KEY = "pay_key";

    public static void main(String[] args) throws Exception {
        PayUtil payUtil = new PayUtil();
        String uuid = UUIDUtil.getUUID();
        String orderIdByTime = WinxinUtil.getOrderIdByTime();
        // 活动标题
        String sTitle = "";
        payUtil.setMch_id(MCH_ID);
        payUtil.setPayKey(PAY_KEY);
        payUtil.setAppid(APPID);
        payUtil.setNonce_str(uuid);
        payUtil.setMch_billno(orderIdByTime);
        // 公众号名称
        payUtil.setSend_name("send_name");
        // 红包接收人openid
        payUtil.setRe_openid("re_openid");
        // 金额为分,福利红包为分享信息金额的10%
        BigDecimal bignum1 = new BigDecimal(String.valueOf(100));
        BigDecimal bignum2 = new BigDecimal("100");
        BigDecimal bignum3 = bignum1.multiply(bignum2); //乘法运算
        int total_amount = bignum3.intValue() / 10;
        payUtil.setTotal_amount(total_amount);
        payUtil.setTotal_num(1);
        payUtil.setWishing("感谢您参加XXX活动" + sTitle);
        payUtil.setAct_name(sTitle);
        payUtil.setRemark(Constants.RED_ENVELOPE_REMARK);
        // 服务器ip
        payUtil.setSpbill_create_ip("127.0.0.1");

        // 给用户发现金红包
        Map map = redEnvelope(payUtil);
        if (StringUtils.equals(WXPayConstants.SUCCESS, map.get("result_code").toString()) && StringUtils.equals(WXPayConstants.SUCCESS, map.get("return_code").toString())) {
            // 红包派发成功,业务处理逻辑 TODO
        } else {
            // 红包派发失败
        }
    }

    /**
     * @Description: 给用户发现金红包
     * @Author: Mr.Jkx
     * @date: 2019/11/12 11:06
     * 参考链接:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3
     */
    public static Map redEnvelope(PayUtil payUtil) throws Exception {
        //生成的随机字符串
        String stringA = "act_name=" + payUtil.getAct_name()
                + "&client_ip=" + payUtil.getSpbill_create_ip()
                + "&mch_billno=" + payUtil.getMch_billno()
                + "&mch_id=" + payUtil.getMch_id()
                + "&nonce_str=" + payUtil.getNonce_str()
                + "&re_openid=" + payUtil.getRe_openid()
                + "&remark=" + payUtil.getRemark()
                + "&send_name=" + payUtil.getSend_name()
                + "&total_amount=" + payUtil.getTotal_amount()
                + "&total_num=" + payUtil.getTotal_num()
                + "&wishing=" + payUtil.getWishing()
                + "&wxappid=" + payUtil.getAppid()
                + "&key=" + payUtil.getPayKey();
        String sign = Md5Util.md5(stringA).toUpperCase();

        String xml = "<xml>" +
                "   <act_name>" + payUtil.getAct_name() + "</act_name>" +
                "   <client_ip>" + payUtil.getSpbill_create_ip() + "</client_ip>" +
                "   <mch_billno>" + payUtil.getMch_billno() + "</mch_billno>" +
                "   <mch_id>" + payUtil.getMch_id() + "</mch_id>" +
                "   <nonce_str>" + payUtil.getNonce_str() + "</nonce_str>" +
                "   <re_openid>" + payUtil.getRe_openid() + "</re_openid>" +
                "   <remark>" + payUtil.getRemark() + "</remark>" +
                "   <send_name>" + payUtil.getSend_name() + "</send_name>" +
                "   <total_amount>" + payUtil.getTotal_amount() + "</total_amount>" +
                "   <total_num>" + payUtil.getTotal_num() + "</total_num>" +
                "   <wishing>" + payUtil.getWishing() + "</wishing>" +
                "   <wxappid>" + payUtil.getAppid() + "</wxappid>" +
                "   <sign>" + sign + "</sign>" +
                "</xml> ";

        LOGGER.info("----现金红包-----请求XML数据:{}", xml);
        String result = payOfCertificate(REDENVELOPE_URL, xml);
        // 将解析结果存储在HashMap中
        Map map = doXMLParse(result);
        LOGGER.info("----现金红包-----回执数据:{}", map);
        return map;
    }

    /**
     * @Description: 加载证书 发送请求
     * @Author: Mr.Jkx
     * @Date: 2019/4/10 10:06
     */
    public static String payOfCertificate(String url, String data) throws Exception {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        FileInputStream is = new FileInputStream(new File(CERTIFICATE_URL));
        try {
            keyStore.load(is, MCH_ID.toCharArray());
        } finally {
            is.close();
        }
        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, MCH_ID.toCharArray()).build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslcontext,
                new String[]{"TLSv1"},
                null,
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
        );
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        try {
            HttpPost httpost = new HttpPost(url); // 设置响应头信息
            httpost.addHeader("Connection", "keep-alive");
            httpost.addHeader("Accept", "*/*");
            httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            httpost.addHeader("Host", "api.mch.weixin.qq.com");
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");
            httpost.addHeader("Cache-Control", "max-age=0");
            httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
            httpost.setEntity(new StringEntity(data, "UTF-8"));
            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();

                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
                EntityUtils.consume(entity);
                return jsonStr;
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }

    /**
     * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
     *
     * @param strxml
     * @return
     */
    public static Map doXMLParse(String strxml) throws Exception {
        if (null == strxml || "".equals(strxml)) {
            return null;
        }
        Map m = new HashMap();
        InputStream in = String2Inputstream(strxml);
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(in);
        Element root = doc.getRootElement();
        List list = root.getChildren();
        Iterator it = list.iterator();
        while (it.hasNext()) {
            Element e = (Element) it.next();
            String k = e.getName();
            String v = "";
            List children = e.getChildren();
            if (children.isEmpty()) {
                v = e.getTextNormalize();
            } else {
                v = getChildrenText(children);
            }
            m.put(k, v);
        }
        //关闭流
        in.close();
        return m;
    }

    /**
     * 获取子结点的xml
     *
     * @param children
     * @return String
     */
    public static String getChildrenText(List children) {
        StringBuffer sb = new StringBuffer();
        if (!children.isEmpty()) {
            Iterator it = children.iterator();
            while (it.hasNext()) {
                Element e = (Element) it.next();
                String name = e.getName();
                String value = e.getTextNormalize();
                List list = e.getChildren();
                sb.append("<" + name + ">");
                if (!list.isEmpty()) {
                    sb.append(getChildrenText(list));
                }
                sb.append(value);
                sb.append("</" + name + ">");
            }
        }

        return sb.toString();
    }

    public static InputStream String2Inputstream(String str) {
        return new ByteArrayInputStream(str.getBytes());
    }
}

作者能力有限,如有问题欢迎批评指正!!!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐