package com.pay; 

import java.util.Date; 

import java.util.Map; 

public class test { 

    /** 

     * 生成统一下单 

     * @throws Exception 

     */ 

public static void main1(String[] args) throws Exception {     

        String        appid = "";    //微信小程序--》“开发者ID” 

        String       mch_id = "";    //商户号,将该值赋值给partner 

        String          key = "";    //微信支付商户平台登录)--》“API安全”--》“API密钥”--“设置密钥”(设置之后的那个值就是partnerkey,32位) 

        String       openid = "";    //openid 

        String           ip = "";    //ip地址 

        String         body = "测试"; //描述 

        int       total_fee = 1;     //支付金额 

        Date           data = new Date(); 

        String   notify_url = "http://www.weixin.qq.com/wxpay/pay.php";   //回调链接 

        String out_trade_no = "SH" + DateUtil.dateFormatSSS.format(data); 

         

        System.out.println("支付订单号:"+out_trade_no); 

           

        Map<Object, Object> map=WeiXinAtcion.me.weixinPlay(mch_id, appid, key, openid, total_fee, out_trade_no, notify_url, body, ip); 

        System.out.println("paySign:"+map.get("paySign")); 

        System.out.println("timeStamp:"+map.get("timeStamp")); 

        System.out.println("nonceStr:"+map.get("nonceStr")); 

        System.out.println("package:"+map.get("package")); 

    } 


/** 

 * 退款 

 * @throws Exception 

 */ 

public static void main2(String[] args) throws Exception { 

    String out_trade_no = "";   //退款订单 

    int   all_total_fee = 100;    //订单金额(这里是按分来计算的) 

    int      refund_fee = 0;      //退款金额(这里是按分来计算的) 

    String        appid = "";   //微信小程序--》“开发者ID” 

    String       mch_id = "";   //商户号,将该值赋值给partner 

    String          key = "";   //微信支付商户平台登录)--》“API安全”--》“API密钥”--“设置密钥”(设置之后的那个值就是partnerkey,32位) 


   Map<String, String>  refundmap=    WeiXinAtcion.me.wechatRefund(mch_id, appid, key, out_trade_no, all_total_fee, refund_fee); 

     if(refundmap.get("return_code").equals("SUCCESS")) { 

         if(refundmap.get("result_code").equals("FAIL")) { 

             System.out.println("退款失败:原因"+refundmap.get("err_code_des")); 

         }else { 

             System.out.println("退款成功"); 

             } 

     }else { 

         System.out.println("退款失败:原因"+refundmap.get("return_ms")); 

         

     } 

} 
}

package com.pay;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class WeiXinAtcion {
    public static final WeiXinAtcion me = new WeiXinAtcion();
    
       /**
         * 退款函数,该方法可以对曾经部分退款的订单进行再次退款
         * @param out_trade_no 商户订单号
         * @param total_fee1 退款对应的订单的总金额(以“元”为单位)
         * @param refund_fee1 计划退款的金额(以“元”为单位)
         * @throws Exception 
         */
        public static  Map<String, String>  wechatRefund(String mch_id,String  appid,String key,String out_trade_no,int all_total_fee,int refund_fee) throws Exception{
            
            SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
            packageParams.put("appid",appid);
            packageParams.put("mch_id",mch_id);
            packageParams.put("op_user_id",mch_id);
            packageParams.put("nonce_str", WXUtil.generate());
            packageParams.put("out_trade_no", out_trade_no);
            packageParams.put("out_refund_no", WXUtil.generate());
            packageParams.put("total_fee",String.valueOf( all_total_fee));
            packageParams.put("refund_fee", String.valueOf( refund_fee));
            String sign = WXUtil.createSign_ChooseWXPay("UTF-8", packageParams, key);
            packageParams.put("sign", sign);
            String XML = WXUtil.getRequestXml(packageParams);
            return WXUtil.doRefund("https://api.mch.weixin.qq.com/secapi/pay/refund", XML,mch_id);
        
        }
    
        /**
         * 生成微信订单
         * 
         * @param openid
         * @param period_number
         * @param merchant_id
         * @param num
         * @return
         */
        public SortedMap<Object, Object> weixinPlay(String mch_id,String appid,String key,String openid,int total_fee,String out_trade_no,String notify_url,String body,String ip) throws UnsupportedEncodingException, DocumentException {
            
            SortedMap<Object, Object> paymentPo = new TreeMap<Object, Object>();
            paymentPo.put("appid",appid);
            paymentPo.put("mch_id",  mch_id);
            paymentPo.put("nonce_str", WXUtil.generate());
            paymentPo.put("body",body);
            paymentPo.put("out_trade_no",out_trade_no);
            paymentPo.put("total_fee",String.valueOf(total_fee));
            paymentPo.put("spbill_create_ip", "127.0.0.1");//这里填写你的服务器IP地址
            paymentPo.put("notify_url", notify_url);
            paymentPo.put("trade_type", "JSAPI");
            paymentPo.put("openid", openid);
            
            String sign = WXUtil.createSign_ChooseWXPay("UTF-8", paymentPo, key);
            paymentPo.put("sign", sign);
            String param = WXUtil.getRequestXml(paymentPo);;
        
            String request = WXUtil.httpRequest("https://api.mch.weixin.qq.com/pay/unifiedorder", "POST", param);
            Map<String, String> map = new HashMap<String, String>();         // 将解析结果存储在HashMap中
            InputStream in = new ByteArrayInputStream(request.getBytes());
            SAXReader reader = new SAXReader();                              // 读取输入流
            Document document = reader.read(in);
        
            Element root = document.getRootElement();                        // 得到xml根元素
            @SuppressWarnings("unchecked")                                   // 得到根元素的所有子节点
            List<Element> elementList = root.elements();
            for (Element element : elementList) {
                map.put(element.getName(), element.getText());
            }
            SortedMap<Object, Object> result = new TreeMap<Object, Object>();
                
            if (map.get("return_code").equals("SUCCESS")) {                  // 业务结果
                String nonceStr  =WXUtil.generate();
                Long   timeStamp = System.currentTimeMillis() / 1000;
                SortedMap<Object, Object> params = new TreeMap<Object, Object>();
                
                params.put("appId", appid);
                params.put("nonceStr", nonceStr);
                params.put("package", "prepay_id=" + map.get("prepay_id")); 
                params.put("signType", "MD5"); 
                params.put("timeStamp", timeStamp); 
                
                String paySign = WXUtil.createSign_ChooseWXPay("UTF-8", params, key);
                result.put("paySign", paySign);
                result.put("timeStamp", timeStamp + "");
                result.put("nonceStr", nonceStr);
                
                result.put("package", "prepay_id=" + map.get("prepay_id"));
                result.put("return_code", "SUCCESS");
            }else {
                result.put("return_code", "Fail");
                result.put("return_msg", map.get("return_msg"));
            }
            return result;
        }
        
        /**
         * 支付成功的回调函数
         * @param request
         * @param response
         * @throws Exception
         */
        public void weixinpay_notify(HttpServletRequest request,HttpServletResponse response) throws Exception{  
            InputStream inputStream ;  
            StringBuffer sb = new StringBuffer();  
            inputStream = request.getInputStream();  
            String s ;  
            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));  
            while ((s = in.readLine()) != null){  
                sb.append(s);  
            }  
            in.close();  
            inputStream.close();  
            Map<String, String> m = new HashMap<String, String>();  
            m = WXUtil.doXMLParse(sb.toString());  
            SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();        
            Iterator it = m.keySet().iterator();  
            while (it.hasNext()) {  
                String parameter = (String) it.next();  
                String parameterValue = m.get(parameter);  
                String v = "";  
                if(null != parameterValue) {  
                    v = parameterValue.trim();  
                }  
                packageParams.put(parameter, v);  
            }  
            String key = ""; //秘钥 
            if(WXUtil.isTenpaySign("UTF-8", packageParams,key)) {  
                String resXml = "";  
                if("SUCCESS".equals((String)packageParams.get("result_code"))){  
                   
                    //得到返回的参数
                    String openid = (String)packageParams.get("openid");  
                    String transaction_id = (String)packageParams.get("transaction_id");  
                    String out_trade_no = (String)packageParams.get("out_trade_no");  
                    String total_fee = (String)packageParams.get("total_fee");  
                    Float fee= Float.parseFloat(total_fee)/100;
                    //这里可以写你需要的业务
                
                    resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"  
                            + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";  
                    BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());  
                    out.write(resXml.getBytes());  
                    out.flush();  
                    out.close();
                } else {  
                  System.out.println("回调失败");
                }  
            } else{  
                System.out.println("回调失败");
            } 
        }
        
}


package com.pay;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.UUID;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpEntity;
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.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;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
public class WXUtil {
    /**
     * 随机字符串
     * @return
     */
    public static String generate() {
        return UUID.randomUUID().toString().trim().replaceAll("-", "");
    }
    
    /**
     * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
     * @param strxml
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    public static Map doXMLParse(String strxml) throws JDOMException, IOException {
        strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");

        if(null == strxml || "".equals(strxml)) {
            return null;
        }
        Map m = new HashMap();
        InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
        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 = WXUtil.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(WXUtil.getChildrenText(list));
                }
                sb.append(value);
                sb.append("</" + name + ">");
            }
        }
        return sb.toString();
    }
    /**
     * 将请求参数转换为xml格式的string字符串,微信服务器接收的是xml格式的字符串
     * 
     * 作者: zhoubang 日期:2015年6月10日 上午9:25:51
     * 
     * @param parameters
     * @return
     */
    public static String getRequestXml(SortedMap<Object, Object> parameters) {
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        Set<Entry<Object, Object>> es = parameters.entrySet();
        Iterator<Entry<Object, Object>> it = es.iterator();
        while (it.hasNext()) {
            Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            
            if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
                sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
            } else {
                sb.append("<" + k + ">" + v + "</" + k + ">");
            }
        }
        sb.append("</xml>");
        return sb.toString();
    }
    
    /**
     * sign签名,必须使用MD5签名,且编码为UTF-8
     * 作者: zhoubang 日期:2015年6月10日 上午9:31:24
     * @param characterEncoding
     * @param parameters
     * @return
     */
    public static String createSign_ChooseWXPay(String characterEncoding, SortedMap<Object, Object> parameters, String key) {
        StringBuffer sb = new StringBuffer();
        Set<Entry<Object, Object>> es = parameters.entrySet();
        Iterator<Entry<Object, Object>> it = es.iterator();
        while (it.hasNext()) {
            Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) it.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        /** 支付密钥必须参与加密,放在字符串最后面 */
        sb.append("key=" + key);
        String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
        return sign;
    }
    

    /**
     * 
     * @param requestUrl请求地址
     * @param requestMethod请求方法
     * @param outputStr参数
     */
    public static String httpRequest(String requestUrl,String requestMethod,String outputStr){
        // 创建SSLContext
        StringBuffer buffer=null;
        try{
        URL url = new URL(requestUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(requestMethod);
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.connect();

        //往服务器端写内容
        if(null !=outputStr){
            OutputStream os=conn.getOutputStream();
            os.write(outputStr.getBytes("utf-8"));
            os.close();
        }
        // 读取服务器端返回的内容
        InputStream is = conn.getInputStream();
        InputStreamReader isr = new InputStreamReader(is, "utf-8");
        BufferedReader br = new BufferedReader(isr);
        buffer = new StringBuffer();
        String line = null;
        while ((line = br.readLine()) != null) {
             buffer.append(line);
         }
        }catch(Exception e){
            e.printStackTrace();
        }
        return buffer.toString();
        }   
    public static String urlEncodeUTF8(String source){
        String result=source;
        try {
            result=java.net.URLEncoder.encode(source, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return result;
    }
        
    /**
     * 退款
     */
   public static Map<String, String> doRefund(String url,String data,String partner) throws Exception {
        //p12证书的位置
        //微信公众平台:“微信支付”--》“商户信息”--》“交易数据”--》“详情请登录微信支付商户平台查看”(登录)--》“API安全”--》“API证书”--》“下载证书”
        //下载证书后将apiclient_cert.p12放在src目录下面(出于安全考虑,请自行下载自己的证书)
        String apiclient_certLocation = "apiclient_cert.p12";
        KeyStore keyStore  = KeyStore.getInstance("PKCS12");
        URL url2 = WXUtil.class.getClassLoader().getResource(apiclient_certLocation);
        URI uri = url2.toURI();
        FileInputStream instream = new FileInputStream(new File(uri));//P12文件目录
        try {
            keyStore.load(instream, partner.toCharArray());
        } finally {
            instream.close();
        }
        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, partner.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 WXUtil.doXMLParse(jsonStr);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
    
    /** 
     * 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。 
     * @return boolean 
     */  
    public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {  
        StringBuffer sb = new StringBuffer();  
        Set es = packageParams.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(!"sign".equals(k) && null != v && !"".equals(v)) {  
                sb.append(k + "=" + v + "&");  
            }  
        }  
        sb.append("key=" + API_KEY);  
        //算出摘要  
        String mysign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toLowerCase();  
        String tenpaySign = ((String)packageParams.get("sign")).toLowerCase();  
          
        //System.out.println(tenpaySign + "    " + mysign);  
        return tenpaySign.equals(mysign);  
    }  

}



package com.pay;
import java.security.MessageDigest;
public class MD5Util {

    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append(byteToHexString(b[i]));

        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

     public static String MD5Encode(String origin, String charsetname) {  
            String resultString = null;  
            try {  
                resultString = new String(origin);  
                MessageDigest md = MessageDigest.getInstance("MD5");  
                if (charsetname == null || "".equals(charsetname))  
                    resultString = byteArrayToHexString(md.digest(resultString  
                            .getBytes()));  
                else  
                    resultString = byteArrayToHexString(md.digest(resultString  
                            .getBytes(charsetname)));  
            } catch (Exception exception) {  
            }  
            return resultString;  
        }  
    
    private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
        "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
}




package com.pay;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateUtil {

    public static SimpleDateFormat dateFormatMillisecond = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
    public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public static SimpleDateFormat dateFormatWithYMD = new SimpleDateFormat("yyyy-MM-dd");
    public static SimpleDateFormat dateFormatWithYMDHM = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    public static SimpleDateFormat dateFormatSSS = new SimpleDateFormat("yyyyMMddHHmmssSSS");

    public static String addDateMinut(Date date, int x) {// 返回的是字符串型的时间,输入的//是String    // day, int x
        // 引号里面个格式也可以是 HH:mm:ss或者HH:mm等等,很随意的,不过在主函数调用时,要和输入的变
        // 量day格式一致
        if (date == null)
            return "";
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MINUTE, x);// 24小时制
        date = cal.getTime();
        cal = null;
        return dateFormat.format(date);
    }
    
    public static void main(String[] args) {
        System.out.println("asd");
    }
    
      /**  
     * 计算两个日期之间相差的天数  
     * @param smdate 较小的时间 
     * @param bdate  较大的时间 
     * @return 相差天数 
     * @throws ParseException  
     */    
    public static int daysBetween(Date smdate,Date bdate) throws ParseException    
    {    
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");  
        smdate=sdf.parse(sdf.format(smdate));  
        bdate=sdf.parse(sdf.format(bdate));  
        Calendar cal = Calendar.getInstance();    
        cal.setTime(smdate);    
        long time1 = cal.getTimeInMillis();                 
        cal.setTime(bdate);    
        long time2 = cal.getTimeInMillis();         
        long between_days=(time2-time1)/(1000*3600*24);  
            
       return Integer.parseInt(String.valueOf(between_days));           
    }   
    
    /** 
    *字符串的日期格式的计算 
    */  
    public static int daysBetween(String smdate,String bdate) throws ParseException{  
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");  
        Calendar cal = Calendar.getInstance();    
        cal.setTime(sdf.parse(smdate));    
        long time1 = cal.getTimeInMillis();                 
        cal.setTime(sdf.parse(bdate));    
        long time2 = cal.getTimeInMillis();         
        long between_days=(time2-time1)/(1000*3600*24);  
            
       return Integer.parseInt(String.valueOf(between_days));     
    }  

    public static Date addDateHour(Date date, int x) {// 返回的是字符串型的时间,输入的//是String
        // 引号里面个格式也可以是 HH:mm:ss或者HH:mm等等,很随意的,不过在主函数调用时,要和输入的变
        // 量day格式一致
        if (date == null)
            return new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.HOUR_OF_DAY, x);
        return cal.getTime();
    }
    public static String dateFormatWithData(Date data, SimpleDateFormat format) {
        return format.format(data);
    }
    public static Date dateFormatWithData(String data, SimpleDateFormat format) {
        try {
            return format.parse(data);
        } catch (ParseException e) {
            return null;
        }
    }
}
 

  链接:https://pan.baidu.com/s/18hqm16SHjyhfray60bw38A 
 


 密码:002y