微信公众号企业付款到零钱

 //企业付款到零钱
    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("\n|\r", "");
        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;
        }

    }

 

 

 

 

 
posted @ 2019-09-10 15:30  tomingto  阅读(2546)  评论(0编辑  收藏  举报