diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/FundBillRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/FundBillRequest.java new file mode 100644 index 0000000000..9f12bc3781 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/FundBillRequest.java @@ -0,0 +1,79 @@ +package com.github.binarywang.wxpay.bean.ecommerce; + +import com.google.gson.annotations.SerializedName; +import lombok.*; + +/** + * 资金账单请求 + * @author: f00lish + * @date: 2020/09/28 + */ +@Data +@Builder +@ToString +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class FundBillRequest { + + /** + *
+ * 字段名:账单日期 + * 变量名:bill_date + * 是否必填:是 + * 类型:string(10) + * 描述: + * 格式YYYY-MM-DD + * 仅支持三个月内的账单下载申请。 + * 示例值:2019-06-11 + *+ */ + @SerializedName(value = "bill_date") + private String billDate; + + + /** + *
+ * 字段名:资金账户类型 + * 变量名:account_type + * 是否必填:是 + * 类型:string(32) + * 描述: + * 枚举值: + * ALL:所有账户 + * 示例值:ALL + *+ */ + @SerializedName(value = "account_type") + private String accountType; + + /** + *
+ * 字段名:压缩类型 + * 变量名:tar_type + * 是否必填:否 + * 类型:string(32) + * 描述: + * 不填则以不压缩的方式返回数据流 + * 枚举值: + * GZIP:返回格式为.gzip的压缩包账单 + * 示例值:GZIP + *+ */ + @SerializedName(value = "tar_type") + private String tarType; + + /** + *
+ * 字段名:加密算法 + * 变量名:algorithm + * 是否必填:是 + * 类型:string(32) + * 描述: + * 枚举值: + * AEAD_AES_256_GCM:AEAD_AES_256_GCM加密算法 + * 示例值:AEAD_AES_256_GCM + *+ */ + @SerializedName(value = "algorithm") + private String algorithm; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/FundBillResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/FundBillResult.java new file mode 100644 index 0000000000..de0dcdb890 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/FundBillResult.java @@ -0,0 +1,139 @@ +package com.github.binarywang.wxpay.bean.ecommerce; + +import com.google.gson.annotations.SerializedName; +import lombok.*; + +/** + * 资金账单结果 + * @author: f00lish + * @date: 2020/09/28 + */ +@Data +@Builder +@ToString +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class FundBillResult { + + /** + *
+ * 字段名:下载信息总数 + * 变量名:download_bill_count + * 是否必填:是 + * 类型:int + * 描述: + * 下载信息总数 + * 示例值:1 + *+ */ + @SerializedName(value = "download_bill_count") + private int downloadBillCount; + + + + /** + *
+ * 字段名:下载信息明细 + * 变量名:download_bill_list + * 是否必填:否 + * 类型:array + * 描述: + * 下载信息明细 + *+ */ + @SerializedName(value = "download_bill_list") + private FundBill[] downloadBillList; + + @Data + public static class FundBill { + + /** + *
+ * 字段名:账单文件序号 + * 变量名:bill_sequence + * 是否必填:是 + * 类型:int + * 描述: + * 商户将多个文件按账单文件序号的顺序合并为完整的资金账单文件,起始值为1 + * 示例值:1 + *+ */ + @SerializedName(value = "bill_sequence") + private String billSequence; + + /** + *
+ * 字段名:哈希类型 + * 变量名:hash_type + * 是否必填:是 + * 类型:string(32) + * 描述: + * 枚举值: + * SHA1:SHA1值 + * 示例值:SHA1 + *+ */ + @SerializedName(value = "hash_type") + private String hashType; + + /** + *
+ * 字段名:哈希值 + * 变量名:hash_value + * 是否必填:是 + * 类型:string(1024) + * 描述: + * 原始账单(gzip需要解压缩)的摘要值,用于校验文件的完整性。 + * 示例值:79bb0f45fc4c42234a918000b2668d689e2bde04 + *+ */ + @SerializedName(value = "hash_value") + private String hashValue; + + /** + *
+ * 字段名:账单下载地址 + * 变量名:download_url + * 是否必填:是 + * 类型:string(2048) + * 描述: + * 供下一步请求账单文件的下载地址,该地址30s内有效。 + * 示例值:https://api.mch.weixin.qq.com/v3/billdownload/file?token=xxx + *+ */ + @SerializedName(value = "download_url") + private String downloadUrl; + + + /** + *
+ * 字段名:加密密钥 + * 变量名:encrypt_key + * 是否必填:是 + * 类型:string(512) + * 描述: + * 加密账单文件使用的加密密钥。密钥用商户证书的公钥进行加密,然后进行Base64编码 + * 示例值:YpkbxSne+mDwyXq//xYPmtr9eQ5LsH7zLMZSs+GSEcY4wjhlsfioS4n9X6q1ZBL0wM1v5qd7KhWuj0rFJ4N1FidP7Q8KDy25QDTt46wiKnsPKSCAXWRFNw1D2JmJBqZsc9y5g0DupONWKYB2GfRigRDEBVszj67uOIILPdxOKX1w3N4jvu0U9IFanJa7ldm70KVvYrMWVgQFDPbgjh1gVDbuTAjmPN88AobLdkiegnBUS2woDZW+PfhPo13kweOiR3h1gXIKRlnKnN3Jkkwpna/AFFijXrFphO3voSuiV0CfptfzTtcae4X3DYG3RSroKqmpa+5tuy2aU2VJUSIuFQ== + *+ */ + @SerializedName(value = "encrypt_key") + private String encryptKey; + + /** + *
+ * 字段名:随机字符串 + * 变量名:nonce + * 是否必填:是 + * 类型:string(16) + * 描述: + * 加密账单文件使用的随机字符串 + * 示例值:a8607ef79034c49c + *+ */ + @SerializedName(value = "nonce") + private String nonce; + + + } + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/BillRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/TradeBillRequest.java similarity index 97% rename from weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/BillRequest.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/TradeBillRequest.java index 247b2a7d01..ad623edf56 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/BillRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/TradeBillRequest.java @@ -4,7 +4,7 @@ import lombok.*; /** - * 账单请求 + * 交易账单请求 * @author: f00lish * @date: 2020/09/28 */ @@ -13,7 +13,7 @@ @ToString @NoArgsConstructor(access = AccessLevel.PRIVATE) @AllArgsConstructor(access = AccessLevel.PRIVATE) -public class BillRequest { +public class TradeBillRequest { /** *
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/BillResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/TradeBillResult.java
similarity index 96%
rename from weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/BillResult.java
rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/TradeBillResult.java
index 4a5bdb9524..2fb7b60564 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/BillResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/TradeBillResult.java
@@ -4,7 +4,7 @@
import lombok.*;
/**
- * 账单结果
+ * 交易账单结果
* @author: f00lish
* @date: 2020/09/28
*/
@@ -13,7 +13,7 @@
@ToString
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
-public class BillResult {
+public class TradeBillResult {
/**
*
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/enums/BillTypeEnum.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/enums/FundBillTypeEnum.java
similarity index 64%
rename from weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/enums/BillTypeEnum.java
rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/enums/FundBillTypeEnum.java
index 598ee4be4b..72aff3a02b 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/enums/BillTypeEnum.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/enums/FundBillTypeEnum.java
@@ -10,17 +10,16 @@
*/
@Getter
@AllArgsConstructor
-public enum BillTypeEnum {
+public enum FundBillTypeEnum {
/**
- * 交易账单
+ * 资金账单
*/
- TRADE_BILL("%s/v3/bill/tradebill?%s"),
+ FUND_FLOW_BILL("%s/v3/bill/fundflowbill?%s"),
/**
- * 资金账单
+ * 二级商户资金账单
*/
- FUND_FLOW_BILL("%s/v3/bill/fundflowbill?%s");
-
+ SUB_FUND_FLOW_BILL("%s/v3/ecommerce/bill/fundflowbill?%s");
/**
* url
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/EcommerceService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/EcommerceService.java
index 367f2e8e1e..91c58e7ac3 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/EcommerceService.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/EcommerceService.java
@@ -1,7 +1,7 @@
package com.github.binarywang.wxpay.service;
import com.github.binarywang.wxpay.bean.ecommerce.*;
-import com.github.binarywang.wxpay.bean.ecommerce.enums.BillTypeEnum;
+import com.github.binarywang.wxpay.bean.ecommerce.enums.FundBillTypeEnum;
import com.github.binarywang.wxpay.bean.ecommerce.enums.SpAccountTypeEnum;
import com.github.binarywang.wxpay.bean.ecommerce.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.exception.WxPayException;
@@ -394,12 +394,24 @@ public interface EcommerceService {
* 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/bill.shtml
*
*
+ * @param request 请求信息。
+ * @return 返回数据 return trade bill result
+ * @throws WxPayException the wx pay exception
+ */
+ TradeBillResult applyBill(TradeBillRequest request) throws WxPayException;
+
+ /**
+ *
+ * 申请资金账单API
+ * 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/bill/chapter3_2.shtml
+ *
+ *
* @param billType 账单类型。
- * @param request 二级商户号。
- * @return 返回数据 return bill result
+ * @param request 请求信息。
+ * @return 返回数据 return fund bill result
* @throws WxPayException the wx pay exception
*/
- BillResult applyBill(BillTypeEnum billType, BillRequest request) throws WxPayException;
+ FundBillResult applyFundBill(FundBillTypeEnum billType, FundBillRequest request) throws WxPayException;
/**
*
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/EcommerceServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/EcommerceServiceImpl.java
index 67976caf31..58a02d8ff8 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/EcommerceServiceImpl.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/EcommerceServiceImpl.java
@@ -1,7 +1,7 @@
package com.github.binarywang.wxpay.service.impl;
import com.github.binarywang.wxpay.bean.ecommerce.*;
-import com.github.binarywang.wxpay.bean.ecommerce.enums.BillTypeEnum;
+import com.github.binarywang.wxpay.bean.ecommerce.enums.FundBillTypeEnum;
import com.github.binarywang.wxpay.bean.ecommerce.enums.SpAccountTypeEnum;
import com.github.binarywang.wxpay.bean.ecommerce.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.exception.WxPayException;
@@ -295,10 +295,17 @@ public SettlementResult querySettlement(String subMchid) throws WxPayException {
}
@Override
- public BillResult applyBill(BillTypeEnum billType, BillRequest request) throws WxPayException {
+ public TradeBillResult applyBill(TradeBillRequest request) throws WxPayException {
+ String url = String.format("%s/v3/bill/tradebill?%s", this.payService.getPayBaseUrl(), this.parseURLPair(request));
+ String response = this.payService.getV3(URI.create(url));
+ return GSON.fromJson(response, TradeBillResult.class);
+ }
+
+ @Override
+ public FundBillResult applyFundBill(FundBillTypeEnum billType, FundBillRequest request) throws WxPayException {
String url = String.format(billType.getUrl(), this.payService.getPayBaseUrl(), this.parseURLPair(request));
String response = this.payService.getV3(URI.create(url));
- return GSON.fromJson(response, BillResult.class);
+ return GSON.fromJson(response, FundBillResult.class);
}
@Override
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/AesUtils.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/AesUtils.java
index 4030965ebe..2c8c40252f 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/AesUtils.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/v3/util/AesUtils.java
@@ -4,6 +4,11 @@
import com.google.common.io.BaseEncoding;
import org.apache.commons.lang3.StringUtils;
+import javax.crypto.Cipher;
+import javax.crypto.Mac;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
@@ -13,11 +18,6 @@
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
-import javax.crypto.Cipher;
-import javax.crypto.Mac;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.spec.GCMParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
public class AesUtils {
@@ -32,6 +32,31 @@ public AesUtils(byte[] key) {
this.aesKey = key;
}
+ public static byte[] decryptToByte(byte[] nonce, byte[] cipherData, byte[] key)
+ throws GeneralSecurityException {
+ return decryptToByte(null, nonce, cipherData, key);
+ }
+
+ public static byte[] decryptToByte(byte[] associatedData, byte[] nonce, byte[] cipherData, byte[] key)
+ throws GeneralSecurityException {
+ try {
+ Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+
+ SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
+ GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);
+
+ cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, spec);
+ if (associatedData != null) {
+ cipher.updateAAD(associatedData);
+ }
+ return cipher.doFinal(cipherData);
+ } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
+ throw new IllegalStateException(e);
+ } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext)
throws GeneralSecurityException, IOException {
try {
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBillResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayTradeFundBillResultTest.java
similarity index 100%
rename from weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBillResultTest.java
rename to weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayTradeFundBillResultTest.java