springboot 使用 RestTemplate 攜帶 微信API證書發送請求實現企業付款到零錢/提現/微信退款等場景


 

springboot版本:

2.2.0.BUILD-SNAPSHOT

 

可使用場景:企業付款到零錢/提現/微信退款等場景

 

企業提現零錢付款場景下:

下面是能跑通的代碼,減少踩坑時間.

兩套方案:一套使用注入bean的方式:

("商戶號".toCharArray(),商戶號就是證書密碼)

@Configuration
public class RestTemplateCert {

    @Qualifier("RestTemplateWithCert")
    @Bean
    public RestTemplate getRestTemplateWithCert() {

        RestTemplate restTemplate = null;
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");//eg. PKCS12
//            這個之前嘗試放在resources目錄下來讀取,結果這個居然是證書錯誤的源頭,使用下面的直接從路徑讀取就能成功了,證書讀取有問題spring沒有報錯,大坑
//            InputStream cp = this.getClass().getResourceAsStream("apiclient_cert.p12");
            FileInputStream instream = new FileInputStream(new File("C:\\extend\\apiclient_cert.p12"));
            keyStore.load(instream, "商戶號".toCharArray());
            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContextBuilder.create()
                    .loadKeyMaterial(keyStore, "商戶號".toCharArray())
                    .build();
            // Allow TLSv1 protocol only
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, NoopHostnameVerifier.INSTANCE);
            CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
            HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
            restTemplate = new RestTemplate(factory);
            //將轉換器的編碼換成utf-8
            restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("utf-8")));
            //System.out.println("restTemplate.hashCode():" + restTemplate.hashCode());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return restTemplate;
    }

    @Primary
    @Bean
    public RestTemplate getRestTemplate() {
        RestTemplate restTemplate = new RestTemplate();

        //將轉換器的編碼換成utf-8
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("utf-8")));
        return restTemplate;
    }

}

 

攜帶微信api證書:
    @Qualifier("RestTemplateWithCert")
    @Resource
    private RestTemplate restTemplateWithCert;

常規請求:
    @Resource
    private RestTemplate restTemplate;

 

微信提現請求:

     HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        String body = "xml數據";
        String url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
        HttpEntity<String> request = new HttpEntity<>(body, headers);
        ResponseEntity<String> res = restTemplateWithCert.postForEntity(url, request, String.class);
        System.out.println(res.getBody());

 

第二個解決方案:

需要依賴:

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.3</version>
        </dependency>

 

public class WxSSLTestTemplate {

    public static String TransferRestTemplate(String url, String data) throws KeyStoreException, IOException, UnrecoverableKeyException, KeyManagementException, CertificateException, NoSuchAlgorithmException {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        FileInputStream instream = new FileInputStream(new File("C:\\extend\\apiclient_cert.p12"));
        keyStore.load(instream, "商戶號".toCharArray());
        // Trust own CA and all self-signed certs
        SSLContext sslcontext = SSLContextBuilder.create()
                .loadKeyMaterial(keyStore, "商戶號".toCharArray())
                .build();
        // Allow TLSv1 protocol only
        HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"},
                null, hostnameVerifier);

        CloseableHttpClient httpclient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .build();

        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpclient);
        RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Connection", "keep-alive");
        requestHeaders.add("Accept", "*/*");
        requestHeaders.add("Content-Type", "application/x-www-form-urlencoded");
        requestHeaders.add("Host", "api.mch.weixin.qq.com");
        requestHeaders.add("X-Requested-With", "XMLHttpRequest");
        requestHeaders.add("Cache-Control", "max-age=0");
        requestHeaders.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");

//        如果使用這個方法,就不能使用下面的這個實例化,而要使用下面第一條使用中的request,否則會報jackson的錯誤,就算配置忽略bean的檢測也沒用
//        org.springframework.http.HttpEntity<String> requestEntity =
//                new org.springframework.http.HttpEntity(new StringEntity(data, "UTF-8"), requestHeaders);

        HttpEntity<String> request = new HttpEntity<>(data, requestHeaders);
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
        return response.getBody();
    }

}

 

微信提現請求:

        String body = "xml數據";
        String url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
        String result = WxSSLTestTemplate.TransferRestTemplate(url, body);
        System.out.println(result);

 

這樣就可以完美跑通了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM