java --微信支付2

以下是微信支付工具類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();
	}
}
相關文章
相關標籤/搜索