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);