Spring-Boot

微信支付(APP支付)之服务端

2019-11-22  本文已影响0人  王传贺

一: 项目背景

最近和朋友一起做了一款APP ,涉及到微信支付, 简单记录一下微信支付服务端流程
微信支付的难点在于没有测试账号,无客服,这点远不如支付宝友好,网上搜索的微信支付千篇一律,对初学者很不友好,因此踩了很多坑。本文从账号的注册,代码的编写详细介绍。

二: 账号注册

微信支付是需要审核资质,拥有营业执照的个体户即可申请。值得注意的是,申请账号关联相关身份必须与营业执照一致。
注册方式开发总结如下,按照流程注册即可
若app需要接入微信支付,需要先注册并认证开放平台(https://open.weixin.qq.com/)账号,才能生成appid,然后再注册商户平台(https://pay.weixin.qq.com)账号,获取商户号、密钥等,申请成功后,请通过微信支付商户平台发起appid授权绑定(https://kf.qq.com/faq/1801116VJfua1801113QVNVz.html),微信支付开发文档地址为:https://pay.weixin.qq.com/wiki/doc/api/index.html

三:微信支付接口调试

注意代码注释结合,微信支付开发文档查看
常量类

/**
 * created by wangch on 2019/8/9
 */
public class ConstantUtil {

    /**
     * 微信开发平台应用ID
     */
    public static final String APP_ID="";
    /**
     * 应用对应的凭证
     */
    public static final String APP_SECRET="";
    /**
     * 应用对应的密钥
     */
    public static final String APP_KEY="";
    /**
     * 微信支付商户号
     */
    public static final String MCH_ID="1557353761";
    /**
     * 商品描述
     */
    public static final String BODY="QQ游戏-账户充值";
    /**
     * 商户号对应的密钥
     */
    public static final String PARTNER_key="123466";

    /**
     * 商户id
     */
    public static final String PARTNER_ID="";
    /**
     * 常量固定值
     */
    public static final String GRANT_TYPE="client_credential";
    /**
     * 获取预支付id的接口url
     */
    public static String GATEURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    /**
     * 微信服务器回调通知url
     */
    public static String NOTIFY_URL="ip:8080/order/pay/notify";
}

接口类

@RestController
@RequestMapping("/order")
public class PayController {

    private static final Logger LOG = Logger.getLogger(PayController.class);

    private static final String ORDER_PAY = "https://api.mch.weixin.qq.com/pay/unifiedorder"; // 统一下单

    private static final String ORDER_PAY_QUERY = "https://api.mch.weixin.qq.com/pay/orderquery"; // 支付订单查询

    private static final String ORDER_REFUND = "https://api.mch.weixin.qq.com/secapi/pay/refund"; // 申请退款

    private static final String ORDER_REFUND_QUERY = "https://api.mch.weixin.qq.com/pay/refundquery"; // 申请退款

    private static final String APP_ID = ConstantUtil.APP_ID;

    private static final String MCH_ID = ConstantUtil.MCH_ID;

    private static final String API_SECRET = ConstantUtil.APP_KEY;

    @Autowired
    private IOrderService iOrderService;

    /**
     * 支付下订单
     *
     * @param request
     * @param response
     * @RequestParam(required = false, defaultValue = "0") Double cashnum, String mercid, String callback

     */
    @RequestMapping(value = "/pay", method = RequestMethod.POST)
    public R orderPay(@RequestBody Order order, HttpServletRequest request, HttpServletResponse response) {
        LOG.info("[/order/pay]");
//        if (!"001".equals(mercid)) {
//            WebUtil.response(response, WebUtil.packJsonp(callback, JSON
//                    .toJSONString(new JsonResult(-1, "商品不存在", new ResponseData()), SerializerFeatureUtil.FEATURES)));
//        }

        Map<String, String> restmap = null;
        boolean flag = true; // 是否订单创建成功
        try {
            String total_fee = BigDecimal.valueOf(order.getPrice()).multiply(BigDecimal.valueOf(100))
                    .setScale(0, BigDecimal.ROUND_HALF_UP).toString();
            Map<String, String> parm = new HashMap<String, String>();
            parm.put("appid", APP_ID);
            parm.put("mch_id", MCH_ID);
            parm.put("device_info", "WEB");
            parm.put("nonce_str", PayUtil.getNonceStr());
            parm.put("body", "微信支付");
            parm.put("attach", "wangch");
            // PayUtil.getTradeNo
            parm.put("out_trade_no", order.getCode());
            // String.valueOf(order.getPrice())
            parm.put("total_fee", total_fee);
            parm.put("spbill_create_ip", PayUtil.getRemoteAddrIp(request));
            // "https://www.andy.org/wxpay/order/pay/notify.shtml"
            parm.put("notify_url",ConstantUtil.NOTIFY_URL );
            parm.put("trade_type", "APP");
            parm.put("sign", PayUtil.getSign(parm, API_SECRET));

            String restxml = HttpUtils.post(ORDER_PAY, XmlUtil.xmlFormat(parm, false));
            restmap = XmlUtil.xmlParse(restxml);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
        }

        Map<String, String> payMap = new HashMap<String, String>();
        if (CollectionUtil.isNotEmpty(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {
            payMap.put("appid", APP_ID);
            payMap.put("partnerid", MCH_ID);
            payMap.put("prepayid", restmap.get("prepay_id"));
            payMap.put("package", "Sign=WXPay");
            payMap.put("noncestr", PayUtil.getNonceStr());
            payMap.put("timestamp", PayUtil.payTimestamp());
            try {
                payMap.put("sign", PayUtil.getSign(payMap, API_SECRET));
            } catch (Exception e) {
                flag = false;
            }
        }

//        if (flag) {
//            //return new R().put("获取成功",new ResponseData(null, payMap));
//            WebUtil.response(response,
//                    WebUtil.packJsonp("data",
//                            JSON.toJSONString(new JsonResult(1, "订单获取成功", new ResponseData(null, payMap)),
//                                    SerializerFeatureUtil.FEATURES)));
//        } else {
//            if (CollectionUtil.isNotEmpty(restmap)) {
//               //return new R().put("订单创建失败",new ResponseData(null, payMap));
//               LOG.info("订单创建失败:" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
//            }
//            WebUtil.response(response, WebUtil.packJsonp(order.getCode(), JSON
//                    .toJSONString(new JsonResult(-1, "订单获取失败", new ResponseData()), SerializerFeatureUtil.FEATURES)));
//            //return new R().put("订单获取失败",new ResponseData());
//        }
        R r = new R();
        if (flag){
            return r.put("data",payMap);
        } else {

            return R.error("获取失败");
        }

    }


    /**
     * 查询支付结果
     *
     * @param request
     * @param response
     * @param tradeid  微信交易订单号
     * @param tradeno 商品订单号
     * @param callback
     */
    @RequestMapping(value = "/pay/query", method = RequestMethod.POST)
    public R orderPayQuery(HttpServletRequest request, HttpServletResponse response,Integer orderId) {
        LOG.info("[/order/pay/query]");
//        if (StringUtil.isEmpty(tradeno) && StringUtil.isEmpty(tradeid)) {
//            WebUtil.response(response, WebUtil.packJsonp(callback, JSON
//                    .toJSONString(new JsonResult(-1, "订单号不能为空", new ResponseData()), SerializerFeatureUtil.FEATURES)));
//        }

        // 通过id 获取商户订单号与微信订单号
        Map<String,String> map = iOrderService.getOrderInfoByOrderId(orderId);
        Map<String, String> restmap = null;
        try {
            Map<String, String> parm = new HashMap<String, String>();
            parm.put("appid", APP_ID);
            parm.put("mch_id", MCH_ID);
            parm.put("transaction_id", map.get("tradeNo"));
            parm.put("out_trade_no", map.get("code"));
            parm.put("nonce_str", PayUtil.getNonceStr());
            parm.put("sign", PayUtil.getSign(parm, API_SECRET));

            String restxml = HttpUtils.post(ORDER_PAY_QUERY, XmlUtil.xmlFormat(parm, false));
            restmap = XmlUtil.xmlParse(restxml);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
        }

//        if (CollectionUtil.isNotEmpty(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {
//            // 订单查询成功 处理业务逻辑
//            LOG.info("订单查询:订单" + restmap.get("out_trade_no") + "支付成功");
//            // 将微信订单号存入order 表中
//
//            WebUtil.response(response, WebUtil.packJsonp(callback, JSON
//                    .toJSONString(new JsonResult(1, "订单支付成功", new ResponseData()), SerializerFeatureUtil.FEATURES)));
//        } else {
//            if (CollectionUtil.isNotEmpty(restmap)) {
//                LOG.info("订单支付失败:" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
//            }
//            WebUtil.response(response, WebUtil.packJsonp(callback, JSON
//                    .toJSONString(new JsonResult(-1, "订单支付失败", new ResponseData()), SerializerFeatureUtil.FEATURES)));
//        }
        R r = new R();
        if (CollectionUtil.isNotEmpty(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {
            // 订单查询成功 处理业务逻辑
            iOrderService.updateOrderPayByOrderCode(map.get("code"),1);
            return r.ok();
        }else {
            return R.error("支付失败");
        }
    }


    /**
     * 订单支付微信服务器异步通知
     *
     * @param request
     * @param response
     */
    @RequestMapping("/pay/notify")
    public void orderPayNotify(HttpServletRequest request, HttpServletResponse response) {
        LOG.info("[/order/pay/notify]");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/xml");
        try {
            ServletInputStream in = request.getInputStream();
            String resxml = FileUtil.readInputStream2String(in);
            Map<String, String> restmap = XmlUtil.xmlParse(resxml);
            LOG.info("支付结果通知:" + restmap);
            // 将微信订单号存入order 表中
            iOrderService.insertTradeNo(restmap.get("transaction_id"),restmap.get("out_trade_no"));
            if ("SUCCESS".equals(restmap.get("result_code"))) {
                // 订单支付成功 业务处理
                String out_trade_no = restmap.get("out_trade_no"); // 商户订单号
                // 通过商户订单判断是否该订单已经处理 如果处理跳过 如果未处理先校验sign签名 再进行订单业务相关的处理
                String sing = restmap.get("sign"); // 返回的签名
                restmap.remove("sign");
                String signnow = PayUtil.getSign(restmap, API_SECRET);
                if (signnow.equals(sing)) {
                    // 进行业务处理
                    LOG.info("订单支付通知: 支付成功,订单号" + out_trade_no);
                    // 支付成功
                    int count = iOrderService.updateOrderPayByOrderCode(out_trade_no,1);
                    // 处理成功后相应给响应xml
                    Map<String, String> respMap = new HashMap<>();
                    respMap = new HashMap<String, String>();
                    respMap.put("return_code", "SUCCESS");  //相应给微信服务器
                    respMap.put("return_msg", "OK");
                    String resXml = XmlUtil.xmlFormat(restmap, true);
                    response.getWriter().write(resXml);
                } else {
                    LOG.info("订单支付通知:签名错误");
                }
            } else {
                LOG.info("订单支付通知:支付失败," + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
            }
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
        }
    }

工具类
PayUtil

**
 * created by wangch on 2019/8/9
 */
public class PayUtil {

    /**
     * 生成订单号
     * 
     * @return
     */
    public static String getTradeNo() {
        // 自增8位数 00000001
        return "TNO" + DatetimeUtil.formatDate(new Date(), DatetimeUtil.TIME_STAMP_PATTERN) + "00000001";
    }

    /**
     * 退款单号
     * 
     * @return
     */
    public static String getRefundNo() {
        // 自增8位数 00000001
        return "RNO" + DatetimeUtil.formatDate(new Date(), DatetimeUtil.TIME_STAMP_PATTERN) + "00000001";
    }

    /**
     * 退款单号
     * 
     * @return
     */
    public static String getTransferNo() {
        // 自增8位数 00000001
        return "TNO" + DatetimeUtil.formatDate(new Date(), DatetimeUtil.TIME_STAMP_PATTERN) + "00000001";
    }

    /**
     * 返回客户端ip
     * 
     * @param request
     * @return
     */
    public static String getRemoteAddrIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtil.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值,第一个ip才是真实ip
            int index = ip.indexOf(",");
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (StringUtil.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip;
        }
        return request.getRemoteAddr();
    }

    /**
     * 获取服务器的ip地址
     * 
     * @param request
     * @return
     */
    public static String getLocalIp(HttpServletRequest request) {
        return request.getLocalAddr();
    }

    public static String getSign(Map<String, String> params, String paternerKey) throws UnsupportedEncodingException {
        return MD5Utils.getMD5(createSign(params, false) + "&key=" + paternerKey).toUpperCase();
    }

    /**
     * 构造签名
     * 
     * @param params
     * @param encode
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String createSign(Map<String, String> params, boolean encode) throws UnsupportedEncodingException {
        Set<String> keysSet = params.keySet();
        Object[] keys = keysSet.toArray();
        Arrays.sort(keys);
        StringBuffer temp = new StringBuffer();
        boolean first = true;
        for (Object key : keys) {
            if (key == null || StringUtil.isEmpty(params.get(key))) // 参数为空不参与签名
                continue;
            if (first) {
                first = false;
            } else {
                temp.append("&");
            }
            temp.append(key).append("=");
            Object value = params.get(key);
            String valueStr = "";
            if (null != value) {
                valueStr = value.toString();
            }
            if (encode) {
                temp.append(URLEncoder.encode(valueStr, "UTF-8"));
            } else {
                temp.append(valueStr);
            }
        }
        return temp.toString();
    }

    /**
     * 创建支付随机字符串
     * @return
     */
    public static String getNonceStr(){
        String s = RandomUtil.randomString(RandomUtil.LETTER_NUMBER_CHAR, 32);
        return RandomUtil.randomString(RandomUtil.LETTER_NUMBER_CHAR, 32);
    }
    
    /**
     * 支付时间戳
     * @return
     */
    public static String payTimestamp() {
        String s = Long.toString(System.currentTimeMillis() / 1000);
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}

HttpUtils

**
 * created by wangch on 2019/8/9
 */
public class HttpUtils {

    private static final String DEFAULT_CHARSET = "UTF-8";
    
    private static final int CONNECT_TIME_OUT = 5000; //链接超时时间3秒
    
    private static final RequestConfig REQUEST_CONFIG = RequestConfig.custom().setConnectTimeout(CONNECT_TIME_OUT).build();
    
    private static SSLContext wx_ssl_context = null; //微信支付ssl证书
    
    static{
        Resource resource = new ClassPathResource("wx_apiclient_cert.p12");
        try {
            KeyStore keystore = KeyStore.getInstance("PKCS12");
            char[] keyPassword = ConfigUtil.getProperty("wx.mchid").toCharArray(); //证书密码
            keystore.load(resource.getInputStream(), keyPassword);
            wx_ssl_context = SSLContexts.custom().loadKeyMaterial(keystore, keyPassword).build();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @description 功能描述: get 请求
     * @param url 请求地址
     * @param params 参数
     * @param headers headers参数
     * @return 请求失败返回null
     */
    public static String get(String url, Map<String, String> params, Map<String, String> headers) {

        CloseableHttpClient httpClient = null;
        if (params != null && !params.isEmpty()) {
            StringBuffer param = new StringBuffer();
            boolean flag = true; // 是否开始
            for (Entry<String, String> entry : params.entrySet()) {
                if (flag) {
                    param.append("?");
                    flag = false;
                } else {
                    param.append("&");
                }
                param.append(entry.getKey()).append("=");
                
                try {
                    param.append(URLEncoder.encode(entry.getValue(), DEFAULT_CHARSET));
                } catch (UnsupportedEncodingException e) {
                    //编码失败
                }
            }
            url += param.toString();
        }

        String body = null;
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.custom()
                    .setDefaultRequestConfig(REQUEST_CONFIG)
                    .build();
            HttpGet httpGet = new HttpGet(url);
            response = httpClient.execute(httpGet);
            body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return body;
    }

    /**
     * @description 功能描述: get 请求
     * @param url 请求地址
     * @return 请求失败返回null
     */
    public static String get(String url) {
        return get(url, null);
    }

    /**
     * @description 功能描述: get 请求
     * @param url 请求地址
     * @param params 参数
     * @return 请求失败返回null
     */
    public static String get(String url, Map<String, String> params) {
        return get(url, params, null);
    }

    /**
     * @description 功能描述: post 请求
     * @param url 请求地址
     * @param params 参数
     * @return 请求失败返回null
     */
    public static String post(String url, Map<String, String> params) {
        CloseableHttpClient httpClient = null;
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> nameValuePairs = new ArrayList<>();
        if (params != null && !params.isEmpty()) {
            for (Entry<String, String> entry : params.entrySet()) {
                nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
        }

        String body = null;
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.custom()
                    .setDefaultRequestConfig(REQUEST_CONFIG)
                    .build();
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, DEFAULT_CHARSET));
            response = httpClient.execute(httpPost);
            body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return body;
    }

    /**
     * @description 功能描述: post 请求
     * @param url 请求地址
     * @param s 参数xml
     * @return 请求失败返回null
     */
    public static String post(String url, String s) {
        CloseableHttpClient httpClient = null;
        HttpPost httpPost = new HttpPost(url);
        String body = null;
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.custom()
                    .setDefaultRequestConfig(REQUEST_CONFIG)
                    .build();
            httpPost.setEntity(new StringEntity(s, DEFAULT_CHARSET));
            response = httpClient.execute(httpPost);
            body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return body;
    }

    /**
     * @description 功能描述: post https请求,服务器双向证书验证
     * @param url 请求地址
     * @param params 参数
     * @return 请求失败返回null
     */
     public static String posts(String url, Map<String, String> params) {
        CloseableHttpClient httpClient = null;
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> nameValuePairs = new ArrayList<>();
        if (params != null && !params.isEmpty()) {
            for (Entry<String, String> entry : params.entrySet()) {
                nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
        }

        String body = null;
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.custom()
                    .setDefaultRequestConfig(REQUEST_CONFIG)
                    .setSSLSocketFactory(getSSLConnectionSocket())
                    .build();
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, DEFAULT_CHARSET));
            response = httpClient.execute(httpPost);
            body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return body;
    }
    
    /**
     * @description 功能描述: post https请求,服务器双向证书验证
     * @param url 请求地址
     * @param s 参数xml
     * @return 请求失败返回null
     */
    public static String posts(String url, String s) {
        CloseableHttpClient httpClient = null;
        HttpPost httpPost = new HttpPost(url);
        String body = null;
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.custom()
                    .setDefaultRequestConfig(REQUEST_CONFIG)
                    .setSSLSocketFactory(getSSLConnectionSocket())
                    .build();
            httpPost.setEntity(new StringEntity(s, DEFAULT_CHARSET)); 
            response = httpClient.execute(httpPost);
            body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return body;
    }

    //获取ssl connection链接
    private static SSLConnectionSocketFactory getSSLConnectionSocket() {
        return new SSLConnectionSocketFactory(wx_ssl_context, new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"}, null,
                SSLConnectionSocketFactory.getDefaultHostnameVerifier());
    }
}

XmlUtil

**
 * created by wangch on 2019/8/9
 */
public class XmlUtil {

    private static final String PREFIX_XML = "<xml>";

    private static final String SUFFIX_XML = "</xml>";

    private static final String PREFIX_CDATA = "<![CDATA[";

    private static final String SUFFIX_CDATA = "]]>";

    /**
     * 转化成xml, 单层无嵌套
     * 
     * @param map
     * @param isAddCDATA
     * @return
     */
    public static String xmlFormat(Map<String, String> parm, boolean isAddCDATA) {

        StringBuffer strbuff = new StringBuffer(PREFIX_XML);
        if (CollectionUtil.isNotEmpty(parm)) {
            for (Entry<String, String> entry : parm.entrySet()) {
                strbuff.append("<").append(entry.getKey()).append(">");
                if (isAddCDATA) {
                    strbuff.append(PREFIX_CDATA);
                    if (StringUtil.isNotEmpty(entry.getValue())) {
                        strbuff.append(entry.getValue());
                    }
                    strbuff.append(SUFFIX_CDATA);
                } else {
                    if (StringUtil.isNotEmpty(entry.getValue())) {
                        strbuff.append(entry.getValue());
                    }
                }
                strbuff.append("</").append(entry.getKey()).append(">");
            }
        }
        return strbuff.append(SUFFIX_XML).toString();
    }

    /**
     * 解析xml
     * 
     * @param xml
     * @return
     * @throws XmlPullParserException
     * @throws IOException
     */
    public static Map<String, String> xmlParse(String xml) throws XmlPullParserException, IOException {
        Map<String, String> map = null;
        if (StringUtil.isNotEmpty(xml)) {
            InputStream inputStream = new ByteArrayInputStream(xml.getBytes());
            XmlPullParser pullParser = XmlPullParserFactory.newInstance().newPullParser();
            pullParser.setInput(inputStream, "UTF-8"); // 为xml设置要解析的xml数据
            int eventType = pullParser.getEventType();

            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    map = new HashMap<String, String>();
                    break;
                case XmlPullParser.START_TAG:
                    String key = pullParser.getName();
                    if (key.equals("xml"))
                        break;
                    String value = pullParser.nextText().trim();
                    map.put(key, value);
                    break;
                case XmlPullParser.END_TAG:
                    break;
                }
                eventType = pullParser.next();
            }
        }
        return map;
    }
}

MD5Util

**
 * created by wangch on 2019/8/9
 */
public class MD5Util {

    /**
     * MD5加密
     * @param b
     * @return
     */
    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" };

}

四:总结

上述代码结合微信支付文档很好理解,耐心品味
参考了andy大神的写法,侵删

上一篇下一篇

猜你喜欢

热点阅读