CONMISANMA的正确答案——关于微信支付的退款问题【java】

测试系统:WIN10 x64

IDE工具:netbeans

JDK版本:1.8

 

直接上解决方案:


    /**
     * 获取微信支付的退款结果
     *
     * @param socketAgreement 安全套接字协议(当前微信支持的安全套接字协议为“PKCS12”【20200713091509】)
     * @param certificatePath 证书的系统绝对路径(按微信建议,最好不能随便被外网访问的路径)
     * @param certificatePassword 证书密码(默认为商户号)
     * @param url 退款路径
     * @param data 发送的XML数据
     * @return 申请退款的结果
     * @throws Exception
     */
    public static String getWXPayRefundResult(
            String socketAgreement,
            String certificatePath,
            String certificatePassword,
            String url,
            String data
    ) throws Exception {
        String result = null;

        SSLConnectionSocketFactory sslcsf;
        try (FileInputStream fis = new FileInputStream(certificatePath)) {
            KeyStore keyStore;
            SSLContext sslc;
            SSLContextBuilder sslcb;

            socketAgreement = StringUtils.isBlank(socketAgreement) ? "PKCS12" : socketAgreement;    // 默认为“PKCS12”

            keyStore = KeyStore.getInstance(socketAgreement);                                       // 创建密钥和证书储存器
            keyStore.load(fis, certificatePassword.toCharArray());                                  // 加载证书以及该证书的密码

            sslcb = SSLContexts.custom();                                                           // 创建一个SSL上下文构造器
            sslc = sslcb.loadKeyMaterial(keyStore, certificatePassword.toCharArray()).build();      // 构造器加载储存器并构建

            sslcsf = new SSLConnectionSocketFactory(
                    sslc,
                    new String[]{"TLSv1", "TLSv1.1", "TLSv1.2"},
                    null,
                    new DefaultHostnameVerifier()
            );                                                                                      // 创建SSL连接工厂
        }

        try (CloseableHttpClient chc = HttpClients.custom().setSSLSocketFactory(sslcsf).build()) {
            HttpPost post = new HttpPost(url);                                                  // 创建连接
            post.setEntity(new StringEntity(new String(data.getBytes())));                      // 写入数据
            CloseableHttpResponse chr = chc.execute(post);                                      // 提交数据

            // 读取返回结果
            try (InputStreamReader isr = new InputStreamReader(chr.getEntity().getContent(), "UTF-8");
                    BufferedReader br = new BufferedReader(isr)) {
                String line;
                while ((line = br.readLine()) != null) {
                    result += line;
                }
            }
        }

        return result;
    }

 

坑点:

  1. 微信支付的退款必须使用证书,这个证书的下载和安装过程参考:(https://jingyan.baidu.com/article/ed2a5d1f02ad0649f6be179d.html)
  2. 直接访问退款地址的人几乎都会看到这句话(这里简单说了这个退款必须经过SSL进行连接):
    400 Bad Request
    No required SSL certificate was sent
  3. 证书最好不要外网可以访问的位置~

  4. 如果你的网络有严重的掉包,最好设置一下超时,默认超时一般不会挂。对,没被D/DOS的情况下~,再或者你的机器真的太...,基于这样的问题,你最好还是先进行压力测试,看看你这机器的瓶颈在哪~

  5. 部分代码来自httpclient官网API:(http://hc.apache.org/httpclient-3.x/sslguide.html)

  6. 经常做接口的最好把httpclient吃一遍,你会发现真的很好用~

你可能感兴趣的:(微信支付)