公衆號下發紅包接口實現(java)

前言

用戶邀請朋友購買公衆號產品,購買成功之後工會總好將給邀請人指定百分比的佣金,通過公衆號紅包的形式下發的邀請人;
此處整理將相關代碼都集中在了一起,真正開發中建議此寫法;
代碼中的相關參數如有不明白可參閱官方文檔

公衆號發送紅包

此功能實現需公衆號開通微信支付功能;
並採集微信商戶平臺信息,商戶號,支付祕鑰及證書申請下載

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());
    }
}

作者能力有限,如有問題歡迎批評指正!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章