diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/TransferAcceptType.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/TransferAcceptType.java new file mode 100644 index 0000000..2020bb9 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/TransferAcceptType.java @@ -0,0 +1,22 @@ +package cn.felord.payment.wechat.enumeration; + +/** + * 批量转账到零钱 - 电子回单受理类型 + * + * @author felord.cn + * @since 1.0.11.RELEASE + */ +public enum TransferAcceptType { + /** + * 批量转账明细电子回单 + */ + BATCH_TRANSFER, + /** + * 企业付款至零钱电子回单 + */ + TRANSFER_TO_POCKET, + /** + * 企业付款至银行卡电子回单 + */ + TRANSFER_TO_BANK +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java index a112747..c4ea443 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java @@ -487,6 +487,35 @@ public enum WechatPayV3Type { * @since 1.0.6.RELEASES */ BATCH_TRANSFER_DOWNLOAD_BILL(HttpMethod.GET, "%s/v3/transfer/bill-receipt/{out_batch_no}"), + /** + * 转账明细电子回单受理API. + * + * @since 1.0.11.RELEASES + */ + BATCH_TRANSFER_ELECTRONIC(HttpMethod.POST, "%s/v3/transfer-detail/electronic-receipts"), + /** + * 查询转账明细电子回单受理结果API. + * 请求方式同{@link WechatPayV3Type#BATCH_TRANSFER_ELECTRONIC}不同 + * @since 1.0.11.RELEASES + */ + BATCH_TRANSFER_ELECTRONIC_DETAIL(HttpMethod.GET, "%s/v3/transfer-detail/electronic-receipts"), + /** + * 查询账户实时余额API + * + * @since 1.0.11.RELEASES + */ + BATCH_TRANSFER_FUND_BALANCE(HttpMethod.GET, "%s/v3/merchant/fund/balance/{account_type}"), + /** + * 查询账户日终余额API + * + * @since 1.0.11.RELEASES + */ + BATCH_TRANSFER_FUND_DAY_BALANCE(HttpMethod.GET, "%s/v3/merchant/fund/dayendbalance/{account_type}"), /** + * 商户银行来账查询API + * + * @since 1.0.11.RELEASES + */ + BATCH_TRANSFER_FUND_INCOME_RECORDS(HttpMethod.GET, "%s/v3/merchantfund/merchant/income-records"), //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBatchTransferApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBatchTransferApi.java index 25dd953..9e0bf9a 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBatchTransferApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBatchTransferApi.java @@ -17,11 +17,10 @@ package cn.felord.payment.wechat.v3; +import cn.felord.payment.wechat.enumeration.FundFlowAccountType; import cn.felord.payment.wechat.enumeration.WeChatServer; import cn.felord.payment.wechat.enumeration.WechatPayV3Type; -import cn.felord.payment.wechat.v3.model.batchtransfer.CreateBatchTransferParams; -import cn.felord.payment.wechat.v3.model.batchtransfer.QueryBatchTransferDetailParams; -import cn.felord.payment.wechat.v3.model.batchtransfer.QueryBatchTransferParams; +import cn.felord.payment.wechat.v3.model.batchtransfer.*; import com.fasterxml.jackson.databind.node.ObjectNode; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; @@ -38,6 +37,7 @@ import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; /** @@ -254,6 +254,152 @@ public class WechatBatchTransferApi extends AbstractApi { .request(); String downloadUrl = wechatResponseEntity.getBody().get("download_url").asText(); Assert.hasText(downloadUrl, "download url has no text"); - return this.billResource(downloadUrl, false); + return this.billResource(downloadUrl); + } + + /** + * 转账明细电子回单受理API + *

+ * 受理转账明细电子回单接口,商户通过该接口可以申请受理转账明细单电子回单服务。 + *

+ * 返回的下载链接可调用{@link this#downloadBillResponse(String, String)}下载文件 + * + * @param params the params + * @return the wechat response entity + * @since 1.0.11.RELEASE + */ + public WechatResponseEntity transferElectronic(TransferDetailElectronicParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.BATCH_TRANSFER_ELECTRONIC, params) + .function((type, transferDetailElectronic) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) + .build() + .toUri(); + return Post(uri, transferDetailElectronic); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 查询转账明细电子回单受理结果API + *

+ * 查询转账明细电子回单受理结果接口,商户通过该接口可以查询电子回单受理进度信息, + * 包括电子回单据信息,电子回单文件的hash值,电子回单文件的下载地址等。 + *

+ * 返回的下载链接可调用{@link this#downloadBillResponse(String, String)}下载文件 + * + * @param params the params + * @return the wechat response entity + * @since 1.0.11.RELEASE + */ + public WechatResponseEntity queryTransferElectronicResult(TransferDetailElectronicParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.BATCH_TRANSFER_ELECTRONIC_DETAIL, params) + .function((type, transferDetailElectronic) -> { + MultiValueMap queryParams = new LinkedMultiValueMap<>(); + queryParams.add("accept_type", transferDetailElectronic.getAcceptType().name()); + queryParams.add("out_batch_no", transferDetailElectronic.getOutBatchNo()); + queryParams.add("out_detail_no", transferDetailElectronic.getOutDetailNo()); + + URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) + .queryParams(queryParams) + .build() + .toUri(); + return Get(uri); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 查询账户实时余额API + *

+ * 商户通过此接口可以查询本商户号的账号余额情况。 + * + * @param accountType the account type + * @return the wechat response entity + * @since 1.0.11.RELEASE + */ + public WechatResponseEntity queryFundBalance(FundFlowAccountType accountType) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.BATCH_TRANSFER_FUND_BALANCE, accountType) + .function((type, flowAccountType) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) + .build() + .expand(flowAccountType.name()) + .toUri(); + return Get(uri); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 查询账户日终余额API + *

+ * 通过此接口可以查询本商户号指定日期当天24点的账户余额。 + * + * @param queryDayBalanceParams the transfer day balance params + * @return the wechat response entity + * @since 1.0.11.RELEASE + */ + public WechatResponseEntity queryDayFundBalance(QueryDayBalanceParams queryDayBalanceParams) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.BATCH_TRANSFER_FUND_DAY_BALANCE, queryDayBalanceParams) + .function((type, params) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) + .queryParam("date", params.getDate().toString()) + .build() + .expand(params.getAccountType().name()) + .toUri(); + return Get(uri); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 商户银行来账查询API + *

+ * 商户通过本接口查询指定日期内本商户银行来账记录列表。 + * 列表内包含本商户银行来账相关的业务单号、金额、完成时间等信息,用于查询和核对。 + *

+ * 注意: + *

    + *
  1. 如需检索,请在前端缓存所有银行来账记录数据并自行完成检索功能;
  2. + *
  3. 调用该接口前,商户需提前开通“来账识别”产品权限;
  4. + *
  5. 本接口对可查询的商户范围有所规定,仅支持对本商户进行查询;
  6. + *
  7. 本接口仅提供近90天内的银行来账记录查询,且一次只能查询一天,商户需确保查询记录日期在此范围内;
  8. + *
  9. 本接口返回的记录字段后续可能会有所扩充,商户需做好接口兼容准备;
  10. + *
  11. 单商户单接口最大请求频率不超过50TPS。
  12. + *
+ * + * @param queryIncomeRecordParams the transfer day balance params + * @return the wechat response entity + * @since 1.0.11.RELEASE + */ + public WechatResponseEntity queryIncomeRecords(QueryIncomeRecordParams queryIncomeRecordParams) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.BATCH_TRANSFER_FUND_INCOME_RECORDS, queryIncomeRecordParams) + .function((type, params) -> { + MultiValueMap queryParams = new LinkedMultiValueMap<>(); + queryParams.add("account_type", params.getAccountType().name()); + queryParams.add("date", params.getDate().toString()); + queryParams.add("offset", Optional.ofNullable(params.getOffset()).orElse(0).toString()); + queryParams.add("limit", params.getLimit().toString()); + URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) + .queryParams(queryParams) + .build() + .toUri(); + return Get(uri); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; } } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/batchtransfer/QueryDayBalanceParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/batchtransfer/QueryDayBalanceParams.java new file mode 100644 index 0000000..c816806 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/batchtransfer/QueryDayBalanceParams.java @@ -0,0 +1,25 @@ +package cn.felord.payment.wechat.v3.model.batchtransfer; + +import cn.felord.payment.wechat.enumeration.FundFlowAccountType; +import lombok.Data; + +import java.time.LocalDate; + +/** + * 查询账户日终余额API 请求参数 + * + * @author felord.cn + * @since 1.0.11.RELEASE + */ +@Data +public class QueryDayBalanceParams { + /** + * 账户类型,必填 + * @see FundFlowAccountType + */ + private FundFlowAccountType accountType; + /** + * 日期,必填 + */ + private LocalDate date; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/batchtransfer/QueryIncomeRecordParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/batchtransfer/QueryIncomeRecordParams.java new file mode 100644 index 0000000..1ffad1e --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/batchtransfer/QueryIncomeRecordParams.java @@ -0,0 +1,37 @@ +package cn.felord.payment.wechat.v3.model.batchtransfer; + +import cn.felord.payment.wechat.enumeration.FundFlowAccountType; +import lombok.Data; + +import java.time.LocalDate; + +/** + * 商户银行来账查询API 请求参数 + * + * @author felord.cn + * @since 1.0.11.RELEASE + */ +@Data +public class QueryIncomeRecordParams { + /** + * 账户类型,必填 + * @see FundFlowAccountType + */ + private FundFlowAccountType accountType; + /** + * 日期,必填 + */ + private LocalDate date; + /** + * 本次查询偏移量,选填 + *

+ * 表示该次请求资源的起始位置,从0开始计数。调用方选填,默认为0。offset为20,limit为100时,查询第20-119条数据 + */ + private Integer offset; + /** + * 本次请求最大查询条数,必填 + *

+ * 非0非负的整数,该次请求可返回的最大资源条数,最大支持100条。 + */ + private Integer limit; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/batchtransfer/TransferDetailElectronicParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/batchtransfer/TransferDetailElectronicParams.java new file mode 100644 index 0000000..79e1da6 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/batchtransfer/TransferDetailElectronicParams.java @@ -0,0 +1,36 @@ +package cn.felord.payment.wechat.v3.model.batchtransfer; + +import cn.felord.payment.wechat.enumeration.TransferAcceptType; +import lombok.Data; + +/** + * 转账明细电子回单受理API请求参数 + * + * @author felord.cn + * @since 1.0.11.RELEASE + */ +@Data +public class TransferDetailElectronicParams { + /** + * 电子回单受理类型,必填。 + * + * @see TransferAcceptType + */ + private TransferAcceptType acceptType; + /** + * 商家转账批次单号,选填。 + *

+ * 需要电子回单的批量转账明细单所在的转账批次单号,该单号为商户申请转账时生成的商户单号。 + * 受理类型为{@code BATCH_TRANSFER}时该单号必填,否则该单号留空。 + */ + private String outBatchNo; + /** + * 商家转账明细单号,必填。 + *

+ *

    + *
  • 受理类型为{@code BATCH_TRANSFER}时填写商家批量转账明细单号。
  • + *
  • 受理类型为{@code TRANSFER_TO_POCKET}或{@code TRANSFER_TO_BANK}时填写商家转账单号。
  • + *
+ */ + private String outDetailNo; +}