package com.transfer.demo.common.wechat.executer;
import com.transfer.demo.common.wechat.dto.TransferBatchDto;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.transferbatch.TransferBatchService;
import com.wechat.pay.java.service.transferbatch.model.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Component
@Slf4j
public class TransferBatchUtil {
/**
* 转账请求执行器
*/
private final TransferBatchService firstService;
/**
* 转账请求执行器
*/
private final TransferBatchService secondService;
/**
* 初始化转账微信转账到零钱 执行器
*/
@Autowired
public TransferBatchUtil(RSAAutoCertificateConfig firstMchConfig,RSAAutoCertificateConfig secondMchConfig){
firstService = new TransferBatchService.Builder().config(firstMchConfig).build();
secondService = new TransferBatchService.Builder().config(secondMchConfig).build();
}
/**
* 微信转账到零钱 -新版
* @return 转账到零钱响应
*/
public InitiateBatchTransferResponse wechatTransferBatch(TransferBatchDto transferBatchDto){
List<TransferDetailInput> list = buildTransferDetailList(transferBatchDto);
//构建请求参数
InitiateBatchTransferRequest request = new InitiateBatchTransferRequest();
//appid
request.setAppid(transferBatchDto.getAppid());
request.setOutBatchNo(transferBatchDto.getOutBatchNo());
//批量转账名称
request.setBatchName(transferBatchDto.getBatchName());
//批量转账备注
request.setBatchRemark(transferBatchDto.getBatchRemark());
//批量转账总金额
request.setTotalAmount(transferBatchDto.getTotalAmount());
//转账总笔数
request.setTotalNum(list.size());
//批量转账明细
request.setTransferDetailList(list);
//【转账场景ID】 该批次转账使用的转账场景,如不填写则使用商家的默认场景,如无默认场景可为空,可前往“商家转账到零钱-前往功能”中申请。
//如:1001-现金营销
request.setTransferSceneId("1001");
log.info("[执行微信批量转账] request:{}",request);
if (transferBatchDto.getMchid().equals("first_mch_id")){
return firstService.initiateBatchTransfer(request);
}else{
return secondService.initiateBatchTransfer(request);
}
}
/**
* 查询微信转账到零钱批次单 -新版
* 微信批次单号查单接口。商户可以通过该接口查询转账批次单以及指定状态的转账明细单。返回消息中包含微信批次单号、批次状态、批次类型、转账总金额、转账总笔数、成功金额、失败金额等信息。
* @param out_batch_no 批次单号
* @param mchid 商户号
* @return 批次情况
*/
public TransferBatchEntity getTransferBatchByNo(String out_batch_no,String mchid){
GetTransferBatchByOutNoRequest request = new GetTransferBatchByOutNoRequest();
// 【微信批次单号】 微信批次单号,微信商家转账系统返回的唯一标识
request.setOutBatchNo(out_batch_no);
//【是否查询转账明细单】 true-是;false-否,默认否。商户可选择是否查询指定状态的转账明细单,当转账批次单状态为“FINISHED”(已完成)时,才会返回满足条件的转账明细单
request.setNeedQueryDetail(true);
//【请求资源起始位置】 该次请求资源的起始位置。返回的明细是按照设置的明细条数进行分页展示的,一次查询可能无法返回所有明细,我们使用该参数标识查询开始位置,默认值为0
request.setOffset(0);
//【最大资源条数】 该次请求可返回的最大明细条数,最小20条,最大100条,不传则默认20条。不足20条按实际条数返回
request.setLimit(40);
//【明细状态】 WAIT_PAY: 待确认。待商户确认, 符合免密条件时, 系统会自动扭转为转账中
//ALL:全部。需要同时查询转账成功、失败和待确认的明细单
//SUCCESS:转账成功
//FAIL:转账失败。需要确认失败原因后,再决定是否重新发起对该笔明细单的转账(并非整个转账批次单)
request.setDetailStatus("ALL");
log.info("[微信批次回查] out_batch_no:{}",out_batch_no);
if (mchid.equals("first_mch_id")){
return firstService.getTransferBatchByOutNo(request);
}else{
return secondService.getTransferBatchByOutNo(request);
}
}
/**
* 构建批量转账明细参数 -新版
* @return 明细集合
*/
public List<TransferDetailInput> buildTransferDetailList(TransferBatchDto transferBatchDto){
List<TransferDetailInput> list = new ArrayList<>();
int amount = transferBatchDto.getTotalAmount().intValue();
if (amount >50000) {
//如果转账金额大于500
int num = amount/50000;
int money = amount%50000;
if (money>0) num++;
for (int i = 0; i < num; i++) {
TransferDetailInput transferDetailInput = new TransferDetailInput();
transferDetailInput.setOutDetailNo(UUID.randomUUID().toString());
if (i==num-1 && money>0){
//转账金额
transferDetailInput.setTransferAmount((long) money);
}else {
//转账金额
transferDetailInput.setTransferAmount(50000L);
}
transferDetailInput.setTransferRemark(transferBatchDto.getBatchRemark());
transferDetailInput.setOpenid(transferBatchDto.getOpenid());
transferDetailInput.setUserName(transferBatchDto.getUsername());
list.add(transferDetailInput);
}
}else{
TransferDetailInput transferDetailInput = new TransferDetailInput();
transferDetailInput.setOutDetailNo(UUID.randomUUID().toString());
//转账金额
transferDetailInput.setTransferAmount(((long) amount));
transferDetailInput.setTransferRemark(transferBatchDto.getBatchRemark());
transferDetailInput.setOpenid(transferBatchDto.getOpenid());
transferDetailInput.setUserName(transferBatchDto.getUsername());
list.add(transferDetailInput);
}
log.info("[转账明细构建完毕] size:{}",list.size());
return list;
}
/**
* 商户明细单号查单接口。商户可以通过该接口查询单笔转账明细单。返回消息中包含微信明细单号、明细状态、转账金额、失败原因、收款用户姓名、用户OpenID等信息。
* @param out_batch_no 商家转账批次单号
* @param out_detail_no 商家明细单号
* @param mchid 商户号
* @
*/
public TransferDetailEntity getTransferDetailByOutNo(String out_batch_no,String out_detail_no,String mchid){
GetTransferDetailByOutNoRequest request =
new GetTransferDetailByOutNoRequest();
request.setOutDetailNo(out_detail_no);
request.setOutBatchNo(out_batch_no);
log.info("[微信转账明细查询] batch_no:{},detail_no:{}",out_batch_no,out_detail_no);
if (mchid.equals("first_mch_id")){
return firstService.getTransferDetailByOutNo(request);
}else{
return secondService.getTrans