mirror of
https://github.com/dromara/payment-spring-boot.git
synced 2026-03-13 21:33:41 +08:00
feat: 微信支付V3批量转账到零钱
- 增加批量转账到零钱API调用入口WechatBatchTransferApi - 实现发起批量转账 - 实现微信批次单号查询批次单API - 实现微信明细单号查询明细单API - 实现商家批次单号查询批次单API - 实现商家明细单号查询明细单API - 实现转账电子回单申请受理API - 实现查询转账电子回单API,同时实现直接下载功能
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2019-2021 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
/**
|
||||
* 转账明细.
|
||||
*
|
||||
* @author xfa00
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
public enum DetailStatus {
|
||||
/**
|
||||
* 全部。需要同时查询转账成功和转账失败的明细单
|
||||
*/
|
||||
ALL,
|
||||
/**
|
||||
* 转账成功。只查询转账成功的明细单
|
||||
*/
|
||||
SUCCESS,
|
||||
/**
|
||||
* 转账失败。只查询转账失败的明细单
|
||||
*/
|
||||
FAIL
|
||||
}
|
||||
@@ -28,9 +28,7 @@ import org.springframework.http.HttpMethod;
|
||||
* @since 1.0.0.RELEASE
|
||||
*/
|
||||
public enum WechatPayV3Type {
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* 获取证书.
|
||||
*
|
||||
@@ -445,8 +443,50 @@ public enum WechatPayV3Type {
|
||||
*
|
||||
* @since 1.0.4.RELEASES
|
||||
*/
|
||||
MARKETING_BUSI_FAVOR_DEACTIVATE(HttpMethod.POST, "%s/v3/marketing/busifavor/coupons/deactivate");
|
||||
|
||||
MARKETING_BUSI_FAVOR_DEACTIVATE(HttpMethod.POST, "%s/v3/marketing/busifavor/coupons/deactivate"),
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/**
|
||||
* 发起批量转账API.
|
||||
*
|
||||
* @since 1.0.6.RELEASES
|
||||
*/
|
||||
BATCH_TRANSFER_REQ(HttpMethod.POST, "%s/v3/transfer/batches"),
|
||||
/**
|
||||
* 微信批次单号查询批次单API.
|
||||
*
|
||||
* @since 1.0.6.RELEASES
|
||||
*/
|
||||
BATCH_TRANSFER_BATCH_ID(HttpMethod.GET, "%s/v3/transfer/batches/batch-id/{batch_id}"),
|
||||
/**
|
||||
* 微信明细单号查询明细单API.
|
||||
*
|
||||
* @since 1.0.6.RELEASES
|
||||
*/
|
||||
BATCH_TRANSFER_DETAIL_WECHAT(HttpMethod.GET, "%s/v3/transfer/batches/batch-id/{batch_id}/details/detail-id/{detail_id}"),
|
||||
/**
|
||||
* 商家批次单号查询批次单API.
|
||||
*
|
||||
* @since 1.0.6.RELEASES
|
||||
*/
|
||||
BATCH_TRANSFER_OUT_BATCH_NO(HttpMethod.GET, "%s/v3/transfer/batches/out-batch-no/{out_batch_no}"),
|
||||
/**
|
||||
* 商家明细单号查询明细单API.
|
||||
*
|
||||
* @since 1.0.6.RELEASES
|
||||
*/
|
||||
BATCH_TRANSFER_DETAIL_MCH(HttpMethod.GET, "%s/v3/transfer/batches/out-batch-no/{out_batch_no}/details/out-detail-no/{out_detail_no}"),
|
||||
/**
|
||||
* 转账电子回单申请受理API.
|
||||
*
|
||||
* @since 1.0.6.RELEASES
|
||||
*/
|
||||
BATCH_TRANSFER_BILL_RECEIPT(HttpMethod.POST, "%s/v3/transfer/bill-receipt"),
|
||||
/**
|
||||
* 查询转账电子回单并下载.
|
||||
*
|
||||
* @since 1.0.6.RELEASES
|
||||
*/
|
||||
BATCH_TRANSFER_DOWNLOAD_BILL(HttpMethod.GET, "%s/v3/transfer/bill-receipt/{out_batch_no}");
|
||||
/**
|
||||
* The Pattern.
|
||||
*
|
||||
@@ -492,7 +532,6 @@ public enum WechatPayV3Type {
|
||||
return this.pattern;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 默认支付URI.
|
||||
*
|
||||
@@ -503,5 +542,4 @@ public enum WechatPayV3Type {
|
||||
public String uri(WeChatServer weChatServer) {
|
||||
return String.format(this.pattern, weChatServer.domain());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
@@ -166,10 +168,10 @@ public abstract class AbstractApi {
|
||||
|
||||
|
||||
/**
|
||||
* 对账单下载。
|
||||
* 对账单内容下载,非流文件。
|
||||
*
|
||||
* @param link the link
|
||||
* @return 对账单内容,有可能为空字符 “”
|
||||
* @return 对账单内容 ,有可能为空字符 “”
|
||||
*/
|
||||
protected String billDownload(String link) {
|
||||
return this.client().withType(WechatPayV3Type.FILE_DOWNLOAD, link)
|
||||
@@ -182,6 +184,22 @@ public abstract class AbstractApi {
|
||||
.download();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对账单下载,流文件。
|
||||
*
|
||||
* @param link the link
|
||||
* @return response entity
|
||||
*/
|
||||
protected ResponseEntity<Resource> billResource(String link) {
|
||||
return this.client().withType(WechatPayV3Type.FILE_DOWNLOAD, link)
|
||||
.function((type, downloadUrl) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(downloadUrl)
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.resource();
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请交易账单API
|
||||
|
||||
@@ -110,6 +110,19 @@ public class WechatApiProvider {
|
||||
return new WechatMarketingBusiFavorApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量转账到零钱.
|
||||
* <p>
|
||||
* 批量转账到零钱提供商户同时向多个用户微信零钱转账的能力。商户可以使用批量转账到零钱用于费用报销、员工福利发放、合作伙伴货款或服务款项支付等场景,提高转账效率。
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the WechatBatchTransferApi
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
public WechatBatchTransferApi batchTransferApi(String tenantId) {
|
||||
return new WechatBatchTransferApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 回调.
|
||||
* <p>
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright 2019-2021 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
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 com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import sun.security.x509.X509CertImpl;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 批量转账到零钱
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
public class WechatBatchTransferApi extends AbstractApi {
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
public WechatBatchTransferApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起批量转账API
|
||||
*
|
||||
* @param createBatchTransferParams the batchTransferParams
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> batchTransfer(CreateBatchTransferParams createBatchTransferParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BATCH_TRANSFER_REQ, createBatchTransferParams)
|
||||
.function(this::batchTransferFunction)
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
private RequestEntity<?> batchTransferFunction(WechatPayV3Type type, CreateBatchTransferParams createBatchTransferParams) {
|
||||
List<CreateBatchTransferParams.TransferDetailListItem> transferDetailList = createBatchTransferParams.getTransferDetailList();
|
||||
|
||||
SignatureProvider signatureProvider = this.client().signatureProvider();
|
||||
final X509CertImpl certificate = signatureProvider.getCertificate();
|
||||
List<CreateBatchTransferParams.TransferDetailListItem> encrypted = transferDetailList.stream()
|
||||
.peek(transferDetailListItem -> {
|
||||
String userName = transferDetailListItem.getUserName();
|
||||
String encryptedUserName = signatureProvider.encryptRequestMessage(userName, certificate);
|
||||
transferDetailListItem.setUserName(encryptedUserName);
|
||||
String userIdCard = transferDetailListItem.getUserIdCard();
|
||||
if (StringUtils.hasText(userIdCard)) {
|
||||
String encryptedUserIdCard = signatureProvider.encryptRequestMessage(userIdCard, certificate);
|
||||
transferDetailListItem.setUserIdCard(encryptedUserIdCard);
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
createBatchTransferParams.setTransferDetailList(encrypted);
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, createBatchTransferParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信批次单号查询批次单API
|
||||
*
|
||||
* @param queryBatchTransferParams the queryBatchTransferParams
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryBatchByBatchId(QueryBatchTransferParams queryBatchTransferParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BATCH_TRANSFER_BATCH_ID, queryBatchTransferParams)
|
||||
.function((type, params) -> {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
queryParams.add("need_query_detail", params.getNeedQueryDetail().toString());
|
||||
queryParams.add("offset", params.getOffset().toString());
|
||||
queryParams.add("limit", params.getLimit().toString());
|
||||
queryParams.add("detail_status", params.getDetailStatus().name());
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build()
|
||||
.expand(params.getCode())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信明细单号查询明细单API
|
||||
*
|
||||
* @param queryBatchTransferDetailParams the queryBatchTransferDetailParams
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryBatchDetailByWechat(QueryBatchTransferDetailParams queryBatchTransferDetailParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BATCH_TRANSFER_DETAIL_WECHAT, queryBatchTransferDetailParams)
|
||||
.function((type, params) -> {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
queryParams.add("batch_id", params.getBatchIdOrOutBatchNo());
|
||||
queryParams.add("detail_id", params.getDetailIdOrOutDetailNo());
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(queryParams)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信批次单号查询批次单API
|
||||
*
|
||||
* @param queryBatchTransferParams the queryBatchTransferParams
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryBatchByOutBatchNo(QueryBatchTransferParams queryBatchTransferParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BATCH_TRANSFER_OUT_BATCH_NO, queryBatchTransferParams)
|
||||
.function((type, params) -> {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
queryParams.add("need_query_detail", params.getNeedQueryDetail().toString());
|
||||
queryParams.add("offset", params.getOffset().toString());
|
||||
queryParams.add("limit", params.getLimit().toString());
|
||||
queryParams.add("detail_status", params.getDetailStatus().name());
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build()
|
||||
.expand(params.getCode())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商家明细单号查询明细单API
|
||||
*
|
||||
* @param queryBatchTransferDetailParams the queryBatchTransferDetailParams
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryBatchDetailByMch(QueryBatchTransferDetailParams queryBatchTransferDetailParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BATCH_TRANSFER_DETAIL_MCH, queryBatchTransferDetailParams)
|
||||
.function((type, params) -> {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
queryParams.add("out_batch_no", params.getBatchIdOrOutBatchNo());
|
||||
queryParams.add("out_detail_no", params.getDetailIdOrOutDetailNo());
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(queryParams)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转账电子回单申请受理API
|
||||
*
|
||||
* @param outBatchNo the outBatchNo
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> receiptBill(String outBatchNo) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BATCH_TRANSFER_BILL_RECEIPT, outBatchNo)
|
||||
.function((type, batchNo) -> {
|
||||
Map<String, String> body = new HashMap<>(1);
|
||||
body.put("out_batch_no", outBatchNo);
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, body);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询并下载转账电子回单API
|
||||
*
|
||||
* @param outBatchNo the outBatchNo
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
public ResponseEntity<Resource> downloadBill(String outBatchNo) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BATCH_TRANSFER_DOWNLOAD_BILL, outBatchNo)
|
||||
.function((type, batchNo) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(batchNo)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
String downloadUrl = wechatResponseEntity.getBody().get("download_url").asText();
|
||||
Assert.hasText(downloadUrl,"download url has no text");
|
||||
return this.billResource(downloadUrl);
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import cn.felord.payment.wechat.WechatPayResponseErrorHandler;
|
||||
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
||||
import cn.felord.payment.wechat.v3.model.ResponseSignVerifyParams;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
@@ -176,6 +177,17 @@ public class WechatPayClient {
|
||||
WechatRequestEntity<?> wechatRequestEntity = WechatRequestEntity.of(requestEntity, this.responseBodyConsumer);
|
||||
return this.doDownload(this.header(wechatRequestEntity));
|
||||
}
|
||||
/**
|
||||
* Download string.
|
||||
*
|
||||
* @return the string
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
public ResponseEntity<Resource> resource() {
|
||||
RequestEntity<?> requestEntity = this.requestEntityBiFunction.apply(this.wechatPayV3Type, this.model);
|
||||
WechatRequestEntity<?> wechatRequestEntity = WechatRequestEntity.of(requestEntity, this.responseBodyConsumer);
|
||||
return this.doResource(this.header(wechatRequestEntity));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -267,7 +279,7 @@ public class WechatPayClient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Do download string.
|
||||
* 下载文件返回的是字符串类型的.
|
||||
*
|
||||
* @param <T> the type parameter
|
||||
* @param requestEntity the request entity
|
||||
@@ -286,6 +298,28 @@ public class WechatPayClient {
|
||||
return Optional.ofNullable(responseEntity.getBody()).orElse("");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 下载文件返回的是流类型的.
|
||||
*
|
||||
* @param <T> the type parameter
|
||||
* @param requestEntity the request entity
|
||||
* @return the resource
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
private <T> ResponseEntity<Resource> doResource(WechatRequestEntity<T> requestEntity) {
|
||||
|
||||
ResponseEntity<Resource> responseEntity = restOperations.exchange(requestEntity, Resource.class);
|
||||
|
||||
HttpStatus statusCode = responseEntity.getStatusCode();
|
||||
// 微信请求id
|
||||
String requestId = requestEntity.getHeaders().getFirst("Request-ID");
|
||||
if (!statusCode.is2xxSuccessful()) {
|
||||
throw new PayException("wechat pay server error, Request-ID " + requestId + " , statusCode " + statusCode + ",result : " + responseEntity);
|
||||
}
|
||||
return responseEntity;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2021 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model.batchtransfer;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 批量转账到零钱API请求参数.
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class CreateBatchTransferParams {
|
||||
|
||||
/**
|
||||
* 直连商户的appid
|
||||
*/
|
||||
private String appid;
|
||||
/**
|
||||
* 商家批次单号
|
||||
*/
|
||||
private String outBatchNo;
|
||||
/**
|
||||
* 批次名称
|
||||
*/
|
||||
private String batchName;
|
||||
/**
|
||||
* 批次备注
|
||||
*/
|
||||
private String batchRemark;
|
||||
/**
|
||||
* 发起批量转账的明细列表,最多三千笔
|
||||
*/
|
||||
private List<TransferDetailListItem> transferDetailList;
|
||||
/**
|
||||
* 转账总金额,单位为“分”。转账总金额必须与批次内所有明细转账金额之和保持一致,否则无法发起转账操作
|
||||
*/
|
||||
private Integer totalAmount;
|
||||
/**
|
||||
* 转账总笔数,一个转账批次单最多发起三千笔转账。转账总笔数必须与批次内所有明细之和保持一致,否则无法发起转账操作
|
||||
*/
|
||||
private Integer totalNum;
|
||||
|
||||
/**
|
||||
* 转账明细.
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public static class TransferDetailListItem{
|
||||
|
||||
/**
|
||||
* 商家明细单号
|
||||
*/
|
||||
private String outDetailNo;
|
||||
/**
|
||||
* 转账金额,单位为分
|
||||
*/
|
||||
private Integer transferAmount;
|
||||
/**
|
||||
* 单条转账备注(微信用户会收到该备注),UTF8编码,最多允许32个字符
|
||||
*/
|
||||
private String transferRemark;
|
||||
/**
|
||||
* 用户在直连商户appid下的唯一标识
|
||||
*/
|
||||
private String openid;
|
||||
/**
|
||||
* 收款用户姓名
|
||||
*/
|
||||
private String userName;
|
||||
/**
|
||||
* 收款用户身份证
|
||||
*/
|
||||
private String userIdCard;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2019-2021 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model.batchtransfer;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class QueryBatchTransferDetailParams {
|
||||
/**
|
||||
* 微信批次单号 或 商家批次单号
|
||||
*/
|
||||
private String batchIdOrOutBatchNo;
|
||||
/**
|
||||
* 微信明细单号 或 商家明细单号
|
||||
*/
|
||||
private String detailIdOrOutDetailNo;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2019-2021 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model.batchtransfer;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.DetailStatus;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 微信批次单号查询批次单API 或者 商家批次单号查询批次单API 请求参数
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class QueryBatchTransferParams {
|
||||
/**
|
||||
* 微信批次单号 或 商家批次单号
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
* 是否查询转账明细单
|
||||
*/
|
||||
private Boolean needQueryDetail;
|
||||
/**
|
||||
* 请求资源起始位置
|
||||
*/
|
||||
private Integer offset;
|
||||
/**
|
||||
* 最大资源条数
|
||||
*/
|
||||
private Integer limit;
|
||||
/**
|
||||
* 明细状态
|
||||
*/
|
||||
private DetailStatus detailStatus;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user