以下是微信支付工具類java
package com.readygo.pet.utils; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; import java.security.KeyStore; import java.security.MessageDigest; import java.text.SimpleDateFormat; import javax.net.ssl.SSLContext; import javax.servlet.http.HttpServletRequest; import org.springframework.util.StringUtils; import java.util.*; 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.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; /** * 程序名 :WXPayUtils.java * 程序功能 :微信支付工具類 * 做成者 :xx * 做成日期 :2016-04-27 * 修改履歷 * 項目名 狀態 做成者 做成日期 * ----------------------------------- * pets 新規 xx 2016-04-27 */ public class WXPayUtils { /** 微信支付預支付單失敗 */ public static final String MSG_WXPAY_ORDER_FAILED = "微信支付鏈接失敗,請檢查網絡。"; /** 微信支付失敗 */ public static final String MSG_WXPAY_PAY_FAILED = "微信支付付款失敗。"; /** 微信支付查詢 */ public static final String MSG_WXPAY_SEARCH_FAILED = "微信支付付款失敗。"; /** 微信支付關閉失敗 */ public static final String MSG_WXPAY_CLOSE_FAILED = "支付訂單關閉失敗。"; public static final String SunX509 = "SunX509"; public static final String JKS = "JKS"; public static final String PKCS12 = "PKCS12"; public static final String TLS = "TLS"; /** * 採番表對象枚舉 */ public enum TableType { T_WXPAY_ORDER_RECORD("WX_PAY_ORDER_RECORD_ID"), // 微信預支付訂單記錄表 T_WXPAY_RECORD("WX_PAY_RECORD_ID"), // 微信支付記錄表 T_WXPAY_CLOSE_RECORD("WX_PAY_CLOSE_RECORD_ID"), // 微信支付訂單關閉記錄表 T_WXPAY_REFUND_RECORD("WX_PAY_REFUND_RECORD_ID"); // 微信退款訂單記錄表 private String type; private TableType(String type) { this.type = type; } public String getType() { return this.type; } } /** * 錯誤碼枚舉 **/ public enum ResultCode { SUCCESS(0), // 成功 FAILED(1), // 失敗 SUCCESS_UPLOADIMG(2);// 評論成功,上傳圖片失敗 private int type; private ResultCode(Integer type) { this.type = type; } public Integer getType() { return this.type; } } /** * 獲取系統時間 * * @return 系統時間(格式爲:yyyyMMddHHmmss) */ public static String getSysTime() { SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); Date curDate = new Date();// 獲取當前時間 String str = df.format(curDate); return str; } /** * 獲取ip地址 * * @param request * 請求包 * @return 本次請求的ip地址 */ public static String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } /** * 對象轉XML字符串 * 擴展xstream使其支持CDATA * * @param pi * 微信發起支付訂單參數 * @return xml字符串 * */ /* * public static String payInfoToXML(WXPayParam pi) { xstream.alias("xml", * pi.getClass()); return xstream.toXML(pi); } * * private static XStream xstream = new XStream(new XppDriver() { public * HierarchicalStreamWriter createWriter(Writer out) { return new * PrettyPrintWriter(out) { // 增長CDATA標記 boolean cdata = true; * * @SuppressWarnings("rawtypes") public void startNode(String name, Class * clazz) { super.startNode(name, clazz); } * * protected void writeText(QuickWriter writer, String text) { if (cdata) { * writer.write("<![CDATA["); writer.write(text); writer.write("]]>"); } * else { writer.write(text); } } }; } }); */ /** * MAP轉XML * * @param vo * 參數map * @param rootElement * 根節點 * @return xml字符串 */ public static String map2xmlBody(Map<String, Object> vo, String rootElement) { org.dom4j.Document doc = DocumentHelper.createDocument(); Element body = DocumentHelper.createElement(rootElement); doc.add(body); __buildMap2xmlBody(body, vo); return doc.asXML(); } @SuppressWarnings("unchecked") private static void __buildMap2xmlBody(Element body, Map<String, Object> vo) { if (vo != null) { Iterator<String> it = vo.keySet().iterator(); while (it.hasNext()) { String key = (String) it.next(); if (!StringUtils.isEmpty(key)) { Object obj = vo.get(key); Element element = DocumentHelper.createElement(key); if (obj != null) { if (obj instanceof java.lang.String) { element.setText((String) obj); } else { if (obj instanceof java.lang.Character || obj instanceof java.lang.Boolean || obj instanceof java.lang.Number || obj instanceof java.math.BigInteger || obj instanceof java.math.BigDecimal) { org.dom4j.Attribute attr = DocumentHelper.createAttribute(element, "type", obj.getClass().getCanonicalName()); element.add(attr); element.setText(String.valueOf(obj)); } else if (obj instanceof java.util.Map) { org.dom4j.Attribute attr = DocumentHelper.createAttribute(element, "type", java.util.Map.class.getCanonicalName()); element.add(attr); __buildMap2xmlBody(element, (Map<String, Object>) obj); } else { } } } body.add(element); } } } } /** * XML轉MAP * * @param xml * xml字符串 * @return map */ @SuppressWarnings("unchecked") public static SortedMap<String, String> parseXml(String xml) throws Exception { SortedMap<String, String> map = new TreeMap<String, String>(); if (!StringUtils.isEmpty(xml)) { Document document = DocumentHelper.parseText(xml); Element root = document.getRootElement(); List<Element> elementList = root.elements(); for (Element e : elementList) { map.put(e.getName(), e.getText()); } } return map; } /** * 生成簽名 * * @param charaterEncodeing * 編碼格式 * @param parameters * 請求參數(按ascii排序後) * @param apiKey * 商戶支付祕鑰 * @return */ @SuppressWarnings("rawtypes") public static String createSign(String charaterEncodeing, SortedMap<String, Object> parameters, String apiKey) throws Exception { StringBuffer sb = new StringBuffer(); Set es = parameters.entrySet(); Iterator it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey(); Object v = entry.getValue(); if (!StringUtils.isEmpty(v) && !"sing".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&"); } } System.out.println("生成字符串:" + sb.toString()); sb.append("key=" + apiKey); System.out.println("鏈接商戶key字符串:" + sb.toString()); String sign = MD5Encode(sb.toString(), charaterEncodeing).toUpperCase(); return sign; } /** ----------------MD5相關方法--------------------- */ private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; 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]; } private static String byteArrayToHexString(byte b[]) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < b.length; i++) { sb.append(byteToHexString(b[i])); } return sb.toString(); } /** * MD5加密 * * @param origin * 加密串 * @param charsetname * 編碼格式(UTF-8) * @return 加密後字符串 * @throws Exception */ public static String MD5Encode(String origin, String charsetname) throws Exception { String resultString = null; resultString = new String(origin); MessageDigest md = MessageDigest.getInstance("MD5"); if (StringUtils.isEmpty(charsetname)) { resultString = byteArrayToHexString(md.digest(resultString.getBytes())); } else { resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname))); } return resultString; } /** ----------------MD5相關方法--------------------- */ /** * 生成指定長度的隨機字符串(英數字) * * @param length * 生成字符串的長度 * @return 隨機字符串 */ public static String getRandomString(int length) { String base = "abcdefghijklmnopqrstuvwxyz0123456789"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { int number = random.nextInt(base.length()); sb.append(base.charAt(number)); } return sb.toString(); } /** * 帶證書的HTTPS請求 * * @param requestURL * 請求地址 * @param outputStr * 請求參數 * @param certPath * 證書本地路徑 * @param keyPasswd * 私密密碼 * @return 請求結果 * @throws Exception * */ public static String httpsRequestWithCert(String requestURL, String outputStr, String certPath, String keyPasswd) throws Exception { StringBuffer buffer = new StringBuffer(); // P12私密 FileInputStream keyFileInputStream = new FileInputStream(new File(certPath)); final char[] kp = keyPasswd.toCharArray(); KeyStore ks = KeyStore.getInstance(PKCS12); ks.load(keyFileInputStream, kp); keyFileInputStream.close(); // 相信本身的CA和全部自簽名的證書 SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(ks, kp).build(); // 只容許使用TLSv1協議 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); // 建立http請求(post方式) HttpPost httpPost = new HttpPost(requestURL); System.out.println("executing request" + httpPost.getRequestLine()); StringEntity reqEntity = new StringEntity(outputStr); // 設置類型 reqEntity.setContentType("application/x-www-form-urlencoded"); httpPost.setEntity(reqEntity); // 進行訪問並獲取返回 CloseableHttpResponse response = httpclient.execute(httpPost); // 獲取返回內容 HttpEntity entity = response.getEntity(); if (entity != null) { System.out.println("Response content length: " + entity.getContentLength()); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8")); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); } // 關閉應該關閉的資源 EntityUtils.consume(entity); response.close(); httpclient.close(); return buffer.toString(); } }