@ -1,10 +1,12 @@
package cn.iocoder.yudao.module.pay.service.wxprofitsharing ;
import cn.hutool.core.bean.BeanUtil ;
import cn.hutool.core.collection.CollectionUtil ;
import cn.hutool.core.util.ObjectUtil ;
import cn.iocoder.yudao.framework.common.exception.ErrorCode ;
import cn.iocoder.yudao.framework.common.exception.ServiceException ;
import cn.iocoder.yudao.framework.common.pojo.PageResult ;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils ;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils ;
import cn.iocoder.yudao.framework.pay.core.client.PayClient ;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackRespDto ;
import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideBackUnifiedDto ;
@ -13,21 +15,21 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.divide.PayDivideUnifiedDto
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO ;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO ;
import cn.iocoder.yudao.framework.pay.core.enums.divide.PayDivideRefundStatusRespEnum ;
import cn.iocoder.yudao.framework.pay.core.enums.divide.PayDivideStatusRespEnum ;
import cn.iocoder.yudao.module.pay.controller.admin.wxprofitsharing.vo.WxProfitsharingPageReqVO ;
import cn.iocoder.yudao.module.pay.controller.admin.wxprofitsharing.vo.WxProfitsharingSaveReqVO ;
import cn.iocoder.yudao.module.pay.controller.app.divide.vo.DrawMoneyVO ;
import cn.iocoder.yudao.module.pay.controller.app.divide.vo.RefundMoneyVO ;
import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO ;
import cn.iocoder.yudao.module.pay.dal.dataobject.divide.DivideDO ;
import cn.iocoder.yudao.module.pay.dal.dataobject.dividecompany.DivideCompanyDO ;
import cn.iocoder.yudao.module.pay.dal.dataobject.divideinfo.DivideInfoDO ;
import cn.iocoder.yudao.module.pay.dal.dataobject.dividerecord.DivideRecordDO ;
import cn.iocoder.yudao.module.pay.dal.dataobject.refundlog.PayRefundLogDO ;
import cn.iocoder.yudao.module.pay.dal.dataobject.refundrecord.RefundRecordDO ;
import cn.iocoder.yudao.module.pay.dal.dataobject.wxorder.WxOrderDO ;
import cn.iocoder.yudao.module.pay.dal.dataobject.wxprofitsharing.WxProfitsharingDO ;
import cn.iocoder.yudao.module.pay.dal.dataobject.wxprofitsharinginfo.WxProfitsharingInfoDO ;
import cn.iocoder.yudao.module.pay.dal.dataobject.wxprofitsharingreturn.WxProfitsharingReturnDO ;
import cn.iocoder.yudao.module.pay.dal.dataobject.wxrefund.WxRefundDO ;
import cn.iocoder.yudao.module.pay.dal.mysql.refundlog.PayRefundLogMapper ;
import cn.iocoder.yudao.module.pay.dal.mysql.wxorder.WxOrderMapper ;
import cn.iocoder.yudao.module.pay.dal.mysql.wxprofitsharing.WxProfitsharingMapper ;
import cn.iocoder.yudao.module.pay.dal.mysql.wxprofitsharinginfo.WxProfitsharingInfoMapper ;
import cn.iocoder.yudao.module.pay.dal.mysql.wxprofitsharingreturn.WxProfitsharingReturnMapper ;
import cn.iocoder.yudao.module.pay.dal.mysql.wxrefund.WxRefundMapper ;
@ -42,27 +44,18 @@ import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingV3Resu
import lombok.extern.slf4j.Slf4j ;
import org.springframework.data.redis.core.StringRedisTemplate ;
import org.springframework.stereotype.Service ;
import org.springframework.validation.annotation.Validated ;
import javax.annotation.Resource ;
import org.springframework.validation.annotation.Validated ;
import org.springframework.transaction.annotation.Transactional ;
import java.math.BigDecimal ;
import java.math.RoundingMode ;
import java.time.LocalDateTime ;
import java.util.* ;
import java.util.ArrayList ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
import java.util.concurrent.TimeUnit ;
import java.util.stream.Collectors ;
import java.util.stream.Stream ;
import cn.iocoder.yudao.module.pay.controller.admin.wxprofitsharing.vo.* ;
import cn.iocoder.yudao.module.pay.dal.dataobject.wxprofitsharing.WxProfitsharingDO ;
import cn.iocoder.yudao.framework.common.pojo.PageResult ;
import cn.iocoder.yudao.framework.common.pojo.PageParam ;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils ;
import cn.iocoder.yudao.module.pay.dal.mysql.wxprofitsharing.WxProfitsharingMapper ;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception ;
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.* ;
@ -852,4 +845,103 @@ public class WxProfitsharingServiceImpl implements WxProfitsharingService {
}
}
@Override
public Boolean refundMoney ( RefundMoneyVO refundMoney ) {
//判断用户是否正在退款
List < WxRefundDO > refundDOList1 = wxRefundMapper . selectList ( Wrappers . < WxRefundDO > lambdaQuery ( )
. eq ( WxRefundDO : : getStatus , PayDivideRefundStatusRespEnum . PROCESSING . getStatus ( ) )
. eq ( WxRefundDO : : getUserId , refundMoney . getUserId ( ) ) ) ;
if ( CollectionUtil . isNotEmpty ( refundDOList1 ) ) {
throw new ServiceException ( REFUND_NOT_COMPLETE ) ;
}
//判断是否有金额可退款
int money = refundMoney . getTotalPrice ( ) ;
//交易时间超过一年的订单无法提交退款(按支付成功时间+365天计算)
LocalDateTime now = LocalDateTime . now ( ) ; // 获取当前时间
LocalDateTime threeYearsAgo = now . minusDays ( 364 ) ;
//查询最近的充值订单,时间倒序退款
List < WxOrderDO > wxOrderDOList = wxOrderMapper . selectList ( Wrappers . < WxOrderDO > lambdaQuery ( )
. eq ( WxOrderDO : : getOpenId , refundMoney . getChannelUserId ( ) )
. eq ( WxOrderDO : : getTransactionId , refundMoney . getTransactionId ( ) )
. gt ( WxOrderDO : : getRefundPrice , 0 )
. ge ( WxOrderDO : : getCreateTime , threeYearsAgo )
. orderByDesc ( WxOrderDO : : getCreateTime ) ) ;
if ( wxOrderDOList . isEmpty ( ) ) {
throw new ServiceException ( new ErrorCode ( 1_007_902_002 , " 未查询到付款订单 " ) ) ;
}
Map < Long , WxOrderDO > orderMap = wxOrderDOList . stream ( ) . collect ( Collectors . toMap ( WxOrderDO : : getId , vo - > vo ) ) ;
//筛选出未分账的订单
List < WxOrderDO > unDivideList = wxOrderDOList . stream ( ) . filter ( vo - > vo . getRefundPrice ( ) . equals ( vo . getProfitsharingPrice ( ) ) ) . collect ( Collectors . toList ( ) ) ;
//筛选出已分账的订单
List < WxOrderDO > divideList = wxOrderDOList . stream ( ) . filter ( vo - > ! vo . getRefundPrice ( ) . equals ( vo . getProfitsharingPrice ( ) ) ) . collect ( Collectors . toList ( ) ) ;
//筛选出分账完的订单
List < WxOrderDO > divideCpList = divideList . stream ( ) . filter ( vo - > vo . getProfitsharingPrice ( ) = = 0 ) . collect ( Collectors . toList ( ) ) ;
//剩下的是未分账完的订单
List < WxOrderDO > divideUnCpList = divideList . stream ( ) . filter ( vo - > vo . getProfitsharingPrice ( ) ! = 0 ) . collect ( Collectors . toList ( ) ) ;
//生成退款订单
List < WxRefundDO > refundDOList = createRefund ( unDivideList , divideCpList , divideUnCpList , money , refundMoney . getUserId ( ) ) ;
int failNum = 0 ;
//调用微信退款接口
if ( CollectionUtil . isNotEmpty ( refundDOList ) ) {
for ( WxRefundDO wxRefundDO : refundDOList ) {
WxOrderDO wxOrderDO = orderMap . get ( wxRefundDO . getPayWxOrderId ( ) ) ;
PayChannelDO channel = channelService . validPayChannel ( wxOrderDO . getChannelId ( ) ) ;
PayClient client = channelService . getPayClient ( wxOrderDO . getChannelId ( ) ) ;
PayRefundUnifiedReqDTO payRefundUnifiedReqDTO = new PayRefundUnifiedReqDTO ( ) ;
payRefundUnifiedReqDTO . setTransactionId ( wxOrderDO . getTransactionId ( ) )
. setReason ( " 预定退款 " )
. setRefundPrice ( wxRefundDO . getTotalPrice ( ) )
. setOutRefundNo ( wxRefundDO . getOutRefundNo ( ) )
. setPayPrice ( wxOrderDO . getTotalPrice ( ) )
. setNotifyUrl ( genChannelRefundNotifyUrl ( channel ) ) ;
PayRefundRespDTO payRefundRespDTO = client . unifiedRefund ( payRefundUnifiedReqDTO ) ;
String channelRefundNo = payRefundRespDTO . getChannelRefundNo ( ) ;
wxRefundDO . setRefundId ( channelRefundNo ) ;
if ( cn . iocoder . yudao . framework . pay . core . enums . refund . PayRefundStatusRespEnum . WAITING . getStatus ( ) . equals ( payRefundRespDTO . getStatus ( ) ) ) {
wxRefundDO . setStatus ( PayDivideRefundStatusRespEnum . PROCESSING . getStatus ( ) ) ;
} else if ( cn . iocoder . yudao . framework . pay . core . enums . refund . PayRefundStatusRespEnum . SUCCESS . getStatus ( ) . equals ( payRefundRespDTO . getStatus ( ) ) ) {
wxRefundDO . setStatus ( PayDivideRefundStatusRespEnum . SUCCESS . getStatus ( ) ) ;
} else {
failNum + + ;
wxRefundDO . setStatus ( PayDivideRefundStatusRespEnum . ABNORMAL . getStatus ( ) ) ;
}
wxRefundMapper . insert ( wxRefundDO ) ;
}
}
return failNum < = 0 ;
}
public WxRefundDO createRefundOne ( WxOrderDO wxOrderDO , int money , Long userId ) {
//退款订单
List < WxRefundDO > backList = new ArrayList < > ( ) ;
WxRefundDO wxRefundDO = new WxRefundDO ( ) ;
wxRefundDO . setPayWxOrderId ( wxOrderDO . getId ( ) ) ;
wxRefundDO . setUserId ( userId ) ;
wxRefundDO . setOutRefundNo ( noRedisDAO . generate ( payProperties . getRefundNoPrefix ( ) ) ) ;
wxRefundDO . setTotalPrice ( money ) ;
return wxRefundDO ;
}
}