🆕 #2672 【微信支付】增加商家转账的更多接口

This commit is contained in:
Binary Wang
2022-06-21 16:49:54 +08:00
parent 541589be59
commit 1ccb94fd4e
17 changed files with 2018 additions and 75 deletions

View File

@@ -0,0 +1,150 @@
package com.github.binarywang.wxpay.service;
import com.github.binarywang.wxpay.bean.merchanttransfer.*;
import com.github.binarywang.wxpay.exception.WxPayException;
/**
* 商家转账到零钱(直联商户)
*
* @author glz
* @date 2022-6-11
*/
public interface MerchantTransferService {
/**
* 发起商家转账API
* <p>
* 适用对象:直连商户
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_3_1.shtml
* 请求URLhttps://api.mch.weixin.qq.com/v3/transfer/batches
* 请求方式POST
* 接口限频: 单个商户 50QPS如果超过频率限制会报错FREQUENCY_LIMITED请降低频率请求。
* 是否需要证书:是
*
* @param request the request
* @return transfer create result
* @throws WxPayException the wx pay exception
*/
TransferCreateResult createTransfer(TransferCreateRequest request) throws WxPayException;
/**
* 微信批次单号查询批次单API
* <p>
* 适用对象:直连商户
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_3_2.shtml
* 请求URLhttps://api.mch.weixin.qq.com/v3/transfer/batches/batch-id/{batch_id}
* 请求方式GET
* 接口限频: 单个商户 50QPS如果超过频率限制会报错FREQUENCY_LIMITED请降低频率请求。
*
* @param request the request
* @return batches query result
* @throws WxPayException the wx pay exception
*/
BatchesQueryResult queryWxBatches(WxBatchesQueryRequest request) throws WxPayException;
/**
* 微信明细单号查询明细单API
* <p>
* 适用对象:直连商户
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_3_3.shtml
* 请求URLhttps://api.mch.weixin.qq.com/v3/transfer/batches/batch-id/{batch_id}/details/detail-id/{detail_id}
* 请求方式GET
* 接口限频: 单个商户 50QPS如果超过频率限制会报错FREQUENCY_LIMITED请降低频率请求。
*
* @param request the request
* @return details query result
* @throws WxPayException the wx pay exception
*/
DetailsQueryResult queryWxDetails(WxDetailsQueryRequest request) throws WxPayException;
/**
* 商家批次单号查询批次单API
* <p>
* 适用对象:直连商户
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_3_5.shtml
* 请求URLhttps://api.mch.weixin.qq.com/v3/transfer/batches/out-batch-no/{out_batch_no}
* 请求方式GET
* 接口限频: 单个商户 50QPS如果超过频率限制会报错FREQUENCY_LIMITED请降低频率请求。
*
* @param request the request
* @return batches query result
* @throws WxPayException the wx pay exception
*/
BatchesQueryResult queryMerchantBatches(MerchantBatchesQueryRequest request) throws WxPayException;
/**
* 商家明细单号查询明细单API
* <p>
* 适用对象:直连商户
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_3_6.shtml
* 请求URLhttps://api.mch.weixin.qq.com/v3/transfer/batches/out-batch-no/{out_batch_no}/details/out-detail-no/{out_detail_no}
* 请求方式GET
* 接口限频: 单个商户 50QPS如果超过频率限制会报错FREQUENCY_LIMITED请降低频率请求。
*
* @param request the request
* @return details query result
* @throws WxPayException the wx pay exception
*/
DetailsQueryResult queryMerchantDetails(MerchantDetailsQueryRequest request) throws WxPayException;
/**
* 转账电子回单申请受理API
* <p>
* 适用对象:直连商户
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_3_7.shtml
* 请求URLhttps://api.mch.weixin.qq.com/v3/transfer/bill-receipt
* 请求方式POST
* 接口限频: 单个商户 20QPS如果超过频率限制会报错FREQUENCY_LIMITED请降低频率请求。
*
* @param request the request
* @return electronic bill result
* @throws WxPayException the wx pay exception
*/
ElectronicBillResult applyElectronicBill(ElectronicBillApplyRequest request) throws WxPayException;
/**
* 查询转账电子回单API
* <p>
* 适用对象:直连商户
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_3_8.shtml
* 请求URLhttps://api.mch.weixin.qq.com/v3/transfer/bill-receipt/{out_batch_no}
* 请求方式GET
*
* @param outBatchNo the out batch no
* @return electronic bill result
* @throws WxPayException the wx pay exception
*/
ElectronicBillResult queryElectronicBill(String outBatchNo) throws WxPayException;
/**
* 转账明细电子回单受理API
* <p>
* 适用对象:直连商户
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_3_9.shtml
* 请求URLhttps://api.mch.weixin.qq.com/v3/transfer-detail/electronic-receipts
* 请求方式POST
* 接口限频: 单个商户 20QPS如果超过频率限制会报错FREQUENCY_LIMITED请降低频率请求。
* 前置条件只支持受理最近30天内的转账明细单
*
* @param request the request
* @return detail electronic bill result
* @throws WxPayException the wx pay exception
*/
DetailElectronicBillResult applyDetailElectronicBill(DetailElectronicBillRequest request) throws WxPayException;
/**
* 查询转账明细电子回单受理结果API
* <p>
* 适用对象:直连商户
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_3_10.shtml
* 请求URLhttps://api.mch.weixin.qq.com/v3/transfer-detail/electronic-receipts
* 请求方式GET
* 前置条件只支持查询最近90天内的转账明细单
*
* @param request the request
* @return detail electronic bill result
* @throws WxPayException the wx pay exception
*/
DetailElectronicBillResult queryDetailElectronicBill(DetailElectronicBillRequest request) throws WxPayException;
}

View File

@@ -304,6 +304,13 @@ public interface WxPayService {
*/
MarketingBusiFavorService getMarketingBusiFavorService();
/**
* 获取商家转账到零钱服务类
*
* @return the merchant transfer service
*/
MerchantTransferService getMerchantTransferService();
/**
* 设置企业付款服务类,允许开发者自定义实现类.
*

View File

@@ -27,6 +27,8 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.Getter;
import lombok.Setter;
import me.chanjar.weixin.common.error.WxRuntimeException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@@ -63,101 +65,64 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
static ThreadLocal<WxPayApiData> wxApiData = new ThreadLocal<>();
@Setter
@Getter
private EntPayService entPayService = new EntPayServiceImpl(this);
@Getter
private final ProfitSharingService profitSharingService = new ProfitSharingServiceImpl(this);
@Getter
private final ProfitSharingV3Service profitSharingV3Service = new ProfitSharingV3ServiceImpl(this);
@Getter
private final RedpackService redpackService = new RedpackServiceImpl(this);
@Getter
private final PayScoreService payScoreService = new PayScoreServiceImpl(this);
@Getter
private final EcommerceService ecommerceService = new EcommerceServiceImpl(this);
@Getter
private final BusinessCircleService businessCircleService = new BusinessCircleServiceImpl(this);
@Getter
private final MerchantMediaService merchantMediaService = new MerchantMediaServiceImpl(this);
@Getter
private final MarketingMediaService marketingMediaService = new MarketingMediaServiceImpl(this);
@Getter
private final MarketingFavorService marketingFavorService = new MarketingFavorServiceImpl(this);
@Getter
private final MarketingBusiFavorService marketingBusiFavorService = new MarketingBusiFavorServiceImpl(this);
@Getter
private final WxEntrustPapService wxEntrustPapService = new WxEntrustPapServiceImpl(this);
@Getter
private final PartnerTransferService partnerTransferService = new PartnerTransferServiceImpl(this);
@Getter
private final PayrollService payrollService = new PayrollServiceImpl(this);
@Getter
private final ComplaintService complaintsService = new ComplaintServiceImpl(this);
@Getter
private final BankService bankService = new BankServiceImpl(this);
@Getter
private final TransferService transferService = new TransferServiceImpl(this);
@Getter
private final MerchantTransferService merchantTransferService = new MerchantTransferServiceImpl(this);
protected Map<String, WxPayConfig> configMap;
@Override
public EntPayService getEntPayService() {
return entPayService;
}
@Override
public ProfitSharingService getProfitSharingService() {
return profitSharingService;
}
@Override
public ProfitSharingV3Service getProfitSharingV3Service() {
return profitSharingV3Service;
}
@Override
public PayScoreService getPayScoreService() {
return payScoreService;
}
@Override
public RedpackService getRedpackService() {
return this.redpackService;
}
@Override
public EcommerceService getEcommerceService() {
return ecommerceService;
}
@Override
public BusinessCircleService getBusinessCircleService() {
return this.businessCircleService;
}
@Override
public MerchantMediaService getMerchantMediaService() {
return this.merchantMediaService;
}
@Override
public MarketingMediaService getMarketingMediaService() {
return this.marketingMediaService;
}
@Override
public MarketingFavorService getMarketingFavorService() {
return this.marketingFavorService;
}
@Override
public MarketingBusiFavorService getMarketingBusiFavorService() {
return this.marketingBusiFavorService;
}
@Override
public void setEntPayService(EntPayService entPayService) {
this.entPayService = entPayService;
}
@Override
public WxEntrustPapService getWxEntrustPapService() {
return wxEntrustPapService;
}
@Override
public PartnerTransferService getPartnerTransferService() {
return partnerTransferService;
}
@Override
public PayrollService getPayrollService() {
return payrollService;
}
@Override
public WxPayConfig getConfig() {
if (this.configMap.size() == 1) {

View File

@@ -0,0 +1,118 @@
package com.github.binarywang.wxpay.service.impl;
import com.github.binarywang.wxpay.bean.merchanttransfer.*;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.MerchantTransferService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* @author glz
* @date 2022/6/11
*/
@Slf4j
@RequiredArgsConstructor
public class MerchantTransferServiceImpl implements MerchantTransferService {
private static final Gson GSON = (new GsonBuilder()).create();
private final WxPayService wxPayService;
@Override
public TransferCreateResult createTransfer(TransferCreateRequest request) throws WxPayException {
request.setAppid(this.wxPayService.getConfig().getAppId());
String url = String.format("%s/v3/transfer/batches", this.wxPayService.getPayBaseUrl());
RsaCryptoUtil.encryptFields(request, this.wxPayService.getConfig().getVerifier().getValidCertificate());
String response = wxPayService.postV3WithWechatpaySerial(url,GSON.toJson(request));
return GSON.fromJson(response, TransferCreateResult.class);
}
@Override
public BatchesQueryResult queryWxBatches(WxBatchesQueryRequest request) throws WxPayException {
String url = String.format("%s/v3/transfer/batches/batch-id/%s?need_query_detail=%b", this.wxPayService.getPayBaseUrl(), request.getBatchId(), request.getNeedQueryDetail());
if(request.getOffset()!=null){
url = String.format("%s&offset=%d",url,request.getOffset());
}
if(request.getLimit()!=null){
url = String.format("%s&limit=%d",url,request.getLimit());
}
if(request.getDetailStatus()!=null && request.getDetailStatus().length()!=0){
url = String.format("%s&detail_status=%s",url,request.getDetailStatus());
}
String response = wxPayService.getV3(url);
return GSON.fromJson(response, BatchesQueryResult.class);
}
@Override
public DetailsQueryResult queryWxDetails(WxDetailsQueryRequest request) throws WxPayException {
String url = String.format("%s/v3/transfer/batches/batch-id/%s/details/detail-id/%s",this.wxPayService.getPayBaseUrl(),request.getBatchId(),request.getDetailId());
String response = wxPayService.getV3(url);
return GSON.fromJson(response, DetailsQueryResult.class);
}
@Override
public BatchesQueryResult queryMerchantBatches(MerchantBatchesQueryRequest request) throws WxPayException {
String url = String.format("%s/v3/transfer/batches/out-batch-no/%s?need_query_detail=%b", this.wxPayService.getPayBaseUrl(), request.getOutBatchNo(),request.getNeedQueryDetail());
if(request.getOffset()!=null){
url = String.format("%s&offset=%d",url,request.getOffset());
}
if(request.getLimit()!=null){
url = String.format("%s&limit=%d",url,request.getLimit());
}
if(request.getDetailStatus()!=null && request.getDetailStatus().length()!=0){
url = String.format("%s&detail_status=%s",url,request.getDetailStatus());
}
String response = wxPayService.getV3(url);
return GSON.fromJson(response, BatchesQueryResult.class);
}
@Override
public DetailsQueryResult queryMerchantDetails(MerchantDetailsQueryRequest request) throws WxPayException {
String url = String.format("%s/v3/transfer/batches/out-batch-no/%s/details/out-detail-no/%s",this.wxPayService.getPayBaseUrl(),request.getOutBatchNo(),request.getOutDetailNo());
String response = wxPayService.getV3(url);
return GSON.fromJson(response, DetailsQueryResult.class);
}
@Override
public ElectronicBillResult applyElectronicBill(ElectronicBillApplyRequest request) throws WxPayException {
String url = String.format("%s/v3/transfer/bill-receipt",this.wxPayService.getPayBaseUrl());
String response = wxPayService.postV3(url,GSON.toJson(request));
return GSON.fromJson(response, ElectronicBillResult.class);
}
@Override
public ElectronicBillResult queryElectronicBill(String outBatchNo) throws WxPayException {
String url = String.format("%s/v3/transfer/bill-receipt/%s",this.wxPayService.getPayBaseUrl(),outBatchNo);
String response = wxPayService.getV3(url);
return GSON.fromJson(response, ElectronicBillResult.class);
}
@Override
public DetailElectronicBillResult applyDetailElectronicBill(DetailElectronicBillRequest request) throws WxPayException {
String url = String.format("%s/v3/transfer-detail/electronic-receipts",this.wxPayService.getPayBaseUrl());
String response = wxPayService.postV3(url,GSON.toJson(request));
return GSON.fromJson(response, DetailElectronicBillResult.class);
}
@Override
public DetailElectronicBillResult queryDetailElectronicBill(DetailElectronicBillRequest request) throws WxPayException {
String url = String.format("%s/v3/transfer-detail/electronic-receipts?accept_type=%s&out_detail_no=%s", this.wxPayService.getPayBaseUrl(), request.getAcceptType(),request.getOutDetailNo());
if(request.getOutBatchNo()!=null && request.getOutBatchNo().length()!=0){
url = String.format("%s&out_batch_no=%s",url,request.getOutBatchNo());
}
String response = wxPayService.getV3(url);
return GSON.fromJson(response, DetailElectronicBillResult.class);
}
}