前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

1、组织xml和发起请求


    @Override
    public String payForCompany() {



        SortedMap<Object, Object> sortedMap = new TreeMap<Object, Object>();

        sortedMap.put("mch_appid", "appid");
        sortedMap.put("mchid", "商户号"); 
        sortedMap.put("nonce_str", UUIDGenerator.generate()); //随机字符串,//随机字符串,不长于32位   微信支付API接口协议中包含字段nonce_str,主要保证签名不可预测。我们推荐生成随机数算法如下:调用随机数函数生成,将得到的值转换为字符串。
        sortedMap.put("partner_trade_no", OrderCoderUtil.getOrderCode(1L)); //商户订单号,需保持唯一性(只能是字母或者数字,不能包含有符号)
        sortedMap.put("openid", "某用户的openid"); 
//        sortedMap.put("check_name", "NO_CHECK"); //校验用户姓名选项	 NO_CHECK:不校验真实姓名,FORCE_CHECK:强校验真实姓名
        sortedMap.put("check_name", "FORCE_CHECK"); //校验用户姓名选项	 NO_CHECK:不校验真实姓名,FORCE_CHECK:强校验真实姓名
        sortedMap.put("re_user_name", "HealerJean"); //收款用户姓名  收款用户真实姓名。 如果check_name设置为FORCE_CHECK,则必填用户真实姓名

        sortedMap.put("amount", "100"); //金额,企业付款金额,单位为分
        sortedMap.put("desc", "HealerJean测试付款"); //企业付款描述信息 企业付款操作说明信息。必填。
        try {
            sortedMap.put("spbill_create_ip", InetAddress.getLocalHost().getHostAddress()); //本机 Ip地址	 该IP同在商户平台设置的IP白名单中的IP没有关联,该IP可传用户端或者服务端的IP。
        } catch (UnknownHostException e) {
            throw  new AppException(e.getMessage());
        }

        String requestUrl = WechatApiUrlParams.PAY_QIYE_URL;


        String characterEncoding = "UTF-8";
        String mySign = PayCommonHttpXmlUtil.createSign(characterEncoding, sortedMap, "Secret");
        sortedMap.put("sign", mySign); //签名


        String requestXml = XmlUtil.SortedMap2XmlString(sortedMap);
        log.info("\n微信支付请求的xml为\n"+requestXml);

        // 调用统一下单接口
        String resultXml = PayCommonHttpXmlUtil.httpsRequest(requestUrl,"POST",requestXml, weChatMerchant.getMchPassWord());

        Map<String,String> map = XmlUtil.wechatXmlToMap(resultXml) ;
        if(StringUtils.equals("FAIL",map.get("result_code") )){  //返回报错
            throw  new AppException(map.get("err_code")+":"+EnumPayErrorType.getDes(map.get("err_code")));
        }

        return XmlUtil.xml2JSONObject(resultXml).toString();

    }

2、签名制作



/**
 * 微信支付签名算法sign
 *
 * @param characterEncoding
 * @param parameters
 * @return
 */
public static String createSign(String characterEncoding, SortedMap<Object, Object> parameters, String secret ) {
    StringBuffer sb = new StringBuffer();
    Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)
    Iterator it = es.iterator();
    while (it.hasNext()) {
        Map.Entry entry = (Map.Entry) it.next();
        String k = (String) entry.getKey();
        Object v = entry.getValue();
        if (null != v && !"".equals(v)
                && !"sign".equals(k) && !"key".equals(k)) {
            sb.append(k + "=" + v + "&");
        }
    }

    sb.append("key=" + secret); //key为商户平台设置的密钥key
    String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
    return sign;
}


3、发起xml请求


/**
 * 发送https请求
 *
 * @param requestUrl  请求地址
 * @param method  请求方式(GET、POST)
 * @param xmlParam 提交的数据
 * @return 返回微信服务器响应的信息
 */
public static String httpsRequest(String requestUrl, String method, String xmlParam,String keyStorePassword) {
    try
        {
        // 证书 密码默认是商户号
        char[] password = keyStorePassword.toCharArray();

        ClassPathResource resource = new ClassPathResource("cert/wechat/apiclient_cert.p12");
        InputStream certinputStream = resource.getInputStream();
        KeyStore ks = KeyStore.getInstance("PKCS12");
        ks.load(certinputStream, password);

        // 实例化密钥库 & 初始化密钥工厂
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(ks, password);

        // 创建 SSLContext
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());
        SSLSocketFactory ssf = sslContext.getSocketFactory();



        URL url = new URL(requestUrl);
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setSSLSocketFactory(ssf); //证书
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setUseCaches(false);
        // 设置请求方式(GET/POST)
        conn.setRequestMethod(method);
        conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
        // 当outputStr不为null时向输出流写数据
        if (null != xmlParam)
        {
            OutputStream outputStream = conn.getOutputStream();
            // 注意编码格式
            outputStream.write(xmlParam.getBytes("UTF-8"));
            outputStream.close();
        }
        // 从输入流读取返回内容
        InputStream inputStream = conn.getInputStream();
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String str = null;
        StringBuffer buffer = new StringBuffer();
        while ((str = bufferedReader.readLine()) != null) {
            buffer.append(str);
        }
        // 释放资源
        bufferedReader.close();
        inputStreamReader.close();
        inputStream.close();
        inputStream = null;
        conn.disconnect();
        return buffer.toString();
    }  catch (ConnectException ce) {
        ExceptionLogUtils.log(ce,PayCommonHttpXmlUtil.class );
    }   catch (IOException e) {
          ExceptionLogUtils.log(e,PayCommonHttpXmlUtil.class );
     }catch (Exception e) {
        ExceptionLogUtils.log(e,PayCommonHttpXmlUtil.class );
    }
    return null;
}


ContactAuthor