Selaa lähdekoodia

微信支付基础组间

小柒2012 7 vuotta sitten
vanhempi
commit
6a4b7c3563

+ 3 - 1
.gitignore

@@ -7,4 +7,6 @@
 *.ear
 /target/
 /.settings/
-zfbinfo.properties
+zfbinfo.properties
+wxinfo.properties
+*apiclient_cert.p12

+ 20 - 2
pom.xml

@@ -82,8 +82,26 @@
 		<dependency>
 			<groupId>net.sourceforge.nekohtml</groupId>
 			<artifactId>nekohtml</artifactId>
-			<version>1.9.22</version>
-		</dependency>  
+		</dependency> 
+		<!--jdom -->
+		<dependency>
+		    <groupId>jdom</groupId>
+		    <artifactId>jdom</artifactId>
+		    <version>1.1</version>
+		</dependency>
+		<!--httpclient -->
+		<dependency>
+		    <groupId>org.apache.httpcomponents</groupId>
+		    <artifactId>httpclient</artifactId>
+		    <version>4.3.4</version><!--$NO-MVN-MAN-VER$-->
+		</dependency>
+		<!-- dom4j -->
+		<dependency>
+		    <groupId>dom4j</groupId>
+		    <artifactId>dom4j</artifactId>
+		    <version>1.6.1</version><!--$NO-MVN-MAN-VER$-->
+		</dependency>
+		 
 	</dependencies>
 	<build>
 		<finalName>spring-boot-pay</finalName>

+ 66 - 0
src/main/java/com/itstyle/modules/weixinpay/util/ClientCustomSSL.java

@@ -0,0 +1,66 @@
+package com.itstyle.modules.weixinpay.util;
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.KeyStore;
+
+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.springframework.util.ResourceUtils;
+
+import com.itstyle.common.constants.Constants;
+/**
+ * 退款认证
+ * 创建者 科帮网
+ * 创建时间	2017年7月31日
+ *
+ */
+public class ClientCustomSSL {
+	 public static String doRefund(String url,String data) throws Exception {  
+        /** 
+         * 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的 
+         */  
+        KeyStore keyStore  = KeyStore.getInstance("PKCS12");  
+        File certfile = ResourceUtils.getFile("classpath:cert"+ Constants.SF_FILE_SEPARATOR + ConfigUtil.CERT_PATH);
+        FileInputStream instream = new FileInputStream(certfile);
+        try {  
+            keyStore.load(instream, ConfigUtil.MCH_ID.toCharArray());
+        } finally {  
+            instream.close();  
+        }  
+        SSLContext sslcontext = SSLContexts.custom()  
+                .loadKeyMaterial(keyStore, ConfigUtil.MCH_ID.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.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 jsonStr;
+			} finally {
+				response.close();
+			}
+		} finally {
+			httpclient.close();
+		}
+	}  
+}

+ 137 - 0
src/main/java/com/itstyle/modules/weixinpay/util/ConfigUtil.java

@@ -0,0 +1,137 @@
+package com.itstyle.modules.weixinpay.util;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+
+/**
+ * 相关配置参数 
+ * 创建者 科帮网 
+ * 创建时间 2017年7月31日
+ */
+public class ConfigUtil {
+	private static Configuration configs;
+	public  static String APP_ID;// 服务号的应用ID
+	public  static String APP_SECRET;// 服务号的应用密钥
+	public  static String TOKEN;// 服务号的配置token
+	public  static String MCH_ID;// 商户号
+	public  static String API_KEY;// API密钥
+	public  static String SIGN_TYPE;// 签名加密方式
+	public  static String CERT_PATH ;//微信支付证书
+
+	public static synchronized void init(String filePath) {
+		if (configs != null) {
+			return;
+		}
+		try {
+			configs = new PropertiesConfiguration(filePath);
+		} catch (ConfigurationException e) {
+			e.printStackTrace();
+		}
+
+		if (configs == null) {
+			throw new IllegalStateException("can`t find file by path:"
+					+ filePath);
+		}
+		APP_ID = configs.getString("APP_ID");
+		APP_SECRET = configs.getString("APP_SECRET");
+		TOKEN = configs.getString("TOKEN");
+		MCH_ID = configs.getString("MCH_ID");
+		API_KEY = configs.getString("API_KEY");
+		SIGN_TYPE = configs.getString("SIGN_TYPE");
+		CERT_PATH = configs.getString("CERT_PATH");
+	}
+
+	/**
+	 * 微信基础接口地址
+	 */
+	// 获取token接口(GET)
+	public final static String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
+	// oauth2授权接口(GET)
+	public final static String OAUTH2_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
+	// 刷新access_token接口(GET)
+	public final static String REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";
+	// 菜单创建接口(POST)
+	public final static String MENU_CREATE_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
+	// 菜单查询(GET)
+	public final static String MENU_GET_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN";
+	// 菜单删除(GET)
+	public final static String MENU_DELETE_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";
+	/**
+	 * 微信支付接口地址
+	 */
+	// 微信支付统一接口(POST)
+	public final static String UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
+	// 微信退款接口(POST)
+	public final static String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
+	// 订单查询接口(POST)
+	public final static String CHECK_ORDER_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
+	// 关闭订单接口(POST)
+	public final static String CLOSE_ORDER_URL = "https://api.mch.weixin.qq.com/pay/closeorder";
+	// 退款查询接口(POST)
+	public final static String CHECK_REFUND_URL = "https://api.mch.weixin.qq.com/pay/refundquery";
+	// 对账单接口(POST)
+	public final static String DOWNLOAD_BILL_URL = "https://api.mch.weixin.qq.com/pay/downloadbill";
+	// 短链接转换接口(POST)
+	public final static String SHORT_URL = "https://api.mch.weixin.qq.com/tools/shorturl";
+	// 接口调用上报接口(POST)
+	public final static String REPORT_URL = "https://api.mch.weixin.qq.com/payitil/report";
+    
+	/**
+	 * 基础参数
+	 * @Author  科帮网
+	 * @param packageParams  void
+	 * @Date	2017年7月31日
+	 * 更新日志
+	 * 2017年7月31日  科帮网 首次创建
+	 *
+	 */
+	public static void commonParams(SortedMap<Object, Object> packageParams) {
+		// 账号信息
+		String appid = ConfigUtil.APP_ID; // appid
+		String mch_id = ConfigUtil.MCH_ID; // 商业号
+		// 生成随机字符串
+		String currTime = PayCommonUtil.getCurrTime();
+		String strTime = currTime.substring(8, currTime.length());
+		String strRandom = PayCommonUtil.buildRandom(4) + "";
+		String nonce_str = strTime + strRandom;
+		packageParams.put("appid", appid);// 公众账号ID
+		packageParams.put("mch_id", mch_id);// 商户号
+		packageParams.put("nonce_str", nonce_str);// 随机字符串
+	}
+
+	/**
+	 * 该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量,提升扫描速度和精确度
+	 * @Author  科帮网
+	 * @param urlCode  void
+	 * @Date	2017年7月31日
+	 * 更新日志
+	 * 2017年7月31日  科帮网 首次创建
+	 *
+	 */
+	@SuppressWarnings("rawtypes")
+	public static void shorturl(String urlCode) {
+		try {
+			String key = ConfigUtil.API_KEY; // key
+			SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
+			ConfigUtil.commonParams(packageParams);
+			packageParams.put("long_url", urlCode);// URL链接
+			String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
+			packageParams.put("sign", sign);// 签名
+			String requestXML = PayCommonUtil.getRequestXml(packageParams);
+			String resXml = HttpUtil.postData(ConfigUtil.SHORT_URL, requestXML);
+			Map map = XMLUtil.doXMLParse(resXml);
+			String returnCode = (String) map.get("return_code");
+			if ("SUCCESS".equals(returnCode)) {
+				String resultCode = (String) map.get("return_code");
+				if ("SUCCESS".equals(resultCode)) {
+					urlCode = (String) map.get("short_url");
+				}
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+}

+ 59 - 0
src/main/java/com/itstyle/modules/weixinpay/util/HttpUtil.java

@@ -0,0 +1,59 @@
+package com.itstyle.modules.weixinpay.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.URL;
+import java.net.URLConnection;
+/**
+ * http请求(这里用户获取订单url生成二维码)
+ * 创建者 科帮网
+ * 创建时间	2017年7月31日
+ *
+ */
+public class HttpUtil {
+	private final static int CONNECT_TIMEOUT = 5000; // in milliseconds
+	private final static String DEFAULT_ENCODING = "UTF-8";
+
+	public static String postData(String urlStr, String data) {
+		return postData(urlStr, data, null);
+	}
+
+	public static String postData(String urlStr, String data, String contentType) {
+		BufferedReader reader = null;
+		try {
+			URL url = new URL(urlStr);
+			URLConnection conn = url.openConnection();
+			conn.setDoOutput(true);
+			conn.setConnectTimeout(CONNECT_TIMEOUT);
+			conn.setReadTimeout(CONNECT_TIMEOUT);
+			if (contentType != null)
+				conn.setRequestProperty("content-type", contentType);
+			OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);
+			if (data == null)
+				data = "";
+			writer.write(data);
+			writer.flush();
+			writer.close();
+
+			reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));
+			StringBuilder sb = new StringBuilder();
+			String line = null;
+			while ((line = reader.readLine()) != null) {
+				sb.append(line);
+				sb.append("\r\n");
+			}
+			return sb.toString();
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			try {
+				if (reader != null)
+					reader.close();
+			} catch (IOException e) {
+			}
+		}
+		return null;
+	}
+}

+ 44 - 0
src/main/java/com/itstyle/modules/weixinpay/util/MD5Util.java

@@ -0,0 +1,44 @@
+package com.itstyle.modules.weixinpay.util;
+
+import java.security.MessageDigest;
+/**
+ * MD5加密
+ * 创建者 科帮网
+ * 创建时间	2017年7月31日
+ *
+ */
+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" };
+}

+ 135 - 0
src/main/java/com/itstyle/modules/weixinpay/util/PayCommonUtil.java

@@ -0,0 +1,135 @@
+package com.itstyle.modules.weixinpay.util;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+
+public class PayCommonUtil {
+	/**
+	 * 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。 
+	 * @Author  科帮网
+	 * @param characterEncoding
+	 * @param packageParams
+	 * @param API_KEY
+	 * @return  boolean
+	 * @Date	2017年7月31日
+	 * 更新日志
+	 * 2017年7月31日  科帮网 首次创建
+	 *
+	 */
+	@SuppressWarnings({ "rawtypes"})
+    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();  
+        return tenpaySign.equals(mysign);  
+    }  
+    /**
+     * sign签名
+     * @Author  科帮网
+     * @param characterEncoding
+     * @param packageParams
+     * @param API_KEY
+     * @return  String
+     * @Date	2017年7月31日
+     * 更新日志
+     * 2017年7月31日  科帮网 首次创建
+     *
+     */
+    @SuppressWarnings({ "rawtypes"})
+	public static String createSign(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 (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {  
+                sb.append(k + "=" + v + "&");  
+            }  
+        }  
+        sb.append("key=" + API_KEY);  
+        String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();  
+        return sign;  
+    }  
+  
+   /**
+    * 将请求参数转换为xml格式的string
+    * @Author  科帮网
+    * @param parameters
+    * @return  String
+    * @Date	2017年7月31日
+    * 更新日志
+    * 2017年7月31日  科帮网 首次创建
+    *
+    */
+    @SuppressWarnings({ "rawtypes"})
+    public static String getRequestXml(SortedMap<Object, Object> parameters) {  
+        StringBuffer sb = new StringBuffer();  
+        sb.append("<xml>");  
+        Set es = parameters.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 ("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();  
+    }  
+  
+   /**
+    * 取出一个指定长度大小的随机正整数. 
+    * @Author  科帮网
+    * @param length
+    * @return  int
+    * @Date	2017年7月31日
+    * 更新日志
+    * 2017年7月31日  科帮网 首次创建
+    *
+    */
+    public static int buildRandom(int length) {  
+        int num = 1;  
+        double random = Math.random();  
+        if (random < 0.1) {  
+            random = random + 0.1;  
+        }  
+        for (int i = 0; i < length; i++) {  
+            num = num * 10;  
+        }  
+        return (int) ((random * num));  
+    }  
+  
+    /** 
+     * 获取当前时间 yyyyMMddHHmmss 
+     *  
+     * @return String 
+     */  
+    public static String getCurrTime() {  
+        Date now = new Date();  
+        SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");  
+        String s = outFormat.format(now);  
+        return s;  
+    }
+}

+ 94 - 0
src/main/java/com/itstyle/modules/weixinpay/util/XMLUtil.java

@@ -0,0 +1,94 @@
+package com.itstyle.modules.weixinpay.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+/**
+ * XML解析
+ * 创建者 科帮网
+ * 创建时间	2017年7月31日
+ *
+ */
+public class XMLUtil {
+	/**
+	 * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
+	 * 
+	 * @param strxml
+	 * @return
+	 * @throws JDOMException
+	 * @throws IOException
+	 */
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	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 = XMLUtil.getChildrenText(children);
+			}
+
+			m.put(k, v);
+		}
+
+		// 关闭流
+		in.close();
+
+		return m;
+	}
+
+	/**
+	 * 获取子结点的xml
+	 * 
+	 * @param children
+	 * @return String
+	 */
+	@SuppressWarnings({ "rawtypes" })
+	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(XMLUtil.getChildrenText(list));
+				}
+				sb.append(value);
+				sb.append("</" + name + ">");
+			}
+		}
+
+		return sb.toString();
+	}
+
+}

+ 98 - 0
src/main/java/com/itstyle/modules/weixinpay/util/mobile/MobileUtil.java

@@ -0,0 +1,98 @@
+package com.itstyle.modules.weixinpay.util.mobile;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import com.google.gson.Gson;
+import com.itstyle.modules.weixinpay.util.ConfigUtil;
+/**
+ * 微信H5支付工具类
+ * 创建者 科帮网
+ * 创建时间	2017年7月31日
+ */
+public class MobileUtil {
+	/**
+	 * 获取用户openID
+	 * @Author  科帮网
+	 * @param code
+	 * @return  String
+	 * @Date	2017年7月31日
+	 * 更新日志
+	 * 2017年7月31日  科帮网 首次创建
+	 *
+	 */
+	public static String getOpenId(String code){
+		if (code != null) {
+			String url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
+					+ "appid="+ ConfigUtil.APP_ID
+					+ "&secret="+ ConfigUtil.APP_SECRET + "&code="
+					+code + "&grant_type=authorization_code";
+			String returnData = getReturnData(url);
+			Gson gson = new Gson();
+			OpenIdClass openIdClass = gson.fromJson(returnData,
+					OpenIdClass.class);
+			if (openIdClass.getOpenid() != null) {
+				return openIdClass.getOpenid();
+			}
+		}
+		return "**************";
+	}
+	public static String getReturnData(String urlString) {
+		String res = "";
+		try {
+			URL url = new URL(urlString);
+			java.net.HttpURLConnection conn = (java.net.HttpURLConnection) url
+					.openConnection();
+			conn.connect();
+			java.io.BufferedReader in = new java.io.BufferedReader(
+					new java.io.InputStreamReader(conn.getInputStream(),
+							"UTF-8"));
+			String line;
+			while ((line = in.readLine()) != null) {
+				res += line;
+			}
+			in.close();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return res;
+	}
+	/**
+	 * 回调request 参数解析为map格式
+	 * @Author  科帮网
+	 * @param request
+	 * @return
+	 * @throws Exception  Map<String,String>
+	 * @Date	2017年7月31日
+	 * 更新日志
+	 * 2017年7月31日  科帮网 首次创建
+	 *
+	 */
+	@SuppressWarnings("unchecked")
+	public static Map<String, String> parseXml(HttpServletRequest request)
+			throws Exception {
+		// 解析结果存储在HashMap
+		Map<String, String> map = new HashMap<String, String>();
+		InputStream inputStream = request.getInputStream();
+		// 读取输入流
+		SAXReader reader = new SAXReader();
+		Document document = reader.read(inputStream);
+		// 得到xml根元素
+		Element root = document.getRootElement();
+		// 得到根元素的所有子节点
+		List<Element> elementList = root.elements();
+		// 遍历所有子节点
+		for (Element e : elementList)
+			map.put(e.getName(), e.getText());
+		// 释放资源
+		inputStream.close();
+		inputStream = null;
+		return map;
+	}
+}

+ 82 - 0
src/main/java/com/itstyle/modules/weixinpay/util/mobile/OpenIdClass.java

@@ -0,0 +1,82 @@
+package com.itstyle.modules.weixinpay.util.mobile;
+/**
+ * 微信用户信息
+ * 创建者 科帮网
+ * 创建时间	2017年7月31日
+ *
+ */
+public class OpenIdClass {
+	private String access_token;
+	private String expires_in;
+	private String refresh_token;
+	private String openid;
+	private String scope;
+	private String unionid;
+
+	public String getAccess_token() {
+		return access_token;
+	}
+
+	public void setAccess_token(String access_token) {
+		this.access_token = access_token;
+	}
+
+	public String getExpires_in() {
+		return expires_in;
+	}
+
+	public void setExpires_in(String expires_in) {
+		this.expires_in = expires_in;
+	}
+
+	public String getRefresh_token() {
+		return refresh_token;
+	}
+
+	public void setRefresh_token(String refresh_token) {
+		this.refresh_token = refresh_token;
+	}
+
+	public String getOpenid() {
+		return openid;
+	}
+
+	public void setOpenid(String openid) {
+		this.openid = openid;
+	}
+
+	public String getScope() {
+		return scope;
+	}
+
+	public void setScope(String scope) {
+		this.scope = scope;
+	}
+
+	public String getUnionid() {
+		return unionid;
+	}
+
+	public void setUnionid(String unionid) {
+		this.unionid = unionid;
+	}
+
+	public String getErrcode() {
+		return errcode;
+	}
+
+	public void setErrcode(String errcode) {
+		this.errcode = errcode;
+	}
+
+	public String getErrmsg() {
+		return errmsg;
+	}
+
+	public void setErrmsg(String errmsg) {
+		this.errmsg = errmsg;
+	}
+
+	private String errcode;
+	private String errmsg;
+}

+ 1 - 0
src/main/resources/cert/readme.txt

@@ -0,0 +1 @@
+微信支付证书存放路径地址(微信退款 需要证书认证)