添加分账请求接口;
This commit is contained in:
parent
fa6e00c3ee
commit
0be119cc1c
|
|
@ -54,6 +54,9 @@ public class PayOrderDivisionMQ extends AbstractMQ {
|
|||
/** 支付订单号 **/
|
||||
private String payOrderId;
|
||||
|
||||
/** 是否使用默认分组 **/
|
||||
private Byte useSysAutoDivisionReceivers;
|
||||
|
||||
/**
|
||||
* 分账接受者列表, 字段值为空表示系统默认配置项。
|
||||
* 格式:{receiverId: '1001', receiverGroupId: '1001', divisionProfit: '0.1'}
|
||||
|
|
@ -80,8 +83,8 @@ public class PayOrderDivisionMQ extends AbstractMQ {
|
|||
}
|
||||
|
||||
/** 【!重要配置项!】 构造MQModel , 一般用于发送MQ时 **/
|
||||
public static PayOrderDivisionMQ build(String payOrderId, List<CustomerDivisionReceiver> receiverList){
|
||||
return new PayOrderDivisionMQ(new MsgPayload(payOrderId, receiverList));
|
||||
public static PayOrderDivisionMQ build(String payOrderId, Byte useSysAutoDivisionReceivers, List<CustomerDivisionReceiver> receiverList){
|
||||
return new PayOrderDivisionMQ(new MsgPayload(payOrderId, useSysAutoDivisionReceivers, receiverList));
|
||||
}
|
||||
|
||||
/** 解析MQ消息, 一般用于接收MQ消息时 **/
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ public class AmountUtil {
|
|||
* 计算百分比类型的各种费用值 (订单金额 * 真实费率 结果四舍五入并保留0位小数 )
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeepay.vip
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/20 14:53
|
||||
* @param amount 订单金额 (保持与数据库的格式一致 ,单位:分)
|
||||
* @param rate 费率 (保持与数据库的格式一致 ,真实费率值,如费率为0.55%,则传入 0.0055)
|
||||
|
|
@ -138,7 +138,7 @@ public class AmountUtil {
|
|||
* 计算百分比类型的各种费用值 (订单金额 * 真实费率 结果四舍五入并保留0位小数 )
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeepay.vip
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/20 14:53
|
||||
* @param amount 订单金额 (保持与数据库的格式一致 ,单位:分)
|
||||
* @param rate 费率 (保持与数据库的格式一致 ,真实费率值,如费率为0.55%,则传入 0.0055)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||
* 转账订单api
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeepay.vip
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/13 10:52
|
||||
*/
|
||||
@RestController
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||
* 转账订单api
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeepay.vip
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/13 10:52
|
||||
*/
|
||||
@RestController
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import java.util.List;
|
|||
* 分账接口
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeepay.vip
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/22 08:59
|
||||
*/
|
||||
public interface IDivisionService {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import com.jeequan.jeepay.pay.rqrs.transfer.TransferOrderRQ;
|
|||
* 转账接口
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeepay.vip
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/11 13:59
|
||||
*/
|
||||
public interface ITransferService {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ import java.util.List;
|
|||
* 分账接口: 支付宝官方
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeepay.vip
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/22 09:05
|
||||
*/
|
||||
@Slf4j
|
||||
|
|
@ -63,7 +63,6 @@ public class AlipayDivisionService implements IDivisionService {
|
|||
@Override
|
||||
public ChannelRetMsg bind(MchDivisionReceiver mchDivisionReceiver, MchAppConfigContext mchAppConfigContext) {
|
||||
|
||||
|
||||
try {
|
||||
AlipayTradeRoyaltyRelationBindRequest request = new AlipayTradeRoyaltyRelationBindRequest();
|
||||
AlipayTradeRoyaltyRelationBindModel model = new AlipayTradeRoyaltyRelationBindModel();
|
||||
|
|
@ -114,6 +113,10 @@ public class AlipayDivisionService implements IDivisionService {
|
|||
|
||||
try {
|
||||
|
||||
if(recordList.isEmpty()){ // 当无分账用户时, 支付宝不允许发起分账请求, 支付宝没有完结接口,直接响应成功即可。
|
||||
return ChannelRetMsg.confirmSuccess(null);
|
||||
}
|
||||
|
||||
AlipayTradeOrderSettleRequest request = new AlipayTradeOrderSettleRequest();
|
||||
AlipayTradeOrderSettleModel model = new AlipayTradeOrderSettleModel();
|
||||
request.setBizModel(model);
|
||||
|
|
@ -150,7 +153,7 @@ public class AlipayDivisionService implements IDivisionService {
|
|||
|
||||
}
|
||||
|
||||
if(reqReceiverList.isEmpty()){ // 当无分账用户时, 支付宝不允许发起分账请求, 支付宝没有完结解决,直接响应成功即可。
|
||||
if(reqReceiverList.isEmpty()){ // 当无分账用户时, 支付宝不允许发起分账请求, 支付宝没有完结接口,直接响应成功即可。
|
||||
return ChannelRetMsg.confirmSuccess(null);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import org.springframework.stereotype.Service;
|
|||
* 转账接口: 支付宝官方
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeepay.vip
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/11 14:05
|
||||
*/
|
||||
@Slf4j
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ import java.util.List;
|
|||
* 分账接口: 微信官方
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeepay.vip
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/22 09:05
|
||||
*/
|
||||
@Slf4j
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import org.springframework.stereotype.Service;
|
|||
* 转账接口: 微信官方
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeepay.vip
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/11 14:05
|
||||
*/
|
||||
@Slf4j
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ import java.util.Date;
|
|||
* 分账账号绑定
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeepay.vip
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/25 9:07
|
||||
*/
|
||||
@Slf4j
|
||||
|
|
|
|||
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 com.jeequan.jeepay.pay.ctrl.division;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.jeequan.jeepay.components.mq.model.PayOrderDivisionMQ;
|
||||
import com.jeequan.jeepay.core.constants.CS;
|
||||
import com.jeequan.jeepay.core.entity.MchDivisionReceiver;
|
||||
import com.jeequan.jeepay.core.entity.MchDivisionReceiverGroup;
|
||||
import com.jeequan.jeepay.core.entity.PayOrder;
|
||||
import com.jeequan.jeepay.core.entity.PayOrderDivisionRecord;
|
||||
import com.jeequan.jeepay.core.exception.BizException;
|
||||
import com.jeequan.jeepay.core.model.ApiRes;
|
||||
import com.jeequan.jeepay.pay.ctrl.ApiController;
|
||||
import com.jeequan.jeepay.pay.model.MchAppConfigContext;
|
||||
import com.jeequan.jeepay.pay.rqrs.division.PayOrderDivisionExecRQ;
|
||||
import com.jeequan.jeepay.pay.rqrs.division.PayOrderDivisionExecRS;
|
||||
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
|
||||
import com.jeequan.jeepay.pay.service.ConfigContextService;
|
||||
import com.jeequan.jeepay.pay.service.PayOrderDivisionProcessService;
|
||||
import com.jeequan.jeepay.service.impl.MchDivisionReceiverGroupService;
|
||||
import com.jeequan.jeepay.service.impl.MchDivisionReceiverService;
|
||||
import com.jeequan.jeepay.service.impl.PayOrderService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 发起分账请求
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/27 8:01
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
public class PayOrderDivisionExecController extends ApiController {
|
||||
|
||||
@Autowired private ConfigContextService configContextService;
|
||||
@Autowired private PayOrderService payOrderService;
|
||||
@Autowired private MchDivisionReceiverService mchDivisionReceiverService;
|
||||
@Autowired private MchDivisionReceiverGroupService mchDivisionReceiverGroupService;
|
||||
@Autowired private PayOrderDivisionProcessService payOrderDivisionProcessService;
|
||||
|
||||
/** 分账执行 **/
|
||||
@PostMapping("/api/division/exec")
|
||||
public ApiRes exec(){
|
||||
|
||||
//获取参数 & 验签
|
||||
PayOrderDivisionExecRQ bizRQ = getRQByWithMchSign(PayOrderDivisionExecRQ.class);
|
||||
|
||||
try {
|
||||
|
||||
if(StringUtils.isAllEmpty(bizRQ.getMchOrderNo(), bizRQ.getPayOrderId())){
|
||||
throw new BizException("mchOrderNo 和 payOrderId不能同时为空");
|
||||
}
|
||||
|
||||
PayOrder payOrder = payOrderService.queryMchOrder(bizRQ.getMchNo(), bizRQ.getPayOrderId(), bizRQ.getMchOrderNo());
|
||||
if(payOrder == null){
|
||||
throw new BizException("订单不存在");
|
||||
}
|
||||
|
||||
if(payOrder.getState() != PayOrder.STATE_SUCCESS || payOrder.getDivisionState() != PayOrder.DIVISION_STATE_UNHAPPEN || payOrder.getDivisionMode() != PayOrder.DIVISION_MODE_MANUAL){
|
||||
throw new BizException("当前订单状态不支持分账");
|
||||
}
|
||||
|
||||
List<PayOrderDivisionMQ.CustomerDivisionReceiver> receiverList = null;
|
||||
|
||||
//不使用默认分组, 需要转换每个账号信息
|
||||
if(bizRQ.getUseSysAutoDivisionReceivers() != CS.YES && !StringUtils.isEmpty(bizRQ.getReceivers())){
|
||||
receiverList = JSON.parseArray(bizRQ.getReceivers(), PayOrderDivisionMQ.CustomerDivisionReceiver.class);
|
||||
}
|
||||
|
||||
// 验证账号是否合法
|
||||
this.checkReceiverList(receiverList, payOrder.getIfCode(), bizRQ.getMchNo(), bizRQ.getAppId());
|
||||
|
||||
// 商户配置信息
|
||||
MchAppConfigContext mchAppConfigContext = configContextService.getMchAppConfigContext(bizRQ.getMchNo(), bizRQ.getAppId());
|
||||
if(mchAppConfigContext == null){
|
||||
throw new BizException("获取商户应用信息失败");
|
||||
}
|
||||
|
||||
//处理分账请求
|
||||
ChannelRetMsg channelRetMsg = payOrderDivisionProcessService.processPayOrderDivision(bizRQ.getPayOrderId(), bizRQ.getUseSysAutoDivisionReceivers(), receiverList);
|
||||
|
||||
PayOrderDivisionExecRS bizRS = new PayOrderDivisionExecRS();
|
||||
bizRS.setState(channelRetMsg.getChannelState() == ChannelRetMsg.ChannelState.CONFIRM_SUCCESS ? PayOrderDivisionRecord.STATE_SUCCESS : PayOrderDivisionRecord.STATE_FAIL);
|
||||
bizRS.setChannelBatchOrderId(channelRetMsg.getChannelOrderId());
|
||||
bizRS.setErrCode(channelRetMsg.getChannelErrCode());
|
||||
bizRS.setErrMsg(channelRetMsg.getChannelErrMsg());
|
||||
|
||||
return ApiRes.okWithSign(bizRS, mchAppConfigContext.getMchApp().getAppSecret());
|
||||
|
||||
} catch (BizException e) {
|
||||
return ApiRes.customFail(e.getMessage());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("系统异常:{}", e);
|
||||
return ApiRes.customFail("系统异常");
|
||||
}
|
||||
}
|
||||
|
||||
/** 检验账号是否合法 **/
|
||||
private void checkReceiverList(List<PayOrderDivisionMQ.CustomerDivisionReceiver> receiverList, String ifCode, String mchNo, String appId){
|
||||
|
||||
if(receiverList == null || receiverList.isEmpty()){
|
||||
return ;
|
||||
}
|
||||
|
||||
Set<Long> receiverIdSet = new HashSet<>();
|
||||
Set<Long> receiverGroupIdSet = new HashSet<>();
|
||||
|
||||
for (PayOrderDivisionMQ.CustomerDivisionReceiver receiver : receiverList) {
|
||||
|
||||
if(receiver.getReceiverId() != null){
|
||||
receiverIdSet.add(receiver.getReceiverId());
|
||||
}
|
||||
|
||||
if(receiver.getReceiverGroupId() != null){
|
||||
receiverGroupIdSet.add(receiver.getReceiverGroupId());
|
||||
}
|
||||
|
||||
if(receiver.getReceiverId() == null && receiver.getReceiverGroupId() == null){
|
||||
throw new BizException("分账用户组: receiverId 和 与receiverGroupId 必填一项");
|
||||
}
|
||||
|
||||
if(receiver.getDivisionProfit() != null){
|
||||
|
||||
if(receiver.getDivisionProfit().compareTo(BigDecimal.ZERO) < 0){
|
||||
throw new BizException("分账用户receiverId=["+receiver.getReceiverId() == null ? "": receiver.getReceiverId()+"]," +
|
||||
"receiverGroupId=["+receiver.getReceiverGroupId() == null ? "": receiver.getReceiverGroupId()+"] 分账比例不得小于0%");
|
||||
}
|
||||
|
||||
if(receiver.getDivisionProfit().compareTo(BigDecimal.ONE) > 0){
|
||||
throw new BizException("分账用户receiverId=["+receiver.getReceiverId() == null ? "": receiver.getReceiverId()+"]," +
|
||||
"receiverGroupId=["+receiver.getReceiverGroupId() == null ? "": receiver.getReceiverGroupId()+"] 分账比例不得高于100%");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!receiverIdSet.isEmpty()){
|
||||
|
||||
int receiverCount = mchDivisionReceiverService.count(MchDivisionReceiver.gw()
|
||||
.in(MchDivisionReceiver::getReceiverId, receiverIdSet)
|
||||
.eq(MchDivisionReceiver::getMchNo, mchNo)
|
||||
.eq(MchDivisionReceiver::getAppId, appId)
|
||||
.eq(MchDivisionReceiver::getIfCode, ifCode)
|
||||
.eq(MchDivisionReceiver::getState, CS.YES)
|
||||
);
|
||||
|
||||
if(receiverCount != receiverIdSet.size()){
|
||||
throw new BizException("分账[用户]中包含不存在或渠道不可用账号,请更改");
|
||||
}
|
||||
}
|
||||
|
||||
if(!receiverGroupIdSet.isEmpty()){
|
||||
|
||||
int receiverGroupCount = mchDivisionReceiverGroupService.count(MchDivisionReceiverGroup.gw()
|
||||
.in(MchDivisionReceiverGroup::getReceiverGroupId, receiverGroupIdSet)
|
||||
.eq(MchDivisionReceiverGroup::getMchNo, mchNo)
|
||||
);
|
||||
|
||||
if(receiverGroupCount != receiverGroupIdSet.size()){
|
||||
throw new BizException("分账[账号组]中包含不存在或不可用组,请更改");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ import java.util.Date;
|
|||
* 转账接口
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeepay.vip
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/11 11:07
|
||||
*/
|
||||
@Slf4j
|
||||
|
|
|
|||
|
|
@ -15,38 +15,12 @@
|
|||
*/
|
||||
package com.jeequan.jeepay.pay.mq;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.jeequan.jeepay.components.mq.model.PayOrderDivisionMQ;
|
||||
import com.jeequan.jeepay.core.constants.CS;
|
||||
import com.jeequan.jeepay.core.entity.MchDivisionReceiver;
|
||||
import com.jeequan.jeepay.core.entity.MchDivisionReceiverGroup;
|
||||
import com.jeequan.jeepay.core.entity.PayOrder;
|
||||
import com.jeequan.jeepay.core.entity.PayOrderDivisionRecord;
|
||||
import com.jeequan.jeepay.core.exception.BizException;
|
||||
import com.jeequan.jeepay.core.utils.AmountUtil;
|
||||
import com.jeequan.jeepay.core.utils.JeepayKit;
|
||||
import com.jeequan.jeepay.core.utils.SeqKit;
|
||||
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
|
||||
import com.jeequan.jeepay.pay.channel.IDivisionService;
|
||||
import com.jeequan.jeepay.pay.channel.ITransferService;
|
||||
import com.jeequan.jeepay.pay.model.MchAppConfigContext;
|
||||
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
|
||||
import com.jeequan.jeepay.pay.service.ConfigContextService;
|
||||
import com.jeequan.jeepay.service.impl.MchDivisionReceiverGroupService;
|
||||
import com.jeequan.jeepay.service.impl.MchDivisionReceiverService;
|
||||
import com.jeequan.jeepay.service.impl.PayOrderDivisionRecordService;
|
||||
import com.jeequan.jeepay.service.impl.PayOrderService;
|
||||
import com.jeequan.jeepay.pay.service.PayOrderDivisionProcessService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 接收MQ消息
|
||||
* 业务: 支付订单分账处理逻辑
|
||||
|
|
@ -58,232 +32,18 @@ import java.util.List;
|
|||
@Component
|
||||
public class PayOrderDivisionMQReceiver implements PayOrderDivisionMQ.IMQReceiver {
|
||||
|
||||
@Autowired
|
||||
private PayOrderService payOrderService;
|
||||
@Autowired
|
||||
private MchDivisionReceiverService mchDivisionReceiverService;
|
||||
@Autowired
|
||||
private MchDivisionReceiverGroupService mchDivisionReceiverGroupService;
|
||||
@Autowired
|
||||
private PayOrderDivisionRecordService payOrderDivisionRecordService;
|
||||
@Autowired
|
||||
private ConfigContextService configContextService;
|
||||
@Autowired private PayOrderDivisionProcessService payOrderDivisionProcessService;
|
||||
|
||||
@Override
|
||||
public void receive(PayOrderDivisionMQ.MsgPayload payload) {
|
||||
|
||||
try {
|
||||
|
||||
log.info("接收订单分账通知MQ, msg={}", payload.toString());
|
||||
|
||||
String logPrefix = "订单["+payload.getPayOrderId()+"]执行分账";
|
||||
|
||||
//查询订单信息
|
||||
PayOrder payOrder = payOrderService.getById(payload.getPayOrderId());
|
||||
|
||||
if(payOrder == null){
|
||||
log.error("{},订单不存在", logPrefix);
|
||||
return ;
|
||||
}
|
||||
|
||||
if(payOrder.getState() != PayOrder.STATE_SUCCESS || payOrder.getDivisionState() != PayOrder.DIVISION_STATE_WAIT_TASK){
|
||||
log.error("{}, 订单状态或分账状态不正确", logPrefix);
|
||||
return ;
|
||||
}
|
||||
|
||||
//更新订单为: 分账任务处理中
|
||||
boolean updPayOrder = payOrderService.update(new LambdaUpdateWrapper<PayOrder>()
|
||||
.set(PayOrder::getDivisionState, PayOrder.DIVISION_STATE_ING)
|
||||
.eq(PayOrder::getPayOrderId, payload.getPayOrderId())
|
||||
.eq(PayOrder::getDivisionState, PayOrder.DIVISION_STATE_WAIT_TASK));
|
||||
if(!updPayOrder){
|
||||
log.error("{}, 更新支付订单为分账处理中异常!", logPrefix);
|
||||
return ;
|
||||
}
|
||||
|
||||
// 查询&过滤 所有的分账接收对象
|
||||
List<MchDivisionReceiver> allReceiver = this.queryReceiver(payOrder, payload.getReceiverList());
|
||||
|
||||
//得到全部分账比例 (所有待分账账号的分账比例总和)
|
||||
BigDecimal allDivisionProfit = BigDecimal.ZERO;
|
||||
for (MchDivisionReceiver receiver : allReceiver) {
|
||||
allDivisionProfit = allDivisionProfit.add(receiver.getDivisionProfit());
|
||||
}
|
||||
|
||||
//计算分账金额 = 商家实际入账金额
|
||||
Long payOrderDivisionAmount = payOrderService.calMchIncomeAmount(payOrder);
|
||||
|
||||
//剩余待分账金额 (用作最后一个分账账号的 计算, 避免出现分账金额超出最大) [结果向下取整 , 避免出现金额溢出的情况。 ]
|
||||
Long subDivisionAmount = AmountUtil.calPercentageFee(payOrderDivisionAmount, allDivisionProfit, BigDecimal.ROUND_FLOOR);
|
||||
|
||||
List<PayOrderDivisionRecord> recordList = new ArrayList<>();
|
||||
|
||||
//计算订单分账金额, 并插入到记录表
|
||||
|
||||
String batchOrderId = SeqKit.genDivisionBatchId();
|
||||
|
||||
for (MchDivisionReceiver receiver : allReceiver) {
|
||||
|
||||
PayOrderDivisionRecord record = genRecord(batchOrderId, payOrder, receiver, payOrderDivisionAmount, subDivisionAmount);
|
||||
|
||||
//剩余金额
|
||||
subDivisionAmount = subDivisionAmount - record.getCalDivisionAmount();
|
||||
|
||||
//入库保存
|
||||
payOrderDivisionRecordService.save(record);
|
||||
recordList.add(record);
|
||||
}
|
||||
|
||||
try{
|
||||
|
||||
//调用渠道侧分账接口
|
||||
|
||||
IDivisionService divisionService = SpringBeansUtil.getBean(payOrder.getIfCode() + "DivisionService", IDivisionService.class);
|
||||
if(divisionService == null){
|
||||
throw new BizException("通道无此分账接口");
|
||||
}
|
||||
|
||||
ChannelRetMsg channelRetMsg = divisionService.singleDivision(payOrder, recordList, configContextService.getMchAppConfigContext(payOrder.getMchNo(), payOrder.getAppId()));
|
||||
|
||||
// 确认分账成功
|
||||
if(channelRetMsg.getChannelState() == ChannelRetMsg.ChannelState.CONFIRM_SUCCESS) {
|
||||
|
||||
//分账成功
|
||||
payOrderDivisionRecordService.updateRecordSuccessOrFail(recordList, PayOrderDivisionRecord.STATE_SUCCESS,
|
||||
channelRetMsg.getChannelOrderId(), channelRetMsg.getChannelOriginResponse());
|
||||
|
||||
}else{
|
||||
//分账失败
|
||||
payOrderDivisionRecordService.updateRecordSuccessOrFail(recordList, PayOrderDivisionRecord.STATE_FAIL,
|
||||
channelRetMsg.getChannelOrderId(), channelRetMsg.getChannelErrMsg());
|
||||
}
|
||||
|
||||
} catch (BizException e) {
|
||||
log.error("{}, 调用分账接口异常, {}", logPrefix, e.getMessage());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("{}, 调用分账接口异常", logPrefix, e);
|
||||
payOrderDivisionRecordService.updateRecordSuccessOrFail(recordList, PayOrderDivisionRecord.STATE_FAIL,
|
||||
null, "系统异常:" + e.getMessage());
|
||||
}
|
||||
|
||||
//更新 支付订单主表状态 分账任务已结束。
|
||||
payOrderService.update(new LambdaUpdateWrapper<PayOrder>()
|
||||
.set(PayOrder::getDivisionState, PayOrder.DIVISION_STATE_FINISH)
|
||||
.set(PayOrder::getDivisionLastTime, new Date())
|
||||
.eq(PayOrder::getPayOrderId, payload.getPayOrderId())
|
||||
.eq(PayOrder::getDivisionState, PayOrder.DIVISION_STATE_ING)
|
||||
);
|
||||
payOrderDivisionProcessService.processPayOrderDivision(payload.getPayOrderId(), payload.getUseSysAutoDivisionReceivers(), payload.getReceiverList());
|
||||
|
||||
}catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** 生成对象信息 **/
|
||||
private PayOrderDivisionRecord genRecord(String batchOrderId, PayOrder payOrder, MchDivisionReceiver receiver,
|
||||
Long payOrderDivisionAmount, Long subDivisionAmount){
|
||||
|
||||
PayOrderDivisionRecord record = new PayOrderDivisionRecord();
|
||||
record.setMchNo(payOrder.getMchNo());
|
||||
record.setIsvNo(payOrder.getIsvNo());
|
||||
record.setAppId(payOrder.getAppId());
|
||||
record.setMchName(payOrder.getMchName());
|
||||
record.setMchType(payOrder.getMchType());
|
||||
record.setIfCode(payOrder.getIfCode());
|
||||
record.setPayOrderId(payOrder.getPayOrderId());
|
||||
record.setPayOrderChannelOrderNo(payOrder.getChannelOrderNo()); //支付订单渠道订单号
|
||||
record.setPayOrderAmount(payOrder.getAmount()); //订单金额
|
||||
record.setPayOrderDivisionAmount(payOrderDivisionAmount); // 订单计算分账金额
|
||||
record.setBatchOrderId(batchOrderId); //系统分账批次号
|
||||
record.setState(PayOrderDivisionRecord.STATE_WAIT); //状态: 待分账
|
||||
record.setReceiverId(receiver.getReceiverId());
|
||||
record.setReceiverGroupId(receiver.getReceiverGroupId());
|
||||
record.setReceiverAlias(receiver.getReceiverAlias());
|
||||
record.setAccType(receiver.getAccType());
|
||||
record.setAccNo(receiver.getAccNo());
|
||||
record.setAccName(receiver.getAccName());
|
||||
record.setRelationType(receiver.getRelationType());
|
||||
record.setRelationTypeName(receiver.getRelationTypeName());
|
||||
record.setDivisionProfit(receiver.getDivisionProfit());
|
||||
|
||||
if( subDivisionAmount <= 0 ) {
|
||||
record.setCalDivisionAmount(0L);
|
||||
}else{
|
||||
|
||||
//计算的分账金额
|
||||
record.setCalDivisionAmount(AmountUtil.calPercentageFee(record.getPayOrderDivisionAmount(), record.getDivisionProfit()));
|
||||
if(record.getCalDivisionAmount() > subDivisionAmount){ // 分账金额超过剩余总金额时: 将按照剩余金额进行分账。
|
||||
record.setCalDivisionAmount(subDivisionAmount);
|
||||
}
|
||||
}
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
private List<MchDivisionReceiver> queryReceiver(PayOrder payOrder, List<PayOrderDivisionMQ.CustomerDivisionReceiver> customerDivisionReceiverList){
|
||||
|
||||
// 查询全部分账列表
|
||||
LambdaQueryWrapper<MchDivisionReceiver> queryWrapper = MchDivisionReceiver.gw();
|
||||
|
||||
queryWrapper.eq(MchDivisionReceiver::getMchNo, payOrder.getMchNo()); //mchNo
|
||||
queryWrapper.eq(MchDivisionReceiver::getAppId, payOrder.getAppId()); //appId
|
||||
queryWrapper.eq(MchDivisionReceiver::getIfCode, payOrder.getIfCode()); //ifCode
|
||||
queryWrapper.eq(MchDivisionReceiver::getState, CS.PUB_USABLE); // 可用状态的账号
|
||||
|
||||
// 未设置接收者账号信息, 需要查询 自动分账组的账号
|
||||
if(customerDivisionReceiverList == null){
|
||||
|
||||
List<MchDivisionReceiverGroup> groups = mchDivisionReceiverGroupService.list(
|
||||
MchDivisionReceiverGroup.gw().eq(MchDivisionReceiverGroup::getMchNo, payOrder.getMchNo())
|
||||
.eq(MchDivisionReceiverGroup::getAutoDivisionFlag, CS.YES));
|
||||
|
||||
if(groups.isEmpty()){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
queryWrapper.eq(MchDivisionReceiver::getReceiverGroupId, groups.get(0).getReceiverGroupId());
|
||||
}
|
||||
|
||||
//全部分账账号
|
||||
List<MchDivisionReceiver> allMchReceiver = mchDivisionReceiverService.list(queryWrapper);
|
||||
if(allMchReceiver.isEmpty()){
|
||||
return allMchReceiver;
|
||||
}
|
||||
|
||||
// 自定义列表未定义
|
||||
if(customerDivisionReceiverList == null){
|
||||
return allMchReceiver;
|
||||
}
|
||||
|
||||
//参数有定义,但是没有任何值
|
||||
if(customerDivisionReceiverList.isEmpty()){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 过滤账号
|
||||
List<MchDivisionReceiver> filterMchReceiver = new ArrayList<>();
|
||||
|
||||
for (MchDivisionReceiver mchDivisionReceiver : allMchReceiver) {
|
||||
for (PayOrderDivisionMQ.CustomerDivisionReceiver customerDivisionReceiver : customerDivisionReceiverList) {
|
||||
|
||||
// 查询匹配相同的项目
|
||||
if( mchDivisionReceiver.getReceiverId().equals(customerDivisionReceiver.getReceiverId()) ||
|
||||
mchDivisionReceiver.getReceiverGroupId().equals(customerDivisionReceiver.getReceiverGroupId())
|
||||
){
|
||||
|
||||
// 重新对分账比例赋值
|
||||
if(customerDivisionReceiver.getDivisionProfit() != null){
|
||||
mchDivisionReceiver.setDivisionProfit(customerDivisionReceiver.getDivisionProfit());
|
||||
}
|
||||
filterMchReceiver.add(mchDivisionReceiver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filterMchReceiver;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 com.jeequan.jeepay.pay.rqrs.division;
|
||||
|
||||
import com.jeequan.jeepay.pay.rqrs.AbstractMchAppRQ;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/*
|
||||
* 发起订单分账 请求参数
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/26 17:21
|
||||
*/
|
||||
@Data
|
||||
public class PayOrderDivisionExecRQ extends AbstractMchAppRQ {
|
||||
|
||||
/** 商户订单号 **/
|
||||
private String mchOrderNo;
|
||||
|
||||
/** 支付系统订单号 **/
|
||||
private String payOrderId;
|
||||
|
||||
/**
|
||||
* 是否使用系统配置的自动分账组: 0-否 1-是
|
||||
**/
|
||||
@NotNull(message = "是否使用系统配置的自动分账组不能为空")
|
||||
private Byte useSysAutoDivisionReceivers;
|
||||
|
||||
/** 接收者账号列表(JSONArray 转换为字符串类型)
|
||||
* 仅当useSysAutoDivisionReceivers=0 时有效。
|
||||
*
|
||||
* 参考:
|
||||
*
|
||||
* 方式1: 按账号纬度
|
||||
* [{
|
||||
* receiverId: 800001,
|
||||
* divisionProfit: 0.1 (若不填入则使用系统默认配置值)
|
||||
* }]
|
||||
*
|
||||
* 方式2: 按组纬度
|
||||
* [{
|
||||
* receiverGroupId: 100001, (该组所有 当前订单的渠道账号并且可用状态的全部参与分账)
|
||||
* divisionProfit: 0.1 (每个账号的分账比例, 若不填入则使用系统默认配置值, 建议不填写)
|
||||
* }]
|
||||
*
|
||||
* **/
|
||||
private String receivers;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 com.jeequan.jeepay.pay.rqrs.division;
|
||||
|
||||
import com.jeequan.jeepay.pay.rqrs.AbstractRS;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 发起订单分账 响应参数
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/26 17:20
|
||||
*/
|
||||
@Data
|
||||
public class PayOrderDivisionExecRS extends AbstractRS {
|
||||
|
||||
/**
|
||||
* 分账状态 1-分账成功, 2-分账失败
|
||||
*/
|
||||
private Byte state;
|
||||
|
||||
/**
|
||||
* 上游分账批次号
|
||||
*/
|
||||
private String channelBatchOrderId;
|
||||
|
||||
/**
|
||||
* 支付渠道错误码
|
||||
*/
|
||||
private String errCode;
|
||||
|
||||
/**
|
||||
* 支付渠道错误信息
|
||||
*/
|
||||
private String errMsg;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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 com.jeequan.jeepay.pay.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.jeequan.jeepay.components.mq.model.PayOrderDivisionMQ;
|
||||
import com.jeequan.jeepay.core.constants.CS;
|
||||
import com.jeequan.jeepay.core.entity.MchDivisionReceiver;
|
||||
import com.jeequan.jeepay.core.entity.MchDivisionReceiverGroup;
|
||||
import com.jeequan.jeepay.core.entity.PayOrder;
|
||||
import com.jeequan.jeepay.core.entity.PayOrderDivisionRecord;
|
||||
import com.jeequan.jeepay.core.exception.BizException;
|
||||
import com.jeequan.jeepay.core.utils.AmountUtil;
|
||||
import com.jeequan.jeepay.core.utils.SeqKit;
|
||||
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
|
||||
import com.jeequan.jeepay.pay.channel.IDivisionService;
|
||||
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
|
||||
import com.jeequan.jeepay.service.impl.MchDivisionReceiverGroupService;
|
||||
import com.jeequan.jeepay.service.impl.MchDivisionReceiverService;
|
||||
import com.jeequan.jeepay.service.impl.PayOrderDivisionRecordService;
|
||||
import com.jeequan.jeepay.service.impl.PayOrderService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 业务: 支付订单分账处理逻辑
|
||||
* @author terrfly
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/27 9:43
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class PayOrderDivisionProcessService {
|
||||
|
||||
@Autowired
|
||||
private PayOrderService payOrderService;
|
||||
@Autowired
|
||||
private MchDivisionReceiverService mchDivisionReceiverService;
|
||||
@Autowired
|
||||
private MchDivisionReceiverGroupService mchDivisionReceiverGroupService;
|
||||
@Autowired
|
||||
private PayOrderDivisionRecordService payOrderDivisionRecordService;
|
||||
@Autowired
|
||||
private ConfigContextService configContextService;
|
||||
|
||||
/***
|
||||
* 处理分账,
|
||||
* 1. 向外抛异常: 系统检查没有通过 / 系统级别异常
|
||||
* 2 若正常调起接口将返回渠道侧响应结果
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/27 9:44
|
||||
*/
|
||||
public ChannelRetMsg processPayOrderDivision(String payOrderId, Byte useSysAutoDivisionReceivers, List<PayOrderDivisionMQ.CustomerDivisionReceiver> receiverList) {
|
||||
|
||||
String logPrefix = "订单["+payOrderId+"]执行分账";
|
||||
|
||||
//查询订单信息
|
||||
PayOrder payOrder = payOrderService.getById(payOrderId);
|
||||
|
||||
if(payOrder == null){
|
||||
log.error("{},订单不存在", logPrefix);
|
||||
throw new BizException("订单不存在");
|
||||
}
|
||||
|
||||
// 订单不是成功状态 || 分账状态不正确
|
||||
if(payOrder.getState() != PayOrder.STATE_SUCCESS ||
|
||||
(
|
||||
payOrder.getDivisionState() != PayOrder.DIVISION_STATE_WAIT_TASK
|
||||
&& payOrder.getDivisionState() != PayOrder.DIVISION_STATE_UNHAPPEN
|
||||
)){
|
||||
log.error("{}, 订单状态或分账状态不正确", logPrefix);
|
||||
throw new BizException("订单状态或分账状态不正确");
|
||||
}
|
||||
|
||||
//更新订单为: 分账任务处理中
|
||||
boolean updPayOrder = payOrderService.update(new LambdaUpdateWrapper<PayOrder>()
|
||||
.set(PayOrder::getDivisionState, PayOrder.DIVISION_STATE_ING)
|
||||
.eq(PayOrder::getPayOrderId, payOrderId)
|
||||
.eq(PayOrder::getDivisionState, payOrder.getDivisionState()));
|
||||
if(!updPayOrder){
|
||||
log.error("{}, 更新支付订单为分账处理中异常!", logPrefix);
|
||||
throw new BizException("更新支付订单为分账处理中异常");
|
||||
}
|
||||
|
||||
// 查询&过滤 所有的分账接收对象
|
||||
List<MchDivisionReceiver> allReceiver = this.queryReceiver(useSysAutoDivisionReceivers, payOrder, receiverList);
|
||||
|
||||
//得到全部分账比例 (所有待分账账号的分账比例总和)
|
||||
BigDecimal allDivisionProfit = BigDecimal.ZERO;
|
||||
for (MchDivisionReceiver receiver : allReceiver) {
|
||||
allDivisionProfit = allDivisionProfit.add(receiver.getDivisionProfit());
|
||||
}
|
||||
|
||||
//计算分账金额 = 商家实际入账金额
|
||||
Long payOrderDivisionAmount = payOrderService.calMchIncomeAmount(payOrder);
|
||||
|
||||
//剩余待分账金额 (用作最后一个分账账号的 计算, 避免出现分账金额超出最大) [结果向下取整 , 避免出现金额溢出的情况。 ]
|
||||
Long subDivisionAmount = AmountUtil.calPercentageFee(payOrderDivisionAmount, allDivisionProfit, BigDecimal.ROUND_FLOOR);
|
||||
|
||||
List<PayOrderDivisionRecord> recordList = new ArrayList<>();
|
||||
|
||||
//计算订单分账金额, 并插入到记录表
|
||||
|
||||
String batchOrderId = SeqKit.genDivisionBatchId();
|
||||
|
||||
for (MchDivisionReceiver receiver : allReceiver) {
|
||||
|
||||
PayOrderDivisionRecord record = genRecord(batchOrderId, payOrder, receiver, payOrderDivisionAmount, subDivisionAmount);
|
||||
|
||||
//剩余金额
|
||||
subDivisionAmount = subDivisionAmount - record.getCalDivisionAmount();
|
||||
|
||||
//入库保存
|
||||
payOrderDivisionRecordService.save(record);
|
||||
recordList.add(record);
|
||||
}
|
||||
|
||||
ChannelRetMsg channelRetMsg = null;
|
||||
|
||||
try{
|
||||
|
||||
//调用渠道侧分账接口
|
||||
IDivisionService divisionService = SpringBeansUtil.getBean(payOrder.getIfCode() + "DivisionService", IDivisionService.class);
|
||||
if(divisionService == null){
|
||||
throw new BizException("通道无此分账接口");
|
||||
}
|
||||
|
||||
channelRetMsg = divisionService.singleDivision(payOrder, recordList, configContextService.getMchAppConfigContext(payOrder.getMchNo(), payOrder.getAppId()));
|
||||
|
||||
// 确认分账成功
|
||||
if(channelRetMsg.getChannelState() == ChannelRetMsg.ChannelState.CONFIRM_SUCCESS) {
|
||||
|
||||
//分账成功
|
||||
payOrderDivisionRecordService.updateRecordSuccessOrFail(recordList, PayOrderDivisionRecord.STATE_SUCCESS,
|
||||
channelRetMsg.getChannelOrderId(), channelRetMsg.getChannelOriginResponse());
|
||||
|
||||
}else{
|
||||
//分账失败
|
||||
payOrderDivisionRecordService.updateRecordSuccessOrFail(recordList, PayOrderDivisionRecord.STATE_FAIL,
|
||||
channelRetMsg.getChannelOrderId(), channelRetMsg.getChannelErrMsg());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("{}, 调用分账接口异常", logPrefix, e);
|
||||
payOrderDivisionRecordService.updateRecordSuccessOrFail(recordList, PayOrderDivisionRecord.STATE_FAIL,
|
||||
null, "系统异常:" + e.getMessage());
|
||||
|
||||
channelRetMsg = ChannelRetMsg.confirmFail(null, null, e.getMessage());
|
||||
}
|
||||
|
||||
//更新 支付订单主表状态 分账任务已结束。
|
||||
payOrderService.update(new LambdaUpdateWrapper<PayOrder>()
|
||||
.set(PayOrder::getDivisionState, PayOrder.DIVISION_STATE_FINISH)
|
||||
.set(PayOrder::getDivisionLastTime, new Date())
|
||||
.eq(PayOrder::getPayOrderId, payOrderId)
|
||||
.eq(PayOrder::getDivisionState, PayOrder.DIVISION_STATE_ING)
|
||||
);
|
||||
|
||||
return channelRetMsg;
|
||||
}
|
||||
|
||||
|
||||
/** 生成对象信息 **/
|
||||
private PayOrderDivisionRecord genRecord(String batchOrderId, PayOrder payOrder, MchDivisionReceiver receiver,
|
||||
Long payOrderDivisionAmount, Long subDivisionAmount){
|
||||
|
||||
PayOrderDivisionRecord record = new PayOrderDivisionRecord();
|
||||
record.setMchNo(payOrder.getMchNo());
|
||||
record.setIsvNo(payOrder.getIsvNo());
|
||||
record.setAppId(payOrder.getAppId());
|
||||
record.setMchName(payOrder.getMchName());
|
||||
record.setMchType(payOrder.getMchType());
|
||||
record.setIfCode(payOrder.getIfCode());
|
||||
record.setPayOrderId(payOrder.getPayOrderId());
|
||||
record.setPayOrderChannelOrderNo(payOrder.getChannelOrderNo()); //支付订单渠道订单号
|
||||
record.setPayOrderAmount(payOrder.getAmount()); //订单金额
|
||||
record.setPayOrderDivisionAmount(payOrderDivisionAmount); // 订单计算分账金额
|
||||
record.setBatchOrderId(batchOrderId); //系统分账批次号
|
||||
record.setState(PayOrderDivisionRecord.STATE_WAIT); //状态: 待分账
|
||||
record.setReceiverId(receiver.getReceiverId());
|
||||
record.setReceiverGroupId(receiver.getReceiverGroupId());
|
||||
record.setReceiverAlias(receiver.getReceiverAlias());
|
||||
record.setAccType(receiver.getAccType());
|
||||
record.setAccNo(receiver.getAccNo());
|
||||
record.setAccName(receiver.getAccName());
|
||||
record.setRelationType(receiver.getRelationType());
|
||||
record.setRelationTypeName(receiver.getRelationTypeName());
|
||||
record.setDivisionProfit(receiver.getDivisionProfit());
|
||||
|
||||
if( subDivisionAmount <= 0 ) {
|
||||
record.setCalDivisionAmount(0L);
|
||||
}else{
|
||||
|
||||
//计算的分账金额
|
||||
record.setCalDivisionAmount(AmountUtil.calPercentageFee(record.getPayOrderDivisionAmount(), record.getDivisionProfit()));
|
||||
if(record.getCalDivisionAmount() > subDivisionAmount){ // 分账金额超过剩余总金额时: 将按照剩余金额进行分账。
|
||||
record.setCalDivisionAmount(subDivisionAmount);
|
||||
}
|
||||
}
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
private List<MchDivisionReceiver> queryReceiver(Byte useSysAutoDivisionReceivers, PayOrder payOrder, List<PayOrderDivisionMQ.CustomerDivisionReceiver> customerDivisionReceiverList){
|
||||
|
||||
// 查询全部分账列表
|
||||
LambdaQueryWrapper<MchDivisionReceiver> queryWrapper = MchDivisionReceiver.gw();
|
||||
|
||||
queryWrapper.eq(MchDivisionReceiver::getMchNo, payOrder.getMchNo()); //mchNo
|
||||
queryWrapper.eq(MchDivisionReceiver::getAppId, payOrder.getAppId()); //appId
|
||||
queryWrapper.eq(MchDivisionReceiver::getIfCode, payOrder.getIfCode()); //ifCode
|
||||
queryWrapper.eq(MchDivisionReceiver::getState, CS.PUB_USABLE); // 可用状态的账号
|
||||
|
||||
// 自动分账组的账号
|
||||
if(useSysAutoDivisionReceivers == CS.YES) {
|
||||
|
||||
List<MchDivisionReceiverGroup> groups = mchDivisionReceiverGroupService.list(
|
||||
MchDivisionReceiverGroup.gw().eq(MchDivisionReceiverGroup::getMchNo, payOrder.getMchNo())
|
||||
.eq(MchDivisionReceiverGroup::getAutoDivisionFlag, CS.YES));
|
||||
|
||||
if(groups.isEmpty()){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
queryWrapper.eq(MchDivisionReceiver::getReceiverGroupId, groups.get(0).getReceiverGroupId());
|
||||
}
|
||||
|
||||
//全部分账账号
|
||||
List<MchDivisionReceiver> allMchReceiver = mchDivisionReceiverService.list(queryWrapper);
|
||||
if(allMchReceiver.isEmpty()){
|
||||
return allMchReceiver;
|
||||
}
|
||||
|
||||
//自动分账组
|
||||
if(useSysAutoDivisionReceivers == CS.YES){
|
||||
return allMchReceiver;
|
||||
}
|
||||
|
||||
//以下为 自定义列表
|
||||
|
||||
// 自定义列表未定义
|
||||
if(customerDivisionReceiverList == null || customerDivisionReceiverList.isEmpty()){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 过滤账号
|
||||
List<MchDivisionReceiver> filterMchReceiver = new ArrayList<>();
|
||||
|
||||
for (MchDivisionReceiver mchDivisionReceiver : allMchReceiver) {
|
||||
for (PayOrderDivisionMQ.CustomerDivisionReceiver customerDivisionReceiver : customerDivisionReceiverList) {
|
||||
|
||||
// 查询匹配相同的项目
|
||||
if( mchDivisionReceiver.getReceiverId().equals(customerDivisionReceiver.getReceiverId()) ||
|
||||
mchDivisionReceiver.getReceiverGroupId().equals(customerDivisionReceiver.getReceiverGroupId())
|
||||
){
|
||||
|
||||
// 重新对分账比例赋值
|
||||
if(customerDivisionReceiver.getDivisionProfit() != null){
|
||||
mchDivisionReceiver.setDivisionProfit(customerDivisionReceiver.getDivisionProfit());
|
||||
}
|
||||
filterMchReceiver.add(mchDivisionReceiver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filterMchReceiver;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ package com.jeequan.jeepay.pay.service;
|
|||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.jeequan.jeepay.components.mq.model.PayOrderDivisionMQ;
|
||||
import com.jeequan.jeepay.components.mq.vender.IMQSender;
|
||||
import com.jeequan.jeepay.core.constants.CS;
|
||||
import com.jeequan.jeepay.core.entity.PayOrder;
|
||||
import com.jeequan.jeepay.service.impl.PayOrderService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -28,7 +29,7 @@ import org.springframework.stereotype.Service;
|
|||
* 订单处理通用逻辑
|
||||
*
|
||||
* @author terrfly
|
||||
* @site https://www.jeepay.vip
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/22 16:50
|
||||
*/
|
||||
@Service
|
||||
|
|
@ -75,7 +76,7 @@ public class PayOrderProcessService {
|
|||
|
||||
if(updDivisionState){
|
||||
//推送到分账MQ
|
||||
mqSender.send(PayOrderDivisionMQ.build(payOrder.getPayOrderId(), null), 60); //1分钟后执行
|
||||
mqSender.send(PayOrderDivisionMQ.build(payOrder.getPayOrderId(), CS.YES,null), 60); //1分钟后执行
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ public class PayOrderService extends ServiceImpl<PayOrderMapper, PayOrder> {
|
|||
* 计算支付订单商家入账金额
|
||||
* 商家订单入账金额 (支付金额 - 手续费 - 退款金额 - 总分账金额)
|
||||
* @author terrfly
|
||||
* @site https://www.jeepay.vip
|
||||
* @site https://www.jeequan.com
|
||||
* @date 2021/8/26 16:39
|
||||
*/
|
||||
public Long calMchIncomeAmount(PayOrder dbPayOrder){
|
||||
|
|
|
|||
Loading…
Reference in New Issue