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/BillRequest.java new file mode 100644 index 000000000..247b2a7d0 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/BillRequest.java @@ -0,0 +1,86 @@ +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 BillRequest { + + /** + *
+ * 字段名:账单日期 + * 变量名:bill_date + * 是否必填:是 + * 类型:string(10) + * 描述: + * 格式YYYY-MM-DD + * 仅支持三个月内的账单下载申请。 + * 示例值:2019-06-11 + *+ */ + @SerializedName(value = "bill_date") + private String billDate; + + /** + *
+ * 字段名:二级商户号 + * 变量名:sub_mchid + * 是否必填:否 + * 类型:string(12) + * 描述: + * 1、若商户是直连商户:无需填写该字段。 + * 2、若商户是服务商: + * ● 不填则默认返回服务商下的交易或退款数据。 + * ● 如需下载某个子商户下的交易或退款数据,则该字段必填。 + * 特殊规则:最小字符长度为8 + * 注意:仅适用于电商平台 服务商 + * 示例值:1900000001 + *+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+ * 字段名:账单类型 + * 变量名:bill_type + * 是否必填:否 + * 类型:string(32) + * 描述: + * 不填则默认是ALL + * 枚举值: + * ALL:返回当日所有订单信息(不含充值退款订单) + * SUCCESS:返回当日成功支付的订单(不含充值退款订单) + * REFUND:返回当日退款订单(不含充值退款订单) + * 示例值:ALL + *+ */ + @SerializedName(value = "bill_type") + private String billType; + + /** + *
+ * 字段名:压缩类型 + * 变量名:tar_type + * 是否必填:否 + * 类型:string(32) + * 描述: + * 不填则默认是数据流 + * 枚举值: + * GZIP:返回格式为.gzip的压缩包账单 + * 示例值:GZIP + *+ */ + @SerializedName(value = "tar_type") + private String tarType; + +} 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/BillResult.java new file mode 100644 index 000000000..4a5bdb952 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/BillResult.java @@ -0,0 +1,60 @@ +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 BillResult { + + /** + *
+ * 字段名:哈希类型 + * 变量名:hash_type + * 是否必填:是 + * 类型:string(32) + * 描述: + * 原始账单(gzip需要解压缩)的摘要值,用于校验文件的完整性。 + * 示例值:SHA1 + *+ */ + @SerializedName(value = "hash_type") + private String hashType; + + /** + *
+ * 字段名:哈希值 + * 变量名:hash_value + * 是否必填:是 + * 类型:string(1024) + * 描述: + * 原始账单(gzip需要解压缩)的摘要值,用于校验文件的完整性。 + * 示例值:79bb0f45fc4c42234a918000b2668d689e2bde04 + *+ */ + @SerializedName(value = "hash_value") + private String hashValue; + + /** + *
+ * 字段名:账单下载地址 + * 变量名:download_url + * 是否必填:是 + * 类型:string(32) + * 描述: + * 供下一步请求账单文件的下载地址,该地址30s内有效。 + * 示例值:https://api.mch.weixin.qq.com/v3/billdownload/file?token=xxx + *+ */ + @SerializedName(value = "download_url") + private String downloadUrl; + +} 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/BillTypeEnum.java new file mode 100644 index 000000000..598ee4be4 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/enums/BillTypeEnum.java @@ -0,0 +1,30 @@ +package com.github.binarywang.wxpay.bean.ecommerce.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 账单类型 + * @author: f00lish + * @date: 2020/09/28 + */ +@Getter +@AllArgsConstructor +public enum BillTypeEnum { + + /** + * 交易账单 + */ + TRADE_BILL("%s/v3/bill/tradebill?%s"), + /** + * 资金账单 + */ + FUND_FLOW_BILL("%s/v3/bill/fundflowbill?%s"); + + + /** + * url + */ + private final String 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 c0bc6444f..6e536bb39 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,10 +1,13 @@ 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.SpAccountTypeEnum; import com.github.binarywang.wxpay.bean.ecommerce.enums.TradeTypeEnum; import com.github.binarywang.wxpay.exception.WxPayException; +import java.io.InputStream; + /** *
* 电商收付通相关服务类. @@ -360,4 +363,29 @@ public interface EcommerceService { */ SettlementResult querySettlement(String subMchid) throws WxPayException; + /** + *+ * 请求账单API + * 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/bill.shtml + *+ * + * @param billType 账单类型。 + * @param request 二级商户号。 + * @return 返回数据 return bill result + * @throws WxPayException the wx pay exception + */ + BillResult applyBill(BillTypeEnum billType, BillRequest request) throws WxPayException; + + /** + *+ * 下载账单API + * 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/bill.shtml + *+ * + * @param url 微信返回的账单地址。 + * @return 返回数据 return inputStream + * @throws WxPayException the wx pay exception + */ + InputStream downloadBill(String url) throws WxPayException; + } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java index 27d86548c..11e624224 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java @@ -13,6 +13,7 @@ import com.github.binarywang.wxpay.exception.WxPayException; import org.apache.http.client.methods.HttpPost; import java.io.File; +import java.io.InputStream; import java.net.URI; import java.util.Date; import java.util.Map; @@ -97,6 +98,15 @@ public interface WxPayService { */ String getV3(URI url) throws WxPayException; + /** + * 发送下载 V3请求,得到响应流. + * + * @param url 请求地址 + * @return 返回请求响应流 + * @throws WxPayException the wx pay exception + */ + InputStream downloadV3(URI url) 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 eefc7a264..193d6a20e 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,6 +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.SpAccountTypeEnum; import com.github.binarywang.wxpay.bean.ecommerce.enums.TradeTypeEnum; import com.github.binarywang.wxpay.exception.WxPayException; @@ -8,15 +9,21 @@ import com.github.binarywang.wxpay.service.EcommerceService; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.v3.util.AesUtils; import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil; +import com.google.common.base.CaseFormat; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import lombok.RequiredArgsConstructor; +import org.apache.commons.beanutils.BeanMap; import java.io.IOException; +import java.io.InputStream; import java.net.URI; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; +import java.util.Iterator; +import java.util.Map; import java.util.Objects; +import java.util.Set; @RequiredArgsConstructor public class EcommerceServiceImpl implements EcommerceService { @@ -273,6 +280,18 @@ public class EcommerceServiceImpl implements EcommerceService { return GSON.fromJson(response, SettlementResult.class); } + @Override + public BillResult applyBill(BillTypeEnum billType, BillRequest 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); + } + + @Override + public InputStream downloadBill(String url) throws WxPayException { + return this.payService.downloadV3(URI.create(url)); + } + /** * 校验通知签名 * @param header 通知头信息 @@ -287,4 +306,24 @@ public class EcommerceServiceImpl implements EcommerceService { return payService.getConfig().getVerifier().verify(header.getSerialNo(), beforeSign.getBytes(StandardCharsets.UTF_8), header.getSigned()); } -} + + /** + * 对象拼接到url + * @param o 转换对象 + * @return 拼接好的string + */ + private String parseURLPair(Object o) { + Map