zoukankan      html  css  js  c++  java
  • 微信公众号企业付款到零钱

     //企业付款到零钱
        public Result returnWechatMoney(HttpServletRequest request, String money, String openId) throws Exception {
            //1.0 拼凑企业支付需要的参数
            //2.0 生成map集合
            Map<String, String> params = new HashMap<>();
            params.put("mch_appid", WXPayConfig.APPID);//微信公众号的appid
    params.put("mchid", WXPayConfig.mch_id);//商户号
    params.put("nonce_str", WXPayUtil.generateNonceStr());//随机生成后数字,保证安全性
    params.put("partner_trade_no", WXPayUtil.getorderid());//生成商户订单号
    params.put("openid", openId);// 支付给用户openid params.put("check_name", "NO_CHECK");//是否验证真实姓名呢
    params.put("re_user_name", "邻里用户");//收款用户姓名
    params.put("amount", money);//企业付款金额,单位为分
    params.put("desc", "退还篮子奖励金/收益提现");//企业付款操作说明信息。必填。
    params.put("spbill_create_ip", WXPayUtil.getAddrIp(request));//调用接口的机器Ip地址 //3.0 生成自己的签名 try { String sign = WXPayUtil.generateSignature(params, NowData.PATERNERKEY);//签名 params.put("sign", sign);//封装退款对象 String orderxml = WXPayUtil.mapToXml(params); //将数据转成XML格式 String ru = CertHttpUtil.postData("https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers",orderxml, WXPayConfig.mch_id, WXPayConfig.certificate_url);//退还零钱 Map<String, String> returnMap = WXPayUtil.xmlToMap(ru);//接口返回数据 if (returnMap.containsKey("result_code") && returnMap.get("result_code").equals("SUCCESS")) { return new Result(true, StatusCode.OK, "企业付款到零钱成功。"); } else if (returnMap.containsKey("err_code") && returnMap.get("err_code").equals("AMOUNT_LIMIT")) {//商户金额不足 return new Result(false, StatusCode.AMOUNT_LIMIT, "商户余额不足,请联系相关人员处理。"); } else if (returnMap.containsKey("err_code") && returnMap.get("err_code").equals("SENDNUM_LIMIT")) {//该用户今日付款次数超过限制 return new Result(false, StatusCode.SENDNUM_LIMIT, "该用户今日付款次数超过限制,如有需要请登录微信支付商户平台更改API安全配置."); } else if (returnMap.containsKey("err_code") && returnMap.get("err_code").equals("OPENID_ERROR")) { return new Result(false, StatusCode.OPENID_ERROR, "openid与商户appid不匹配."); } else if (returnMap.containsKey("err_code") && returnMap.get("err_code").equals("MONEY_LIMIT")) {//已达到付款给此用户额度上限. return new Result(false, StatusCode.MONEY_LIMIT, "已达到付款给此用户额度上限."); } else { return new Result(false, StatusCode.ERROR, "企业付款到零钱出现未知错误。"); } } catch (Exception e) { throw e; } }
    //获取机器ip地址
    public static String getAddrIp(HttpServletRequest req) {
            String ip = req.getHeader("x-forwarded-for");
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = req.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = req.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = req.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = req.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = req.getRemoteAddr();
            }
            System.out.println("--------------ip----------" + ip);
            return ip;
        }
    
    /**
     * 生成签名
     *
     * @param data 待签名数据
     * @param key  API密钥
     * @return 签名
     */
    public static String generateSignature(final Map<String, String> data, String key) throws Exception {
        return generateSignature(data, key, SignType.MD5);
    }
    
    /**
     * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
     *
     * @param data     待签名数据
     * @param key      API密钥
     * @param signType 签名方式
     * @return 签名
     */
    public static String generateSignature(final Map<String, String> data, String key, SignType signType) throws Exception {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (k.equals(WXPayConstants.FIELD_SIGN)) {
                continue;
            }
            if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名
                sb.append(k).append("=").append(data.get(k).trim()).append("&");
        }
        sb.append("key=").append(key);
     
        if (SignType.MD5.equals(signType)) {
            return MD5(sb.toString()).toUpperCase();
        } else if (SignType.HMACSHA256.equals(signType)) {
            return HMACSHA256(sb.toString(), key);
        } else {
            throw new Exception(String.format("Invalid sign_type: %s", signType));
        }
    }
    /**
         * 将Map转换为XML格式的字符串
         *
         * @param data Map类型数据
         * @return XML格式的字符串
         * @throws Exception
         */
        public static String mapToXml(Map<String, String> data) throws Exception {
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            org.w3c.dom.Document document = documentBuilder.newDocument();
            org.w3c.dom.Element root = document.createElement("xml");
            document.appendChild(root);
            for (String key : data.keySet()) {
                String value = data.get(key);
                if (value == null) {
                    value = "";
                }
                value = value.trim();
                org.w3c.dom.Element filed = document.createElement(key);
                filed.appendChild(document.createTextNode(value));
                root.appendChild(filed);
            }
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer transformer = tf.newTransformer();
            DOMSource source = new DOMSource(document);
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");//ISO8859-1
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            StringWriter writer = new StringWriter();
            StreamResult result = new StreamResult(writer);
            transformer.transform(source, result);
            String output = writer.getBuffer().toString(); //.replaceAll("
    |
    ", "");
            try {
                writer.close();
            } catch (Exception ex) {
            }
            return output;
        }
    package WXPay;
     
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.security.KeyStore;
     
    import javax.net.ssl.SSLContext;
     
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.conn.ssl.SSLContexts;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
     
    /**
     * 获取微信apiclient_cert.p12证书
     */
    @SuppressWarnings("deprecation")
    public class CertHttpUtil {
     
        private static int socketTimeout = 10000;// 连接超时时间,默认10秒
        private static int connectTimeout = 30000;// 传输超时时间,默认30秒
        private static RequestConfig requestConfig;// 请求器的配置
        private static CloseableHttpClient httpClient;// HTTP请求器
     
        /**
         * 通过Https往API post xml数据
         *
         * @param url API地址
         * @param xmlObj 要提交的XML数据对象
        * @param mchId 商户ID
        * @param certPath 证书位置
         * @return
         */
        public static String postData(String url, String xmlObj, String mchId, String certPath) {
            // 加载证书
            try {
                initCert(mchId, certPath);
            } catch (Exception e) {
                e.printStackTrace();
            }
            String result = null;
            HttpPost httpPost = new HttpPost(url);
            // 得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
            StringEntity postEntity = new StringEntity(xmlObj, "UTF-8");
            httpPost.addHeader("Content-Type", "text/xml");
            httpPost.setEntity(postEntity);
            // 根据默认超时限制初始化requestConfig
            requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
            // 设置请求器的配置
            httpPost.setConfig(requestConfig);
            try {
                HttpResponse response = null;
                try {
                    response = httpClient.execute(httpPost);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                HttpEntity entity = response.getEntity();
                try {
                    result = EntityUtils.toString(entity, "UTF-8");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } finally {
                httpPost.abort();
            }
            return result;
        }
     
        /**
         * 加载证书
         *
         * @param mchId 商户ID
         * @param certPath 证书位置
         * @throws Exception
         */
        private static void initCert(String mchId, String certPath) throws Exception {
            // 证书密码,默认为商户ID
            String key = mchId;
            // 证书的路径
            String path = certPath;
            // 指定读取证书格式为PKCS12
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            // 读取本机存放的PKCS12证书文件
            FileInputStream instream = new FileInputStream(new File(path));
            try {
                // 指定PKCS12的密码(商户ID)
                keyStore.load(instream, key.toCharArray());
            } finally {
                instream.close();
            }
            SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build();
            SSLConnectionSocketFactory sslsf =
                    new SSLConnectionSocketFactory(sslcontext, new String[] {"TLSv1"}, null,
                            SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        }
    }
       /**
         * XML格式字符串转换为Map
         *
         * @param strXML XML字符串
         * @return XML数据转换后的Map
         * @throws Exception
         */
        public static Map<String, String> xmlToMap(String strXML) throws Exception {
            try {
                Map<String, String> data = new HashMap<String, String>();
                DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
                InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
                org.w3c.dom.Document doc = documentBuilder.parse(stream);
                doc.getDocumentElement().normalize();
                NodeList nodeList = doc.getDocumentElement().getChildNodes();
                for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                    Node node = nodeList.item(idx);
                    if (node.getNodeType() == Node.ELEMENT_NODE) {
                        org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                        data.put(element.getNodeName(), element.getTextContent());
                    }
                }
                try {
                    stream.close();
                } catch (Exception ex) {
                    // do nothing
                }
                return data;
            } catch (Exception ex) {
                WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
                throw ex;
            }
    
        }
     
    境随心转而悦,心随境转而烦
  • 相关阅读:
    JAVA_SE基础——47.接口
    抽象类和接口的区别[精华版]
    JAVA_SE基础——46.引用数据类型变量.值交换[独家深入解析]
    JAVA_SE基础——45.基本类型变量.值交换[独家深入解析]
    第一个Spring程序
    三层架构和MVC的区别
    Spring 概述及IOC理论推导
    Mybatis之缓存
    Mybatis之动态SQL
    Mybatis之一对多和多对一处理
  • 原文地址:https://www.cnblogs.com/tomingto/p/11497717.html
Copyright © 2011-2022 走看看