微信支付xml(V2)


import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.net.ssl.HttpsURLConnection;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.*;

/**
 * WeiXinPayUtil
 */
@Component
@Slf4j
public class WeiXinPayUtil {

    @Autowired
    private WeiXinPayConfig weiXinPayConfig;

    public String createSign(Map<String, Object> paramsMap) {
        StringBuffer buffer = new StringBuffer();
        //参数按照ACCSII排序(升序)
        Set set = paramsMap.entrySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            String key = (String) entry.getKey();
            String value = (String) entry.getValue();
            if (!key.equals("sign") && !StringUtils.isEmpty(value)) {
                buffer.append(key + "=" + value + "&");
            }
        }
        buffer.append("key=" + weiXinPayConfig.getWxKey());
        String sign = MD5Utils.MD5Encode(buffer.toString(), "UTF-8").toUpperCase();
        return sign;
    }

    /**
     * @Description: 组装微信支付请求报文
     */
    public String tenPayXmlInfo(Map<String, Object> paramsMap) {
        StringBuffer buffer = new StringBuffer();
        if (paramsMap != null) {
            buffer.append("<xml>");
            for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
                buffer.append("<").append(entry.getKey()).append("><![CDATA[").append(entry.getValue()).append("]]></").append(entry.getKey()).append(">");
            }
            buffer.append("</xml>");
        }
        return buffer.toString();
    }

    /**
     * @Description: 请求调用URL
     */
    public String httpsRequest(String requestUrl, String requestMethod, String output) {
        StringBuffer buffer = new StringBuffer();
        HttpsURLConnection connection = null;
        InputStream inputStream = null;
        BufferedReader bufferedReader = null;
        InputStreamReader inputStreamReader = null;
        try {
            URL url = null;
            url = new URL(requestUrl);
            connection = (HttpsURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod(requestMethod);
            if (!StringUtils.isEmpty(output)) {
                OutputStream outputStream = connection.getOutputStream();
                outputStream.write(output.getBytes("UTF-8"));
                outputStream.close();
            }
            inputStream = connection.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                inputStreamReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            connection.disconnect();
        }
        return buffer.toString();

    }

    /**
     * @Description: 解析xml
     */
    public Map<String, String> readXml(String xml, String rootName, String rowName) {
        XStream xStream = new XStream(new DomDriver());
        XStream.setupDefaultSecurity(xStream);
        xStream.allowTypesByWildcard(new String[]{"com.qql.**"});
        xStream.alias(rootName, Map.class);
        xStream.registerConverter(new WeiXinPayUtil.MapEntryConverter(rowName));
        Map<String, String> map = (Map<String, String>) xStream.fromXML(xml);
        return map;
    }

    /**
     * @Description: 内部类, readXml专用
     */
    public static class MapEntryConverter implements Converter {

        private String rowName;

        public MapEntryConverter(String rowName) {
            this.rowName = rowName;
        }

        @Override
        public boolean canConvert(Class clazz) {
            return Map.class.isAssignableFrom(clazz) || LinkedHashMap.class.isAssignableFrom(clazz);
        }

        @Override
        public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
            this._marshal(value, writer, context);
        }

        @Override
        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
            return this._unmarshal(reader, context);
        }

        private void _marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
            Iterator i$;
            Object object;
            if (value instanceof Map) {
                Map map = (Map) value;
                for (i$ = map.entrySet().iterator(); i$.hasNext(); writer.endNode()) {
                    object = i$.next();
                    Map.Entry entry = (Map.Entry) object;
                    Object _key = entry.getKey();
                    Object _value = entry.getValue();
                    writer.startNode(entry.getKey().toString());
                    if (_value instanceof Map) {
                        this._marshal(_value, writer, context);
                    } else if (_value instanceof List) {
                        this._marshal(_value, writer, context);
                    } else {
                        writer.setValue(entry.getValue().toString());
                    }
                }
            } else if (value instanceof List) {
                List list = (List) value;

                for (i$ = list.iterator(); i$.hasNext(); writer.endNode()) {
                    object = i$.next();
                    writer.startNode(this.rowName);
                    if (!(object instanceof Map) && !(object instanceof List)) {
                        writer.setValue(object.toString());
                    } else {
                        this._marshal(object, writer, context);
                    }
                }
            }

        }


        public Object _unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
            Map map = new HashMap();
            List list = new ArrayList();

            boolean isList;
            for (isList = false; reader.hasMoreChildren(); reader.moveUp()) {
                reader.moveDown();
                String nodeName = reader.getNodeName();
                if (reader.hasMoreChildren()) {
                    if (isList) {
                        list.add(this._unmarshal(reader, context));
                    } else if (map.containsKey(nodeName)) {
                        isList = true;
                        list.add(map.remove(nodeName));
                        list.add(this._unmarshal(reader, context));
                    } else if (this.rowName.equals(nodeName)) {
                        isList = true;
                        list.add(this._unmarshal(reader, context));
                    } else {
                        map.put(nodeName, this._unmarshal(reader, context));
                    }
                } else {
                    String value = reader.getValue();
                    if (isList) {
                        list.add(value);
                    } else if (map.containsKey(nodeName)) {
                        isList = true;
                        list.add(map.remove(nodeName));
                        list.add(value);
                    } else if (this.rowName.equals(nodeName)) {
                        isList = true;
                        list.add(value);
                    } else {
                        map.put(nodeName, value);
                    }
                }
            }
            return isList ? list : map;
        }
    }

    public String getMapToXML(Map<String, String> param) {
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        for (Map.Entry<String, String> entry : param.entrySet()) {
            sb.append("<" + entry.getKey() + ">");
            sb.append(entry.getValue());
            sb.append("</" + entry.getKey() + ">");
        }
        sb.append("</xml>");
        return sb.toString();
    }

    /**
     * 微信订单回调
     *
     * @param request
     * @return
     */
    public Map<String, String> notify(HttpServletRequest request) {
        try (ServletInputStream inputStream = request.getInputStream()) {
            StringBuffer buffer = new StringBuffer();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            Map<String, String> payBackInfo = this.readXml(buffer.toString(), "xml", "");
            TreeMap<String, Object> treeMap = new TreeMap<>(payBackInfo);
            String sign = this.createSign(treeMap);
            if (!sign.equals(treeMap.get("sign"))) {
                log.error(ConstantKey.SUBJECT + "-微信支付回调,签名错误,订单编号:{}", treeMap.get("out_trade_no"));
                return null;
            }
            if (ConstantKey.SUCCESS.equals(treeMap.get("return_code"))) {
                String tradeNo = (String) treeMap.get("transaction_id");
                String totalFee = (String) treeMap.get("total_fee");
                log.debug(ConstantKey.SUBJECT + "-微信支付完成回调,微信支付流水号transaction_id:{} 支付金额:{}", tradeNo, totalFee);
                return payBackInfo;
            } else {
                log.error(ConstantKey.SUBJECT + "-微信支付回调错误,自定义订单号:{},返回信息:{}", treeMap.get("out_trade_no"), treeMap.get("return_msg"));
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return null;
    }


    /**
     * 调用微信支付接口
     *
     * @param sortedMap
     * @return
     */
    public Map<String, String> weChatPay(Map<String, Object> sortedMap) {
        try {
            String xmlInfo = this.tenPayXmlInfo(sortedMap);
            String payRequest = this.httpsRequest(weiXinPayConfig.getWxPayUrl(), "POST", xmlInfo);
            Map<String, String> map = this.readXml(payRequest, "xml", "");
            String returnCode = map.get("return_code");
            String resultCode = map.get("result_code");
            String returnMsg = map.get("return_msg");
            if (ConstantKey.SUCCESS.equals(returnCode) && ConstantKey.SUCCESS.equals(resultCode) && "OK".equals(returnMsg)) {
                return map;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return null;
    }

    /**
     * 参数封装返回带签名的Map
     *
     * @param outTradeNo
     * @param totalFee
     * @param notifyUrl
     * @param openId
     * @param loginIp
     * @return
     */
    public Map<String, Object> customSortedMap(String outTradeNo, String totalFee, String notifyUrl, String openId, String loginIp) {
        try {
            Map<String, Object> sortedMap = new TreeMap<>();
            sortedMap.put("appid", org.apache.commons.lang3.StringUtils.isNotBlank(openId) ? ConstantKey.mini_weiAppId : weiXinPayConfig.getWxAppId());
            sortedMap.put("mch_id", weiXinPayConfig.getWxMchId());
            sortedMap.put("nonce_str", RandomStringUtils.randomAlphanumeric(20));
            if (org.apache.commons.lang3.StringUtils.isNotBlank(openId)) {
                sortedMap.put("openid", openId);
            }
            sortedMap.put("body", ConstantKey.SUBJECT);
            sortedMap.put("out_trade_no", outTradeNo);
            sortedMap.put("total_fee", totalFee);
            sortedMap.put("notify_url", org.apache.commons.lang3.StringUtils.isNotBlank(notifyUrl) ? notifyUrl : weiXinPayConfig.getWxNotifyUrl());
            sortedMap.put("trade_type", org.apache.commons.lang3.StringUtils.isNotBlank(openId) ? ConstantKey.JSAPI : ConstantKey.APP);
            sortedMap.put("sign_type", "MD5");
            sortedMap.put("spbill_create_ip", loginIp);
            String sign = this.createSign(sortedMap);
            sortedMap.put("sign", sign);
            return sortedMap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 查询支付状态
     *
     * @param orderId
     * @return
     */
    public Map<String, String> checkWeChatNotify(String orderId) {
        try {
            String appId = weiXinPayConfig.getWxAppId();
            String mchId = weiXinPayConfig.getWxMchId();
            String nonceStr = RandomStringUtils.randomAlphanumeric(20);
            Map<String, Object> sortedMap = new TreeMap<>();
            sortedMap.put("appid", appId);
            sortedMap.put("mch_id", mchId);
            sortedMap.put("nonce_str", nonceStr);
            sortedMap.put("out_trade_no", orderId);
            sortedMap.put("sign_type", ConstantKey.MD5);
            String sign = this.createSign(sortedMap);
            sortedMap.put("sign", sign);
            String xmlInfo = this.tenPayXmlInfo(sortedMap);
            String queryUrl = weiXinPayConfig.getWxQueryUrl();
            String payRequest = this.httpsRequest(queryUrl, "POST", xmlInfo);
            Map<String, String> map = this.readXml(payRequest, "xml", "");
            String returnCode = map.get("return_code");
            String resultCode = map.get("result_code");
            String tradeState = map.get("trade_state");
            if (ConstantKey.SUCCESS.equals(returnCode) && ConstantKey.SUCCESS.equals(resultCode) && ConstantKey.SUCCESS.equals(tradeState)) {
                return map;
            }
        } catch (Exception e) {
            return null;
        }
        return null;
    }

    /**
     * 调起支付参数签名
     *
     * @param map
     * @param nonceStr
     * @param timestamp
     * @return
     */
    public String getNewSign(Map<String, String> map, String nonceStr, String timestamp) {
        Map<String, Object> returnMap = new TreeMap<>();
        returnMap.put("appid", map.get("appid"));
        returnMap.put("partnerid", map.get("mch_id"));
        returnMap.put("prepayid", map.get("prepay_id"));
        returnMap.put("package", ConstantKey.SIGN_WXPAY);
        returnMap.put("noncestr", nonceStr);
        returnMap.put("timestamp", timestamp);
        String newSign = this.createSign(returnMap);
        return newSign;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值