| package com.xzx.gc.util.pay.util;  | 
|   | 
|   | 
| import com.xzx.gc.model.admin.UserAccountModel;  | 
| import com.xzx.gc.util.pay.util.entity.ResultEntity;  | 
| import com.xzx.gc.util.pay.util.entity.TransfersDtoAdmin;  | 
| import lombok.extern.slf4j.Slf4j;  | 
| import org.apache.commons.codec.digest.DigestUtils;  | 
| import org.apache.commons.logging.Log;  | 
| import org.apache.commons.logging.LogFactory;  | 
| import org.w3c.dom.Document;  | 
|   | 
| import javax.xml.parsers.DocumentBuilderFactory;  | 
| import javax.xml.xpath.XPath;  | 
| import javax.xml.xpath.XPathExpressionException;  | 
| import javax.xml.xpath.XPathFactory;  | 
| import java.io.ByteArrayInputStream;  | 
| import java.io.InputStream;  | 
| import java.text.SimpleDateFormat;  | 
| import java.util.*;  | 
|   | 
|   | 
| @Slf4j  | 
| public class WechatpayUtil  | 
| {  | 
|   | 
|   | 
|     public static String queryErrorMessage(String xmlStr){  | 
|         Document document = StringTOXml(xmlStr);  | 
|         String nodePath = "/xml/err_code_des";  | 
|         String msg = getNodeValue(document,nodePath);  | 
|         return msg;  | 
|     }  | 
|   | 
|     /**  | 
|      *  | 
|      * @param  | 
|      * @return Document 对象  | 
|      */  | 
|     public static Document StringTOXml(String str) {  | 
|   | 
|         StringBuilder sXML = new StringBuilder();  | 
|         sXML.append(str);  | 
|         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();  | 
|         Document doc = null;  | 
|         try {  | 
|             InputStream is = new ByteArrayInputStream(sXML.toString().getBytes("utf-8"));  | 
|             doc = dbf.newDocumentBuilder().parse(is);  | 
|             is.close();  | 
|         } catch (Exception e) {  | 
|             e.printStackTrace();  | 
|         }  | 
|         return doc;  | 
|     }  | 
|     /**  | 
|      *  | 
|      * @param document  | 
|      * @return 某个节点的值 前提是需要知道xml格式,知道需要取的节点相对根节点所在位置  | 
|      */  | 
|     public static String getNodeValue(Document document, String nodePaht) {  | 
|         XPathFactory xpfactory = XPathFactory.newInstance();  | 
|         XPath path = xpfactory.newXPath();  | 
|         String servInitrBrch = "";  | 
|         try {  | 
|             servInitrBrch = path.evaluate(nodePaht, document);  | 
|         } catch (XPathExpressionException e) {  | 
|             e.printStackTrace();  | 
|         }  | 
|         return servInitrBrch;  | 
|     }  | 
|   | 
|     public static void main(String[] args) {  | 
|         String xmlStr = "<xml>\n" +  | 
|                 "<return_code><![CDATA[SUCCESS]]></return_code>\n" +  | 
|                 "<return_msg><![CDATA[支付失败]]></return_msg>\n" +  | 
|                 "<mch_appid><![CDATA[wx9c43b2bf3aad415b]]></mch_appid>\n" +  | 
|                 "<mchid><![CDATA[1546567611]]></mchid>\n" +  | 
|                 "<result_code><![CDATA[FAIL]]></result_code>\n" +  | 
|                 "<err_code><![CDATA[V2_ACCOUNT_SIMPLE_BAN]]></err_code>\n" +  | 
|                 "<err_code_des><![CDATA[非实名用户账号不可发放]]></err_code_des>\n" +  | 
|                 "</xml>";  | 
|         String message = queryErrorMessage(xmlStr);  | 
|         System.out.println(message);  | 
|     }  | 
|     /**  | 
|      * @param model  | 
|      *            微信接口请求参数DTO对象  | 
|      * @return ResultEntity 返回结构体  | 
|      */  | 
|     public static ResultEntity doTransfers(String url, String path, TransfersDtoAdmin model, UserAccountModel userAccount, String stringBuild)  | 
|     {  | 
|         try  | 
|         {  | 
|             // 3.加载证书请求接口  | 
|             String result = HttpRequestHandler.httpsRequest(url, stringBuild,  | 
|                     model, path);  | 
|             log.debug(("response xml = " + result));  | 
|             if(result.contains("CDATA[FAIL]")){  | 
|                 String message = queryErrorMessage(result);  | 
|                 return new ResultEntity(false, message);  | 
|             }  | 
|         }  | 
|         catch (Exception e)  | 
|         {  | 
|             e.printStackTrace();  | 
|             return new ResultEntity(false, e.getMessage());  | 
|         }  | 
|         return new ResultEntity(true);  | 
|     }  | 
|   | 
|     public static String getStringBuild(TransfersDtoAdmin model){  | 
|         // 1.计算参数签名  | 
|         String paramStr = createLinkString(model);  | 
|         String mysign = paramStr + "&key=" + model.getAppkey();  | 
|         String sign = DigestUtils.md5Hex(mysign).toUpperCase();  | 
|         // 2.封装请求参数  | 
|         StringBuilder reqXmlStr = new StringBuilder();  | 
|         reqXmlStr.append("<xml>");  | 
|         reqXmlStr.append("<mchid>" + model.getMchid() + "</mchid>");  | 
|         reqXmlStr.append("<mch_appid>" + model.getMch_appid() + "</mch_appid>");  | 
|         reqXmlStr.append("<nonce_str>" + model.getNonce_str() + "</nonce_str>");  | 
|         reqXmlStr.append("<check_name>" + model.getCheck_name() + "</check_name>");  | 
|         reqXmlStr.append("<openid>" + model.getOpenid() + "</openid>");  | 
|         reqXmlStr.append("<amount>" + model.getAmount() + "</amount>");  | 
|         reqXmlStr.append("<desc>" + model.getDesc() + "</desc>");  | 
|         reqXmlStr.append("<sign>" + sign + "</sign>");  | 
|         reqXmlStr.append("<partner_trade_no>" + model.getPartner_trade_no() + "</partner_trade_no>");  | 
|         reqXmlStr.append("<spbill_create_ip>" + model.getSpbill_create_ip() + "</spbill_create_ip>");  | 
|         reqXmlStr.append("</xml>");  | 
|   | 
|         log.debug("request xml = " + reqXmlStr);  | 
|         return reqXmlStr.toString();  | 
|     }  | 
|     private static String createLinkString(TransfersDtoAdmin model)  | 
|     {  | 
|         // 微信签名规则 https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=4_3  | 
|         Map<String, Object> paramMap = new HashMap<String, Object>();  | 
|   | 
|         // 订单号默认用商户号+时间戳+4位随机数+可以根据自己的规则进行调整  | 
|         model.setAppkey(model.getAppkey());  | 
|         model.setNonce_str(WechatpayUtil.getNonce_str());  | 
|         model.setPartner_trade_no(model.getMchid()  | 
|                 + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())  | 
|                 + (int)((Math.random() * 9 + 1) * 1000));  | 
|   | 
|         paramMap.put("mch_appid", model.getMch_appid());  | 
|         paramMap.put("mchid", model.getMchid());  | 
|         paramMap.put("openid", model.getOpenid());  | 
|         paramMap.put("amount", model.getAmount());  | 
|         paramMap.put("check_name", model.getCheck_name());  | 
|         paramMap.put("desc", model.getDesc());  | 
|         paramMap.put("partner_trade_no", model.getPartner_trade_no());  | 
|         paramMap.put("nonce_str", model.getNonce_str());  | 
|         paramMap.put("spbill_create_ip", model.getSpbill_create_ip());  | 
|   | 
|         List<String> keys = new ArrayList(paramMap.keySet());  | 
|         Collections.sort(keys);  | 
|         String prestr = "";  | 
|         for (int i = 0; i < keys.size(); i++ )  | 
|         {  | 
|             String key = keys.get(i);  | 
|             Object value = (Object)paramMap.get(key);  | 
|             if (i == keys.size() - 1)  | 
|             {// 拼接时,不包括最后一个&字符  | 
|                 prestr = prestr + key + "=" + value;  | 
|             }  | 
|             else  | 
|             {  | 
|                 prestr = prestr + key + "=" + value + "&";  | 
|             }  | 
|         }  | 
|         return prestr;  | 
|     }  | 
|   | 
|     private static String getNonce_str()  | 
|     {  | 
|         String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";  | 
|         Random random = new Random();  | 
|         StringBuilder sb = new StringBuilder();  | 
|         for (int i = 0; i < 15; i++ )  | 
|         {  | 
|             int number = random.nextInt(base.length());  | 
|             sb.append(base.charAt(number));  | 
|         }  | 
|         return sb.toString();  | 
|     }  | 
|   | 
| }  |