package com.xzx.gc.role.service;  
 | 
  
 | 
import org.apache.http.HttpEntity;  
 | 
import org.apache.http.client.ClientProtocolException;  
 | 
import org.apache.http.client.methods.CloseableHttpResponse;  
 | 
import org.apache.http.client.methods.HttpPost;  
 | 
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;  
 | 
import org.apache.http.entity.StringEntity;  
 | 
import org.apache.http.impl.client.CloseableHttpClient;  
 | 
import org.apache.http.impl.client.HttpClients;  
 | 
import org.apache.http.ssl.SSLContexts;  
 | 
import org.apache.http.util.EntityUtils;  
 | 
import org.jdom2.Document;  
 | 
import org.jdom2.Element;  
 | 
import org.jdom2.input.SAXBuilder;  
 | 
import org.slf4j.Logger;  
 | 
import org.slf4j.LoggerFactory;  
 | 
  
 | 
import javax.net.ssl.SSLContext;  
 | 
import java.io.*;  
 | 
import java.security.KeyStore;  
 | 
import java.security.MessageDigest;  
 | 
import java.util.*;  
 | 
  
 | 
public class WxPayService {  
 | 
  
 | 
    static Logger log = LoggerFactory.getLogger(WxPayService.class);  
 | 
  
 | 
    void index(){  
 | 
        String currTime = System.currentTimeMillis()+"";  
 | 
        //8位日期  
 | 
        String strTime = currTime.substring(8, currTime.length());  
 | 
        //四位随机数  
 | 
        String strRandom = (Math.random()*5+1)*1000 + "";  
 | 
        String str=currTime.substring(0, currTime.length()-6) + strRandom;  
 | 
        //10位序列号,可以自行调整。  
 | 
        String nonce_str=strTime;//随机字符串  
 | 
        String mch_id="1546567611";//商户号  
 | 
        String mch_billno=str;//商户订单号  
 | 
        String wxappid="wx6d7dfd9073dfa875";//公众账号appid  
 | 
        String send_name="shanghuming";//商户名称(微信红包发送者名称,最好用英文)  
 | 
        String re_openid="4w5uj7RaLq5S1twuflFcM8k";//用户openId  
 | 
        String total_amount="1";//付款金额  
 | 
        int total_num=1;//红包发放总人数  
 | 
        String wishing="happy";//红包祝福语  
 | 
        String client_ip="192.168.1.0";//ip地址  
 | 
        String act_name="ceshiactivity";//活动名称  
 | 
        String remark="ceshi";  
 | 
        String scene_id="PRODUCT_5";//场景id  
 | 
        String key="QUJvGnZT17N4TAQHISnST6mqLJbaAM5F";//商户号API密钥  
 | 
        SortedMap<String, String> packageParams = new TreeMap<>();  
 | 
        packageParams.put("act_name", act_name);  
 | 
        packageParams.put("client_ip", client_ip);  
 | 
        packageParams.put("mch_billno", mch_billno);  
 | 
        packageParams.put("mch_id", mch_id);  
 | 
        packageParams.put("nonce_str",nonce_str);  
 | 
        packageParams.put("remark", remark);  
 | 
        packageParams.put("re_openid", re_openid);  
 | 
        packageParams.put("send_name", send_name);  
 | 
        packageParams.put("scene_id", scene_id);  
 | 
        packageParams.put("total_amount", total_amount+"");  
 | 
        packageParams.put("total_num", total_num+"");  
 | 
        packageParams.put("wishing", wishing);  
 | 
        packageParams.put("wxappid", wxappid);  
 | 
        //生成签名  
 | 
        String sign = createSign(packageParams,key,"UTF-8");  
 | 
        String xmlTest="<xml>"+  
 | 
                "<act_name>"+act_name+"</act_name>"+  
 | 
                "<client_ip>"+client_ip+"</client_ip>"+  
 | 
                "<mch_billno>"+mch_billno+"</mch_billno>"+  
 | 
                "<mch_id>"+mch_id+"</mch_id>"+  
 | 
                "<nonce_str>"+nonce_str+"</nonce_str>"+  
 | 
                "<remark>"+remark+"</remark>"+  
 | 
                "<re_openid>"+re_openid+"</re_openid>"+  
 | 
                "<send_name>"+send_name+"</send_name>"+  
 | 
                "<scene_id>"+scene_id+"</scene_id>"+  
 | 
                "<total_amount>"+total_amount+"</total_amount>"+  
 | 
                "<total_num>"+total_num+"</total_num>"+  
 | 
                "<wxappid>"+wxappid+"</wxappid>"+  
 | 
                "<wishing>"+wishing+"</wishing>"+  
 | 
                "<sign>"+sign+"</sign>"+  
 | 
                "</xml>";  
 | 
        System.out.println(xmlTest);  
 | 
        String notify_url="https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";  
 | 
        String prepay_id="";  
 | 
        try {  
 | 
            prepay_id =reqPost(notify_url, xmlTest);  
 | 
            if(prepay_id.contains("成功")){  
 | 
                log.info("================支付成功==============");  
 | 
            }else{  
 | 
                log.info("================支付失败==================");  
 | 
            }  
 | 
        } catch (Exception e1) {  
 | 
            e1.printStackTrace();  
 | 
        }  
 | 
  
 | 
    }  
 | 
  
 | 
  
 | 
    public String createSign(SortedMap<String, String> paraMap,String key,String charset) {  
 | 
        StringBuffer sb = new StringBuffer();  
 | 
        Set es = paraMap.entrySet();  
 | 
        Iterator it = es.iterator();  
 | 
        while (it.hasNext()) {  
 | 
            Map.Entry entry = (Map.Entry) it.next();  
 | 
            String k = (String) entry.getKey();  
 | 
            String v = (String) entry.getValue();  
 | 
            if (null != v && !"".equals(v) && !"sign".equals(k)  
 | 
                    && !"key".equals(k)) {  
 | 
                sb.append(k + "=" + v + "&");  
 | 
            }  
 | 
        }  
 | 
        sb.append("key=" + key);  
 | 
        System.out.println("===========签名参数====="+sb.toString());  
 | 
        String sign = md5Password(sb.toString()).toUpperCase();  
 | 
        // String sign = MD5Util.encode(sb.toString()).toUpperCase();  
 | 
        System.out.println("===========生成的签名是====="+sign);  
 | 
        return sign;  
 | 
  
 | 
    }  
 | 
  
 | 
    /**  
 | 
     * 生成32位md5码  
 | 
     *  
 | 
     * @param key  
 | 
     * @return  
 | 
     */  
 | 
    public static String md5Password(String key) {  
 | 
        char hexDigits[] = {  
 | 
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'  
 | 
        };  
 | 
        try {  
 | 
            byte[] btInput = key.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) {  
 | 
            return null;  
 | 
        }  
 | 
    }  
 | 
  
 | 
  
 | 
  
 | 
    String reqPost(String url,String xmlParam) throws Exception{  
 | 
        KeyStore keyStore  = KeyStore.getInstance("PKCS12");  
 | 
        //读取商户证书(我下载下来的证书保存到D盘,根据自己实际情况填写)  
 | 
        // FileInputStream instream = new FileInputStream(new File("D:/10016225.p12"));  
 | 
        try (FileInputStream instream = new FileInputStream(new File("D:/apiclient_cert.p12"))){  
 | 
            keyStore.load(instream, "1546567611".toCharArray());  
 | 
        }  
 | 
  
 | 
        // Trust own CA and all self-signed certs  
 | 
        SSLContext sslcontext = SSLContexts.custom()  
 | 
                .loadKeyMaterial(keyStore, "1546567611".toCharArray())  
 | 
                .build();  
 | 
        // Allow TLSv1 protocol only  
 | 
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(  
 | 
                sslcontext,  
 | 
                new String[] { "TLSv1" },  
 | 
                null,  
 | 
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);  
 | 
        CloseableHttpClient httpclient = HttpClients.custom()  
 | 
                .setSSLSocketFactory(sslsf)  
 | 
                .build();  
 | 
        HttpPost httpPost = new HttpPost(url);  
 | 
        CloseableHttpResponse response1;  
 | 
        String prepay_id = "";  
 | 
        try {  
 | 
            httpPost.setEntity(new StringEntity(xmlParam));  
 | 
            response1 = httpclient.execute(httpPost);  
 | 
            try {  
 | 
                int status = response1.getStatusLine().getStatusCode();  
 | 
                if(status>=200&&status<400){  
 | 
                    System.out.println(response1.getStatusLine());  
 | 
                    HttpEntity entity1 = response1.getEntity();  
 | 
                    String jsonStr = EntityUtils.toString(entity1, "UTF-8");  
 | 
                    Map<String, Object> dataMap = new HashMap<String, Object>();  
 | 
                    System.out.println("返回数据:"+jsonStr);  
 | 
  
 | 
                    if(jsonStr.indexOf("FAIL")!=-1){  
 | 
                        return prepay_id;  
 | 
                    }  
 | 
                    //我的项目的编码为GBK,再次改编码防止乱码出错  
 | 
                    jsonStr=new String(jsonStr.getBytes("UTF-8"), "GBK");  
 | 
                    Map map = doXMLParse(jsonStr);  
 | 
                    String return_code  = (String) map.get("return_code");  
 | 
                    if("SUCCESS".equals(return_code)){  
 | 
                        prepay_id  = (String) map.get("return_msg");  
 | 
                    }  
 | 
                }  
 | 
                return prepay_id;  
 | 
            } catch (Exception e) {  
 | 
                e.printStackTrace();  
 | 
  
 | 
            } finally {  
 | 
                response1.close();  
 | 
            }  
 | 
        } catch (ClientProtocolException e1) {  
 | 
            e1.printStackTrace();  
 | 
  
 | 
        } catch (IOException e1) {  
 | 
            e1.printStackTrace();  
 | 
  
 | 
        }  
 | 
        return null;  
 | 
    }  
 | 
  
 | 
  
 | 
    /**  
 | 
     * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。  
 | 
     * @param strxml  
 | 
     * @return  
 | 
     * @throws Exception  
 | 
     * @throws IOException  
 | 
     */  
 | 
    public static Map doXMLParse(String strxml) throws Exception {  
 | 
        if(null == strxml || "".equals(strxml)) {  
 | 
            return null;  
 | 
        }  
 | 
  
 | 
        Map m = new HashMap();  
 | 
        InputStream in = new ByteArrayInputStream(strxml.getBytes());  
 | 
        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;  
 | 
    }  
 | 
  
 | 
    public static void main(String[] args) throws Exception{  
 | 
        WxPayService wxPayService = new WxPayService();  
 | 
        wxPayService.index();  
 | 
    }  
 | 
  
 | 
}  
 |