feat: 完善批量转账到零钱API

- 转账明细电子回单受理API
- 查询转账明细电子回单受理结果API
- 查询账户实时余额API
- 查询账户日终余额API
- 商户银行来账查询API
This commit is contained in:
felord
2021-05-28 17:01:04 +08:00
parent 16440d01cf
commit 3871e05ea7
6 changed files with 299 additions and 4 deletions

View File

@@ -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
}

View File

@@ -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"),
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -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
* <p>
* 受理转账明细电子回单接口,商户通过该接口可以申请受理转账明细单电子回单服务。
* <p>
* 返回的下载链接可调用{@link this#downloadBillResponse(String, String)}下载文件
*
* @param params the params
* @return the wechat response entity
* @since 1.0.11.RELEASE
*/
public WechatResponseEntity<ObjectNode> transferElectronic(TransferDetailElectronicParams params) {
WechatResponseEntity<ObjectNode> 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
* <p>
* 查询转账明细电子回单受理结果接口,商户通过该接口可以查询电子回单受理进度信息,
* 包括电子回单据信息电子回单文件的hash值电子回单文件的下载地址等。
* <p>
* 返回的下载链接可调用{@link this#downloadBillResponse(String, String)}下载文件
*
* @param params the params
* @return the wechat response entity
* @since 1.0.11.RELEASE
*/
public WechatResponseEntity<ObjectNode> queryTransferElectronicResult(TransferDetailElectronicParams params) {
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
this.client().withType(WechatPayV3Type.BATCH_TRANSFER_ELECTRONIC_DETAIL, params)
.function((type, transferDetailElectronic) -> {
MultiValueMap<String, String> 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
* <p>
* 商户通过此接口可以查询本商户号的账号余额情况。
*
* @param accountType the account type
* @return the wechat response entity
* @since 1.0.11.RELEASE
*/
public WechatResponseEntity<ObjectNode> queryFundBalance(FundFlowAccountType accountType) {
WechatResponseEntity<ObjectNode> 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
* <p>
* 通过此接口可以查询本商户号指定日期当天24点的账户余额。
*
* @param queryDayBalanceParams the transfer day balance params
* @return the wechat response entity
* @since 1.0.11.RELEASE
*/
public WechatResponseEntity<ObjectNode> queryDayFundBalance(QueryDayBalanceParams queryDayBalanceParams) {
WechatResponseEntity<ObjectNode> 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
* <p>
* 商户通过本接口查询指定日期内本商户银行来账记录列表。
* 列表内包含本商户银行来账相关的业务单号、金额、完成时间等信息,用于查询和核对。
* <p>
* 注意:
* <ol>
* <li>如需检索,请在前端缓存所有银行来账记录数据并自行完成检索功能;</li>
* <li>调用该接口前,商户需提前开通“来账识别”产品权限;</li>
* <li>本接口对可查询的商户范围有所规定,仅支持对本商户进行查询;</li>
* <li>本接口仅提供近90天内的银行来账记录查询且一次只能查询一天商户需确保查询记录日期在此范围内</li>
* <li>本接口返回的记录字段后续可能会有所扩充,商户需做好接口兼容准备;</li>
* <li>单商户单接口最大请求频率不超过50TPS。</li>
* </ol>
*
* @param queryIncomeRecordParams the transfer day balance params
* @return the wechat response entity
* @since 1.0.11.RELEASE
*/
public WechatResponseEntity<ObjectNode> queryIncomeRecords(QueryIncomeRecordParams queryIncomeRecordParams) {
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
this.client().withType(WechatPayV3Type.BATCH_TRANSFER_FUND_INCOME_RECORDS, queryIncomeRecordParams)
.function((type, params) -> {
MultiValueMap<String, String> 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;
}
}

View File

@@ -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;
}

View File

@@ -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;
/**
* 本次查询偏移量,选填
* <p>
* 表示该次请求资源的起始位置从0开始计数。调用方选填默认为0。offset为20limit为100时查询第20-119条数据
*/
private Integer offset;
/**
* 本次请求最大查询条数,必填
* <p>
* 非0非负的整数该次请求可返回的最大资源条数最大支持100条。
*/
private Integer limit;
}

View File

@@ -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;
/**
* 商家转账批次单号,选填。
* <p>
* 需要电子回单的批量转账明细单所在的转账批次单号,该单号为商户申请转账时生成的商户单号。
* 受理类型为{@code BATCH_TRANSFER}时该单号必填,否则该单号留空。
*/
private String outBatchNo;
/**
* 商家转账明细单号,必填。
* <p>
* <ul>
* <li>受理类型为{@code BATCH_TRANSFER}时填写商家批量转账明细单号。</li>
* <li>受理类型为{@code TRANSFER_TO_POCKET}或{@code TRANSFER_TO_BANK}时填写商家转账单号。</li>
* </ul>
*/
private String outDetailNo;
}