1. 程式人生 > >APP 微信支付JAVA伺服器端

APP 微信支付JAVA伺服器端

1.支付類:

import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

/**
 * @ClassName: WeixinPay
 * @Description: TODO(微信支付)
 * @author ******@qq.com
 * @date 2018年1月13日 上午9:24:10
 */
public class WeixinPay {
	private static final String URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
	public static final String APP_ID = "*******";
	public static final String MCH_ID = "******";
	private static final String APP_SERCRET = "**************";
	private final static String[] strDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d","e", "f" };
	/**
	 * 獲取預支付
	 * @param body
	 * @param orderNum
	 * @param totalMoney
	 * @param notify_url
	 * @return
	 */
	public Map<String, String> getPreyId(String body, String orderNum, String totalMoney, String notify_url) {
		Map<String, String> reqMap = new HashMap<String, String>();
		reqMap.put("appid", APP_ID);
		reqMap.put("mch_id", MCH_ID);
		reqMap.put("nonce_str", getRandomString());
		reqMap.put("body", body);
		reqMap.put("out_trade_no", orderNum); // 商戶系統內部的訂單號,
		reqMap.put("total_fee", totalMoney); // 訂單總金額,單位為分
		reqMap.put("spbill_create_ip", getHostIp()); // 使用者端實際ip
		reqMap.put("notify_url", notify_url); // 通知地址
		reqMap.put("trade_type", "APP"); // 交易型別
		reqMap.put("sign", getSign(reqMap));
		String reqStr = creatXml(reqMap);
		String retStr = "";
		try {
			retStr = HttpClientUtil.postHtpps(URL, reqStr);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return getInfoByXml(retStr);
	}
	
	
	public static String creatXml(Map<String, String> reqMap) {
		Set<String> set = reqMap.keySet();
		StringBuffer b = new StringBuffer();
		//b.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
		//b.append("<xml>");
		b.append("<xml>");
		for (String key : set) {
			b.append("<" + key + ">").append(reqMap.get(key)).append("</" + key + ">");
		}
		b.append("</xml>");
		return b.toString();
	}

	/**
	 * 得到隨機字串
	 * 
	 * @param length
	 * @return
	 */
	public static String getRandomString() {
		int length = 32;
		String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; ++i) {
			int number = random.nextInt(62);// [0,62)
			sb.append(str.charAt(number));
		}
		return sb.toString();
	}

	/**
	 * 得到本地機器的IP
	 * 
	 * @return
	 */
	private static String getHostIp() {
		String ip = "";
		try {
			ip = InetAddress.getLocalHost().getHostAddress();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return ip;
	}

	/**
	 * 得到加密值
	 * 
	 * @param map
	 * @return
	 */
	public static String getSign(Map<String, String> map) {
		String[] keys = map.keySet().toArray(new String[0]);
		Arrays.sort(keys);
		StringBuffer reqStr = new StringBuffer();
		for (String key : keys) {
			String v = map.get(key);
			if (v != null && !v.equals("")) {
				reqStr.append(key).append("=").append(v).append("&");
			}
		}
		reqStr.append("key").append("=").append(APP_SERCRET);
		String string = encode(reqStr.toString()).toUpperCase();
		return string;
	}

	public static String encode(String strObj) {
		String resultString = null;
		try {
			resultString = new String(strObj);
			MessageDigest md = MessageDigest.getInstance("MD5");
			// md.digest() 該函式返回值為存放雜湊值結果的byte陣列
			try {
				resultString = byteToString(md.digest(strObj.getBytes("UTF-8")));
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (NoSuchAlgorithmException ex) {
			ex.printStackTrace();
		}
		return resultString;
	}

	// 轉換位元組陣列為16進位制字串
	private static String byteToString(byte[] bByte) {
		StringBuffer sBuffer = new StringBuffer();
		for (int i = 0; i < bByte.length; i++) {
			sBuffer.append(byteToArrayString(bByte[i]));
		}
		return sBuffer.toString();
	}

	// 返回形式為數字跟字串
	private static String byteToArrayString(byte bByte) {
		int iRet = bByte;
		if (iRet < 0) {
			iRet += 256;
		}
		int iD1 = iRet / 16;
		int iD2 = iRet % 16;
		return strDigits[iD1] + strDigits[iD2];
	}

	public static Map<String, String> getInfoByXml(String xmlStr) {
		try {
			Map<String, String> m = new HashMap<String, String>();
			Document d = DocumentHelper.parseText(xmlStr);
			Element root = d.getRootElement();
			for (Iterator<?> i = root.elementIterator(); i.hasNext();) {
				Element element = (Element) i.next();
				String name = element.getName();
				if (!element.isTextOnly()) {
					// 不是字串 跳過。確定了微信放回的xml只有根目錄
					continue;
				} else {
					m.put(name, element.getTextTrim());
				}
			}
			// 對返回結果做校驗.去除sign 欄位再去加密
			String retSign = m.get("sign");
			String sign = m.remove("sign");
			String rightSing = getSign(m);
			if (rightSing.equals(retSign)) {
				m.put("sign", sign);
				return m;
			}
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

}
2.呼叫支付類
String url = "https://" + getRequest().getServerName()+ "/********";
				Map<String, String> map = new WeixinPay().getPreyId(body, orderNum, ((int)(Double.valueOf(total_money)*100))+"", url);
				//簽名
				Map<String, String> appMap = new HashMap<String, String>();
				appMap.put("appid", WeixinPay.APP_ID);
				appMap.put("partnerid", WeixinPay.MCH_ID);
				appMap.put("prepayid", map.get("prepay_id"));
				appMap.put("package", "Sign=WXPay");
				appMap.put("timestamp", ((int)(System.currentTimeMillis()/1000))+"");
				appMap.put("noncestr", WeixinPay.getRandomString());
				String sign = WeixinPay.getSign(appMap);