1111import com .github .binarywang .wxpay .bean .request .*;
1212import com .github .binarywang .wxpay .bean .result .*;
1313import com .github .binarywang .wxpay .config .WxPayConfig ;
14+ import com .github .binarywang .wxpay .constant .WxPayConstants ;
1415import com .github .binarywang .wxpay .constant .WxPayConstants .BillType ;
1516import com .github .binarywang .wxpay .constant .WxPayConstants .SignType ;
1617import com .github .binarywang .wxpay .constant .WxPayConstants .TradeType ;
1718import com .github .binarywang .wxpay .exception .WxPayException ;
1819import com .github .binarywang .wxpay .service .WxPayService ;
1920import com .github .binarywang .wxpay .util .SignUtils ;
21+ import com .google .common .base .Joiner ;
2022import com .google .common .collect .Maps ;
23+ import jodd .io .ZipUtil ;
24+ import jodd .util .Base64 ;
2125import org .apache .commons .lang3 .StringUtils ;
26+ import org .apache .http .auth .AuthScope ;
27+ import org .apache .http .auth .UsernamePasswordCredentials ;
28+ import org .apache .http .client .CredentialsProvider ;
29+ import org .apache .http .client .config .RequestConfig ;
30+ import org .apache .http .client .methods .CloseableHttpResponse ;
31+ import org .apache .http .client .methods .HttpPost ;
32+ import org .apache .http .conn .ssl .DefaultHostnameVerifier ;
33+ import org .apache .http .conn .ssl .SSLConnectionSocketFactory ;
34+ import org .apache .http .entity .StringEntity ;
35+ import org .apache .http .impl .client .BasicCredentialsProvider ;
36+ import org .apache .http .impl .client .CloseableHttpClient ;
37+ import org .apache .http .impl .client .HttpClientBuilder ;
38+ import org .apache .http .impl .client .HttpClients ;
39+ import org .apache .http .util .EntityUtils ;
2240import org .slf4j .Logger ;
2341import org .slf4j .LoggerFactory ;
2442
43+ import javax .net .ssl .SSLContext ;
2544import java .io .File ;
45+ import java .io .IOException ;
46+ import java .nio .charset .StandardCharsets ;
47+ import java .nio .file .Files ;
48+ import java .nio .file .Path ;
49+ import java .nio .file .Paths ;
2650import java .util .*;
51+ import java .util .zip .ZipException ;
2752
2853import static com .github .binarywang .wxpay .constant .WxPayConstants .QUERY_COMMENT_DATE_FORMAT ;
54+ import static com .github .binarywang .wxpay .constant .WxPayConstants .TarType ;
2955
3056/**
3157 * <pre>
@@ -61,7 +87,17 @@ private String getPayBaseUrl() {
6187 }
6288
6389 /**
64- * 发送post请求
90+ * 发送post请求,得到响应字节数组
91+ *
92+ * @param url 请求地址
93+ * @param requestStr 请求信息
94+ * @param useKey 是否使用证书
95+ * @return 返回请求结果字节数组
96+ */
97+ protected abstract byte [] postForBytes (String url , String requestStr , boolean useKey ) throws WxPayException ;
98+
99+ /**
100+ * 发送post请求,得到响应字符串
65101 *
66102 * @param url 请求地址
67103 * @param requestStr 请求信息
@@ -410,6 +446,10 @@ public void report(WxPayReportRequest request) throws WxPayException {
410446
411447 @ Override
412448 public WxPayBillResult downloadBill (String billDate , String billType , String tarType , String deviceInfo ) throws WxPayException {
449+ if (!BillType .ALL .equals (billType )) {
450+ throw new WxPayException ("目前仅支持ALL类型的对账单下载" );
451+ }
452+
413453 WxPayDownloadBillRequest request = new WxPayDownloadBillRequest ();
414454 request .setBillType (billType );
415455 request .setBillDate (billDate );
@@ -419,15 +459,52 @@ public WxPayBillResult downloadBill(String billDate, String billType, String tar
419459 request .checkAndSign (this .getConfig (), false );
420460
421461 String url = this .getPayBaseUrl () + "/pay/downloadbill" ;
422- String responseContent = this .post (url , request .toXML (), false );
423- if (responseContent .startsWith ("<" )) {
424- throw WxPayException .from (WxPayBaseResult .fromXML (responseContent , WxPayCommonResult .class ));
462+
463+ String responseContent ;
464+ if (TarType .GZIP .equals (tarType )) {
465+ responseContent = this .handleGzipBill (url , request .toXML ());
466+ } else {
467+ responseContent = this .post (url , request .toXML (), false );
468+ if (responseContent .startsWith ("<" )) {
469+ throw WxPayException .from (WxPayBaseResult .fromXML (responseContent , WxPayCommonResult .class ));
470+ }
471+ }
472+
473+ return this .handleBill (billType , responseContent );
474+ }
475+
476+ private WxPayBillResult handleBill (String billType , String responseContent ) {
477+ if (!BillType .ALL .equals (billType )) {
478+ return null ;
425479 }
426480
427- return this .handleBillInformation (responseContent );
481+ return this .handleAllBill (responseContent );
482+ }
483+
484+ private String handleGzipBill (String url , String requestStr ) throws WxPayException {
485+ try {
486+ byte [] responseBytes = this .postForBytes (url , requestStr , false );
487+ Path tempDirectory = Files .createTempDirectory ("bill" );
488+ Path path = Paths .get (tempDirectory .toString (), System .currentTimeMillis () + ".gzip" );
489+ Files .write (path , responseBytes );
490+ try {
491+ List <String > allLines = Files .readAllLines (ZipUtil .ungzip (path .toFile ()).toPath (), StandardCharsets .UTF_8 );
492+ return Joiner .on ("\n " ).join (allLines );
493+ } catch (ZipException e ) {
494+ if (e .getMessage ().contains ("Not in GZIP format" )) {
495+ throw WxPayException .from (WxPayBaseResult .fromXML (new String (responseBytes , StandardCharsets .UTF_8 ),
496+ WxPayCommonResult .class ));
497+ } else {
498+ this .log .error ("解压zip文件出错" , e );
499+ }
500+ }
501+ } catch (IOException e ) {
502+ e .printStackTrace ();
503+ }
504+ return null ;
428505 }
429506
430- private WxPayBillResult handleBillInformation (String responseContent ) {
507+ private WxPayBillResult handleAllBill (String responseContent ) {
431508 WxPayBillResult wxPayBillResult = new WxPayBillResult ();
432509
433510 String listStr = "" ;
@@ -444,11 +521,16 @@ private WxPayBillResult handleBillInformation(String responseContent) {
444521 * 参考以上格式进行取值
445522 */
446523 List <WxPayBillBaseResult > wxPayBillBaseResultLst = new LinkedList <>();
447- String newStr = listStr .replaceAll ("," , " " ); // 去空格
448- String [] tempStr = newStr .split ("`" ); // 数据分组
449- String [] t = tempStr [0 ].split (" " );// 分组标题
450- int j = tempStr .length / t .length ; // 计算循环次数
451- int k = 1 ; // 纪录数组下标
524+ // 去空格
525+ String newStr = listStr .replaceAll ("," , " " );
526+ // 数据分组
527+ String [] tempStr = newStr .split ("`" );
528+ // 分组标题
529+ String [] t = tempStr [0 ].split (" " );
530+ // 计算循环次数
531+ int j = tempStr .length / t .length ;
532+ // 纪录数组下标
533+ int k = 1 ;
452534 for (int i = 0 ; i < j ; i ++) {
453535 WxPayBillBaseResult wxPayBillBaseResult = new WxPayBillBaseResult ();
454536
0 commit comments