xiaoyong931011
2021-06-22 38609ee05255ce5c36f308fe8d595555a86f9ba3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
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();
    }
 
}