充值超时重新查询充值结果--/recharge/overtime/query-result

This commit is contained in:
tqzhang 2025-02-11 20:40:25 +08:00
parent 9803cafd9b
commit 924c1b1c0b
33 changed files with 1233 additions and 11 deletions

View File

@ -4,6 +4,7 @@ package com.bonus.core.account.v3.app.controller;
import com.bonus.common.core.web.controller.BaseController;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.core.account.v3.app.dto.AccRechargeForAppDTO;
import com.bonus.core.account.v3.app.dto.AppRechargeResultDTO;
import com.bonus.core.account.v3.app.dto.AppTradeDetailListDTO;
import com.bonus.core.account.v3.app.service.AppAccService;
import com.bonus.core.account.v3.app.vo.AppAccTradePageVO;
@ -54,9 +55,9 @@ public class AppAccController extends BaseController {
return AjaxResult.success(mobilePayVO);
}
// @ApiOperation("充值超时重新查询充值结果")
// @PostMapping({"/recharge/overtime/query-result"})
// public AjaxResult queryAppRechargePayOvertimeResult(@RequestBody @Valid AppRechargeResultDTO dto) {
// return AjaxResult.success(this.appAccService.queryAppRechargePayOvertimeResult(dto));
// }
@ApiOperation("充值超时重新查询充值结果")
@PostMapping({"/recharge/overtime/query-result"})
public AjaxResult queryAppRechargePayOvertimeResult(@RequestBody @Valid AppRechargeResultDTO dto) {
return AjaxResult.success(this.appAccService.queryAppRechargePayOvertimeResult(dto));
}
}

View File

@ -15,5 +15,5 @@ public interface AppAccService {
MobilePayVO accRechargeForApp(AccRechargeForAppDTO dto);
// AppAccTradePageVO queryAppRechargePayOvertimeResult(AppRechargeResultDTO content);
AppAccTradePageVO queryAppRechargePayOvertimeResult(AppRechargeResultDTO content);
}

View File

@ -7,6 +7,7 @@ import cn.hutool.json.JSONUtil;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.constant.LeConstants;
import com.bonus.core.account.v3.app.dto.AccRechargeForAppDTO;
import com.bonus.core.account.v3.app.dto.AppRechargeResultDTO;
import com.bonus.core.account.v3.app.dto.AppTradeDetailListDTO;
import com.bonus.core.account.v3.app.service.AppAccService;
import com.bonus.core.account.v3.app.vo.AppAccTradePageVO;
@ -16,6 +17,8 @@ import com.bonus.core.account.v3.model.AccTrade;
import com.bonus.core.account.v3.po.AccTradeAddPO;
import com.bonus.core.account.v3.service.AccInfoService;
import com.bonus.core.account.v3.service.AccTradeService;
import com.bonus.core.account.v3.service.AccWalletService;
import com.bonus.core.account.v3.web.dto.AccRechargeBackDTO;
import com.bonus.core.account.v3.web.vo.AccInfoVO;
import com.bonus.core.allocation.api.AllocMetadataApi;
import com.bonus.core.common.enums.MetadataModelTypeEnum;
@ -27,6 +30,8 @@ import com.bonus.core.marketing.v2.api.MarketApi;
import com.bonus.core.marketing.v2.rule.recharge.dto.RuleRechargeComputeDTO;
import com.bonus.core.pay.api.PayApi;
import com.bonus.core.pay.api.dto.UnifyPayDTO;
import com.bonus.core.pay.api.dto.UnifyPaySelectDTO;
import com.bonus.core.pay.api.vo.UnifyPaySelectVO;
import com.bonus.core.pay.common.constants.PayChannelSelectEnum;
import com.bonus.core.pay.common.constants.PayStateEnum;
import com.bonus.core.pay.common.constants.TradeTypeEnum;
@ -55,6 +60,9 @@ public class AppAccServiceImpl implements AppAccService {
private AccTradeService accTradeService;
@Resource
@Lazy
private AccWalletService accWalletService;
@Resource
@Lazy
private CustInfoApi custInfoApi;
@Resource
@Lazy
@ -165,4 +173,14 @@ public class AppAccServiceImpl implements AppAccService {
return mobilePayDTO;
}
@Override
public AppAccTradePageVO queryAppRechargePayOvertimeResult(AppRechargeResultDTO content) {
UnifyPaySelectDTO paySelectDTO = new UnifyPaySelectDTO();
paySelectDTO.setOrderRechargeId(content.getAccTradeId());
log.info("移动端查询充值结果,调用支付查询入参_{}", JSONUtil.toJsonStr(paySelectDTO));
UnifyPaySelectVO paySelectVO = this.payApi.paySelect(paySelectDTO);
log.info("移动端查询充值结果,调用支付查询结果_{}", JSONUtil.toJsonStr(paySelectVO));
this.accWalletService.accRechargeResultHandlerV2(AccRechargeBackDTO.convert(content.getAccTradeId(), paySelectVO));
return this.accTradeService.getOneTradeApp(content.getAccTradeId());
}
}

View File

@ -22,4 +22,6 @@ public interface AccTradeMapper extends BaseMapper<AccTrade> {
AccRechargeSumApiVO getAccRechargeSum(@Param("param") AccRechargeSumApiDTO accRechargeSumApiDTO);
AppAccTradePageVO getOneTradeApp(@Param("tradeId") Long tradeId);
}

View File

@ -0,0 +1,53 @@
package com.bonus.core.account.v3.mq.listener.po;
import java.io.Serializable;
public class AccRechargeBackPO implements Serializable {
private static final long serialVersionUID = 1L;
private Long merchantId;
private Long accTradeId;
private Long ordId;
private Integer payState;
private String tradeResult;
public Long getMerchantId() {
return this.merchantId;
}
public Long getAccTradeId() {
return this.accTradeId;
}
public Long getOrdId() {
return this.ordId;
}
public Integer getPayState() {
return this.payState;
}
public String getTradeResult() {
return this.tradeResult;
}
public void setMerchantId(final Long merchantId) {
this.merchantId = merchantId;
}
public void setAccTradeId(final Long accTradeId) {
this.accTradeId = accTradeId;
}
public void setOrdId(final Long ordId) {
this.ordId = ordId;
}
public void setPayState(final Integer payState) {
this.payState = payState;
}
public void setTradeResult(final String tradeResult) {
this.tradeResult = tradeResult;
}
}

View File

@ -2,6 +2,7 @@ package com.bonus.core.account.v3.service;
import com.bonus.core.account.v3.po.AccConsumeUpdateWalletPO;
import com.bonus.core.account.v3.web.dto.AccRechargeBackDTO;
import com.bonus.core.account.v3.web.vo.AccConsumeWalletVO;
@ -9,4 +10,5 @@ public interface AccBusinessService {
AccConsumeWalletVO doConsumeUpdateWalletAndAddTradeV2(AccConsumeUpdateWalletPO updateWalletPO);
void accRechargeModifyAndUpdate(AccRechargeBackDTO accRechargeBackDTO);
}

View File

@ -31,4 +31,6 @@ public interface AccTradeService extends IService<AccTrade> {
void insertAccTradeForTradeId(AccTradeAddPO addPo);
AccRechargeSumApiVO getAccRechargeSum(AccRechargeSumApiDTO accRechargeSumApiDTO);
AppAccTradePageVO getOneTradeApp(Long accTradeId);
}

View File

@ -0,0 +1,8 @@
package com.bonus.core.account.v3.service;
import com.bonus.core.account.v3.web.dto.AccRechargeBackDTO;
public interface AccWalletService {
void accRechargeResultHandlerV2(AccRechargeBackDTO accRechargeBackDTO);
}

View File

@ -6,26 +6,42 @@ import cn.hutool.json.JSONUtil;
import com.bonus.core.account.v3.constants.AccTradeStateEnum;
import com.bonus.core.account.v3.constants.AccUpdateWalletOperateEnum;
import com.bonus.core.account.v3.metadata.enums.AccWalletIdEnum;
import com.bonus.core.account.v3.model.AccTrade;
import com.bonus.core.account.v3.mq.send.dto.RepAccMqDTO;
import com.bonus.core.account.v3.po.*;
import com.bonus.core.account.v3.service.AccBusinessService;
import com.bonus.core.account.v3.service.AccTradeService;
import com.bonus.core.account.v3.service.AccTradeWalletDetailService;
import com.bonus.core.account.v3.service.AccWalletInfoService;
import com.bonus.core.account.v3.utils.AccUtils;
import com.bonus.core.account.v3.web.dto.AccRechargeBackDTO;
import com.bonus.core.account.v3.web.vo.AccConsumeWalletVO;
import com.bonus.core.account.v3.web.vo.AccUpdateWalletBalanceVO;
import com.bonus.core.common.utils.TenantContextHolder;
import com.bonus.core.marketing.v2.api.MarketApi;
import com.bonus.core.marketing.v2.rule.recharge.dto.RuleRechargeComputeDTO;
import com.bonus.core.marketing.v2.rule.recharge.dto.RuleRechargeResultDTO;
import com.bonus.core.marketing.v2.rule.recharge.dto.RuleRechargeWalletDTO;
import com.bonus.core.pay.common.constants.PayChannelEnum;
import com.bonus.core.pay.common.constants.PayStateEnum;
import com.bonus.core.pay.common.constants.PayTypeEnum;
import com.bonus.utils.id.Id;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class AccBusinessServiceImpl implements AccBusinessService {
@ -39,6 +55,10 @@ public class AccBusinessServiceImpl implements AccBusinessService {
@Resource
@Lazy
private AccTradeWalletDetailService accTradeWalletDetailService;
@Resource
@Lazy
private MarketApi marketApi;
@Override
public AccConsumeWalletVO doConsumeUpdateWalletAndAddTradeV2(AccConsumeUpdateWalletPO updateWalletPo) {
@ -82,4 +102,88 @@ public class AccBusinessServiceImpl implements AccBusinessService {
log.info("[账户消费]0元消费,新增记录结束");
return (new AccConsumeWalletVO()).setAccTradeId(tradeId).setAccAllBal(accWalletBalance.getAccAllBal()).setAccBalTotal(accWalletBalance.getAccBalTotal()).setWalletInfoList(accWalletBalance.getWalletInfoList());
}
@Override
@Transactional(
rollbackFor = {Exception.class},
propagation = Propagation.REQUIRES_NEW
)
public void accRechargeModifyAndUpdate(AccRechargeBackDTO accRechargeBackDTO) {
log.info("[账户]支付结果->开始处理入参:{}", JSONUtil.toJsonStr(accRechargeBackDTO));
AccTrade accTrade = (AccTrade)this.accTradeService.getById(accRechargeBackDTO.getAccTradeId());
if (ObjectUtil.isNull(accTrade)) {
log.error("[账户]支付结果->交易记录不存在");
} else if (PayStateEnum.isPaidState(accTrade.getPayState())) {
log.error("[账户]支付结果->记录已经被处理:{}", JSONUtil.toJsonStr(accTrade));
} else {
AccTrade updateTrade = new AccTrade();
updateTrade.setId(accTrade.getId());
updateTrade.setPayState(accRechargeBackDTO.getPayState());
if (PayStateEnum.isPaidState(accRechargeBackDTO.getPayState())) {
RuleRechargeComputeDTO ruleRechargeComputeDTO = this.packageRuleRechargeComputeDTO(accTrade);
log.info("[账户]支付结果->支付成功,调用充值计算规则入参:{}", JSONUtil.toJsonStr(ruleRechargeComputeDTO));
RuleRechargeResultDTO ruleRechargeResultDTO = this.marketApi.ruleRechargeCompute(ruleRechargeComputeDTO);
log.info("[账户]支付结果->支付成功,调用充值计算规则结果={}", JSONUtil.toJsonStr(ruleRechargeResultDTO));
LocalDateTime now = LocalDateTime.now();
this.addAccTradeWalletDeatil(accTrade.getId(), accTrade.getCustId(), ruleRechargeResultDTO.getWalletDetails(), now);
AccUpdateWalletBalanceVO accWalletBalance = this.accWalletInfoService.getAccWalletBalanceByCustId(accTrade.getCustId());
updateTrade.setTradeTime(now);
updateTrade.setTradeState(AccTradeStateEnum.TAKE_EFFECT.getKey());
updateTrade.setActualAmount(ruleRechargeResultDTO.getActualAmount());
updateTrade.setManageCost(ruleRechargeResultDTO.getManageCost());
updateTrade.setWalletBalTotal(accWalletBalance.getAccBalTotal());
updateTrade.setAccAllBal(accWalletBalance.getAccAllBal());
updateTrade.setLeOrdNo(accRechargeBackDTO.getPayTradeId());
updateTrade.setThirdTradeNo(accRechargeBackDTO.getThirdTradeNo());
updateTrade.setRemark(accRechargeBackDTO.getTradeResult());
log.info("[账户]支付结果->支付成功,更新充值记录对象开始,{}", JSONUtil.toJsonStr(updateTrade));
this.accTradeService.updateTradeById(updateTrade);
log.info("[账户]支付结果->支付成功,更新充值记录结束");
this.sendAccSendMq(Collections.singletonList(accTrade.getId()));
} else {
Integer tradeSate = AccTradeStateEnum.CREATE.getKey();
if (PayStateEnum.isFailedState(accRechargeBackDTO.getPayState())) {
updateTrade.setFailReason(accRechargeBackDTO.getTradeResult());
tradeSate = AccTradeStateEnum.CLOSE.getKey();
}
updateTrade.setTradeState(tradeSate);
log.info("[账户]支付结果->未成功,更新充值记录对象开始,{}", JSONUtil.toJsonStr(updateTrade));
this.accTradeService.updateTradeById(updateTrade);
}
}
}
protected RuleRechargeComputeDTO packageRuleRechargeComputeDTO(AccTrade accTrade) {
return (new RuleRechargeComputeDTO()).setCustId(accTrade.getCustId()).setAmount(accTrade.getAmount()).setPayChannel(accTrade.getPayChannel()).setPayType(accTrade.getPayType()).setTradeId(accTrade.getId()).setTradeDate(LocalDate.now());
}
protected void addAccTradeWalletDeatil(Long tradeId, Long custId, List<RuleRechargeWalletDTO> walletDetails, LocalDateTime tradeTime) {
log.info("[账户]支付结果->新增账户交易详情开始,{}", JSONUtil.toJsonStr(walletDetails));
Iterator var5 = walletDetails.iterator();
while(var5.hasNext()) {
RuleRechargeWalletDTO walletDetail = (RuleRechargeWalletDTO)var5.next();
AccWalletBalanceUpdatePO rechargePo = (new AccWalletBalanceUpdatePO()).setOperationType(AccUpdateWalletOperateEnum.AUGMENT_BAL).setCustId(custId).setWalletId(walletDetail.getWalletId()).setAmount(walletDetail.getAmount());
AccUpdateWalletBalanceVO accUpdateWalletBalanceVO = this.updateAccWalletBalance(rechargePo);
AccTradeWalletPO accTradeWalletPo = AccTradeWalletPO.builder().tradeId(tradeId).custId(custId).walletId(walletDetail.getWalletId()).tradeType(walletDetail.getTradeType()).amount(walletDetail.getAmount()).walletBal(AccUtils.getWalletBal(accUpdateWalletBalanceVO.getWalletInfoList(), walletDetail.getWalletId())).frozenBalance(AccUtils.getWalletFrozenBal(accUpdateWalletBalanceVO.getWalletInfoList(), walletDetail.getWalletId())).tradeTime(tradeTime).build();
this.accTradeWalletDetailService.insertAccTradeWalletDetail(accTradeWalletPo);
}
log.info("[账户]支付结果->新增账户交易详情结束");
}
public AccUpdateWalletBalanceVO updateAccWalletBalance(AccWalletBalanceUpdatePO updatePo) {
return this.accWalletInfoService.updateAccWalletBalance(updatePo);
}
public void sendAccSendMq(List<Long> tradeIdList) {
if (CollUtil.isNotEmpty(tradeIdList)) {
List<RepAccMqDTO> sendList = (List)tradeIdList.stream().map((item) -> {
return RepAccMqDTO.builder().tradeId(item).build();
}).collect(Collectors.toList());
// this.accSendMq.accTradeSendHandle(TenantContextHolder.getTenantId(), sendList);
}
}
}

View File

@ -149,4 +149,9 @@ public class AccTradeServiceImpl extends ServiceImpl<AccTradeMapper, AccTrade> i
public AccRechargeSumApiVO getAccRechargeSum(AccRechargeSumApiDTO accRechargeSumApiDTO) {
return ((AccTradeMapper)this.baseMapper).getAccRechargeSum(accRechargeSumApiDTO);
}
@Override
public AppAccTradePageVO getOneTradeApp(Long accTradeId) {
return ((AccTradeMapper)this.baseMapper).getOneTradeApp(accTradeId);
}
}

View File

@ -0,0 +1,99 @@
package com.bonus.core.account.v3.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bonus.constant.LeConstants;
import com.bonus.core.account.v3.constants.*;
import com.bonus.core.account.v3.custom.AccRechargeCustomBusiness;
import com.bonus.core.account.v3.dto.AccWalletUpdateDTO;
import com.bonus.core.account.v3.metadata.enums.AccWalletIdEnum;
import com.bonus.core.account.v3.model.AccTrade;
import com.bonus.core.account.v3.model.AccTradeWalletDetail;
import com.bonus.core.account.v3.mq.send.AccSendMq;
import com.bonus.core.account.v3.mq.send.dto.RepAccMqDTO;
import com.bonus.core.account.v3.po.AccTradeAddPO;
import com.bonus.core.account.v3.po.AccTradeWalletPO;
import com.bonus.core.account.v3.po.AccWalletBalanceUpdatePO;
import com.bonus.core.account.v3.service.*;
import com.bonus.core.account.v3.utils.AccUtils;
import com.bonus.core.account.v3.web.dto.AccRechargeBackDTO;
import com.bonus.core.account.v3.web.vo.AccInfoVO;
import com.bonus.core.account.v3.web.vo.AccUpdateWalletBalanceVO;
import com.bonus.core.account.v3.web.vo.AccWalletInfoVO;
import com.bonus.core.common.page.PageVO;
import com.bonus.core.common.redis.RedisUtil;
import com.bonus.core.common.utils.JacksonUtil;
import com.bonus.core.common.utils.LogUtil;
import com.bonus.core.common.utils.TenantContextHolder;
import com.bonus.core.customer.api.CustInfoApi;
import com.bonus.core.marketing.v2.api.MarketApi;
import com.bonus.core.marketing.v2.rule.recharge.dto.RuleRechargeComputeDTO;
import com.bonus.core.marketing.v2.rule.recharge.dto.RuleRechargeResultDTO;
import com.bonus.core.marketing.v2.rule.recharge.dto.RuleRechargeWalletDTO;
import com.bonus.core.pay.api.PayApi;
import com.bonus.core.pay.api.TradeRecordApi;
import com.bonus.core.pay.api.dto.UnifyPaySelectDTO;
import com.bonus.core.pay.api.dto.UnifyRefundDTO;
import com.bonus.core.pay.api.vo.UnifyPaySelectVO;
import com.bonus.core.pay.common.constants.PayChannelEnum;
import com.bonus.core.pay.common.constants.PayStateEnum;
import com.bonus.core.pay.common.constants.PayTypeEnum;
import com.bonus.core.pay.common.constants.TradeTypeEnum;
import com.bonus.core.pay.common.model.TradeOrderRecharge;
import com.bonus.i18n.I18n;
import com.bonus.utils.LeBeanUtil;
import com.bonus.utils.id.Id;
import com.github.pagehelper.page.PageMethod;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.lang.invoke.SerializedLambda;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@Service
public class AccWalletServiceImpl implements AccWalletService {
private static final Logger log = LoggerFactory.getLogger(AccWalletServiceImpl.class);
@Autowired
@Lazy
private AccBusinessService accBusinessService;
@Override
public void accRechargeResultHandlerV2(AccRechargeBackDTO accRechargeBackDTO) {
log.info("账户收到支付结果>入参:{}", JSONUtil.toJsonStr(accRechargeBackDTO));
if (!AccUtils.getAccTradeLockByTradeId(accRechargeBackDTO.getAccTradeId())) {
log.info("账户收到支付结果,已经有任务在执行{}", JSONUtil.toJsonStr(accRechargeBackDTO));
} else {
try {
this.accBusinessService.accRechargeModifyAndUpdate(accRechargeBackDTO);
} catch (Exception var6) {
log.error("[账户收到支付结果]系统错误", var6);
} finally {
AccUtils.accTradeUnLockByTradeId(accRechargeBackDTO.getAccTradeId());
}
}
}
}

View File

@ -104,6 +104,19 @@ public class AccUtils {
}
}
public static boolean getAccTradeLockByTradeId(Long tradeId) {
Long tenantId = TenantContextHolder.getTenantId();
if (ObjectUtil.isNull(tenantId)) {
return false;
} else {
String lockKey =
"yst:merchant-id:user-id:acc:upgrade:lock".replace("merchant-id", tenantId.toString()).replace("user-id", tradeId.toString());
return RedisUtil.tryLock(lockKey, 0, 600);
}
// String lockKey = "yst:merchant-id:user-id:acc:upgrade:lock".replace("merchant-id", TenantContextHolder.getTenantId().toString()).replace("user-id", tradeId.toString());
// return RedisUtil.tryLock(lockKey, 0, 600);
}
public static void unlockAccWalletBalanceUpdate(Long custId) {
String lockKey = "yst:merchant-id:user-id:acc:wallet:upgrade:lock".replace("merchant-id", TenantContextHolder.getTenantId().toString()).replace("user-id", String.valueOf(custId));
accSafeUnLock(lockKey);
@ -244,4 +257,9 @@ public class AccUtils {
return accOrdBasicsVO;
}
public static void accTradeUnLockByTradeId(Long tradeId) {
String lockKey = "yst:merchant-id:user-id:acc:upgrade:lock".replace("merchant-id", TenantContextHolder.getTenantId().toString()).replace("user-id", tradeId.toString());
accSafeUnLock(lockKey);
}
}

View File

@ -0,0 +1,73 @@
package com.bonus.core.account.v3.web.dto;
import com.bonus.core.account.v3.mq.listener.po.AccRechargeBackPO;
import com.bonus.core.pay.api.vo.UnifyPaySelectVO;
import com.bonus.core.pay.common.vo.AndroidPayVO;
public class AccRechargeBackDTO {
private Long accTradeId;
private Long payTradeId;
private Integer payState;
private String tradeResult;
private String thirdTradeNo;
public static AccRechargeBackDTO convert(AccRechargeBackPO accRechargeBack) {
return (new AccRechargeBackDTO()).setAccTradeId(accRechargeBack.getAccTradeId()).setPayTradeId(accRechargeBack.getOrdId()).setPayState(accRechargeBack.getPayState()).setTradeResult(accRechargeBack.getTradeResult());
}
public static AccRechargeBackDTO convert(Long accTradeId, AndroidPayVO androidPayVO) {
return (new AccRechargeBackDTO()).setAccTradeId(accTradeId).setPayTradeId(androidPayVO.getTradeId()).setPayState(androidPayVO.getCode()).setTradeResult(androidPayVO.getMsg()).setThirdTradeNo(androidPayVO.getOutTradeNo());
}
public static AccRechargeBackDTO convert(Long accTradeId, UnifyPaySelectVO paySelectVO) {
return (new AccRechargeBackDTO()).setAccTradeId(accTradeId).setPayTradeId(paySelectVO.getTradeId())
.setPayState(paySelectVO.getCode()).setTradeResult(paySelectVO.getMsg()).setThirdTradeNo(paySelectVO.getOutTradeNo());
}
public Long getAccTradeId() {
return this.accTradeId;
}
public Long getPayTradeId() {
return this.payTradeId;
}
public Integer getPayState() {
return this.payState;
}
public String getTradeResult() {
return this.tradeResult;
}
public String getThirdTradeNo() {
return this.thirdTradeNo;
}
public AccRechargeBackDTO setAccTradeId(final Long accTradeId) {
this.accTradeId = accTradeId;
return this;
}
public AccRechargeBackDTO setPayTradeId(final Long payTradeId) {
this.payTradeId = payTradeId;
return this;
}
public AccRechargeBackDTO setPayState(final Integer payState) {
this.payState = payState;
return this;
}
public AccRechargeBackDTO setTradeResult(final String tradeResult) {
this.tradeResult = tradeResult;
return this;
}
public AccRechargeBackDTO setThirdTradeNo(final String thirdTradeNo) {
this.thirdTradeNo = thirdTradeNo;
return this;
}
}

View File

@ -120,11 +120,6 @@ public class GlobalMetadataApi {
return MetadataUtil.transferToPayModel(metadataList, t);
}
public <T> T getAvailableModel(MetadataModelTypeEnum modelTypeEnum, T t, Long canteenId, Long stallId) {
List<AllocMetadata> metadataList = this.getAvailableList(modelTypeEnum, canteenId, stallId);
return MetadataUtil.transferToPayModel(metadataList, t);
}
public void saveValue(MetadataModelTypeEnum modelTypeEnum, String modelKey, String modelValue, Long canteenId, Long stallId) {
AllocMetadata allocMetadata = new AllocMetadata();
allocMetadata.setModelType(modelTypeEnum.getKey());

View File

@ -1,6 +1,8 @@
package com.bonus.core.allocation.holiday.service;
import com.bonus.core.allocation.holiday.model.MktHoliday;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
@ -11,4 +13,6 @@ public interface MktHolidayService {
List<Date> getHolidayList(Integer year);
Integer getHolidayType(LocalDate searchDate);
List<MktHoliday> listHolidayByDate(LocalDate searchDate);
}

View File

@ -76,4 +76,10 @@ public class MktHolidayServiceImpl extends ServiceImpl<MktHolidayMapper, MktHoli
String key = "yst:" + var10000 + ":mkt:holiday:" + year;
RedisUtil.setString(key, JSON.toJSONString(dateList), (Long)null);
}
@Override
public List<MktHoliday> listHolidayByDate(LocalDate searchDate) {
return this.list(Wrappers.<MktHoliday>lambdaQuery().eq(MktHoliday::getIfDel,
LeConstants.COMMON_NO).eq(MktHoliday::getHolDate, searchDate.atStartOfDay()));
}
}

View File

@ -1,5 +1,7 @@
package com.bonus.core.pay.api;
import com.bonus.core.pay.api.dto.UnifyPayDTO;
import com.bonus.core.pay.api.dto.UnifyPaySelectDTO;
import com.bonus.core.pay.api.vo.UnifyPaySelectVO;
import com.bonus.core.pay.api.vo.UnifyPayVO;
import com.bonus.core.pay.common.business.ChannelBusiness;
import com.bonus.core.pay.common.business.PayBusiness;
@ -31,4 +33,8 @@ public class PayApi {
public UnifyPayVO pay(UnifyPayDTO payDTO) {
return this.payBusiness.unifyPay(payDTO);
}
public UnifyPaySelectVO paySelect(UnifyPaySelectDTO paySelectDTO) {
return this.payBusiness.unifyPaySelect(paySelectDTO);
}
}

View File

@ -0,0 +1,118 @@
package com.bonus.core.pay.api.vo;
import cn.hutool.core.bean.BeanUtil;
import com.bonus.core.pay.common.constants.PayStateEnum;
import com.bonus.core.pay.common.model.TradeRecord;
import java.math.BigDecimal;
public class UnifyPaySelectVO {
private Integer code;
private String msg;
private Long tradeId;
private String outTradeNo;
private BigDecimal amount;
private BigDecimal realAmount;
private Integer payType;
private Integer payChannel;
private Long custId;
public static UnifyPaySelectVO of(TradeRecord tradeRecord) {
UnifyPaySelectVO androidPayVO = (UnifyPaySelectVO)BeanUtil.copyProperties(tradeRecord, UnifyPaySelectVO.class, new String[0]);
androidPayVO.setTradeId(tradeRecord.getId());
androidPayVO.setCode(tradeRecord.getTradeState());
androidPayVO.setMsg(tradeRecord.getTradeResult());
androidPayVO.setTradeId(tradeRecord.getId());
androidPayVO.setRealAmount(PayStateEnum.isPaidState(tradeRecord.getTradeState()) ? tradeRecord.getAmount() : BigDecimal.ZERO);
return androidPayVO;
}
public static UnifyPaySelectVO of(UnifyPayVO unifyPayVO) {
return (UnifyPaySelectVO)BeanUtil.copyProperties(unifyPayVO, UnifyPaySelectVO.class, new String[0]);
}
public static UnifyPaySelectVO of(Integer code, String msg) {
return (new UnifyPaySelectVO()).setCode(code).setMsg(msg);
}
public Integer getCode() {
return this.code;
}
public String getMsg() {
return this.msg;
}
public Long getTradeId() {
return this.tradeId;
}
public String getOutTradeNo() {
return this.outTradeNo;
}
public BigDecimal getAmount() {
return this.amount;
}
public BigDecimal getRealAmount() {
return this.realAmount;
}
public Integer getPayType() {
return this.payType;
}
public Integer getPayChannel() {
return this.payChannel;
}
public Long getCustId() {
return this.custId;
}
public UnifyPaySelectVO setCode(final Integer code) {
this.code = code;
return this;
}
public UnifyPaySelectVO setMsg(final String msg) {
this.msg = msg;
return this;
}
public UnifyPaySelectVO setTradeId(final Long tradeId) {
this.tradeId = tradeId;
return this;
}
public UnifyPaySelectVO setOutTradeNo(final String outTradeNo) {
this.outTradeNo = outTradeNo;
return this;
}
public UnifyPaySelectVO setAmount(final BigDecimal amount) {
this.amount = amount;
return this;
}
public UnifyPaySelectVO setRealAmount(final BigDecimal realAmount) {
this.realAmount = realAmount;
return this;
}
public UnifyPaySelectVO setPayType(final Integer payType) {
this.payType = payType;
return this;
}
public UnifyPaySelectVO setPayChannel(final Integer payChannel) {
this.payChannel = payChannel;
return this;
}
public UnifyPaySelectVO setCustId(final Long custId) {
this.custId = custId;
return this;
}
}

View File

@ -2,27 +2,33 @@ package com.bonus.core.pay.common.business;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.bonus.constant.LeConstants;
import com.bonus.core.account.v3.api.AccBusinessApi;
import com.bonus.core.account.v3.constants.AccExceptionRecordStatusEnum;
import com.bonus.core.account.v3.web.dto.AccAddExceptionRecordDTO;
import com.bonus.core.account.v3.web.dto.AccUpdateExceptionRecordDTO;
import com.bonus.core.common.utils.JacksonUtil;
import com.bonus.core.common.utils.LogUtil;
import com.bonus.core.customer.api.CustInfoApi;
import com.bonus.core.order.mq.constants.OrderMQConstants;
import com.bonus.core.order.utils.LeNumUtil;
import com.bonus.core.pay.api.dto.UnifyPayDTO;
import com.bonus.core.pay.api.dto.UnifyPaySelectDTO;
import com.bonus.core.pay.api.vo.UnifyPaySelectVO;
import com.bonus.core.pay.api.vo.UnifyPayVO;
import com.bonus.core.pay.common.constants.PayCacheConstants;
import com.bonus.core.pay.common.constants.PayStateEnum;
import com.bonus.core.pay.common.dto.ChannelPayDTO;
import com.bonus.core.pay.common.dto.MixPayResultDTO;
import com.bonus.core.pay.common.dto.PayChannelSplitDTO;
import com.bonus.core.pay.common.dto.PaySelectDTO;
import com.bonus.core.pay.common.model.TradeChannel;
import com.bonus.core.pay.common.model.TradeRecord;
import com.bonus.core.pay.common.service.*;
import com.bonus.core.pay.common.vo.*;
import com.bonus.core.pay.custom.PayCustomBusiness;
import com.bonus.i18n.I18n;
import com.bonus.utils.id.Id;
import com.fasterxml.jackson.databind.JsonNode;
import org.slf4j.Logger;
@ -62,6 +68,11 @@ public class PayBusiness {
@Lazy
@Resource
protected TradeChannelService tradeChannelService;
@Resource
@Lazy
protected CustInfoApi custInfoApi;
@Transactional(
propagation = Propagation.NOT_SUPPORTED
)
@ -493,4 +504,140 @@ public class PayBusiness {
}
}
}
@Transactional(
propagation = Propagation.NOT_SUPPORTED
)
public UnifyPaySelectVO unifyPaySelect(UnifyPaySelectDTO unifyPaySelectDTO) {
LogUtil.info("[支付查询]入参", unifyPaySelectDTO);
this.payCustomBusiness.willPaySelectV2(unifyPaySelectDTO);
TradeRecord tradeRecord = unifyPaySelectDTO.getTradeId() != null ? this.tradeRecordService
.getTradeRecordById(unifyPaySelectDTO.getTradeId()) : this.tradeRecordService.getTradeRecordByOrderRechargeId(unifyPaySelectDTO.getOrderRechargeId());
if (ObjectUtil.isNull(tradeRecord)) {
log.info("[查询支付结果]交易记录不存在orderRechargeId:{}", unifyPaySelectDTO.getOrderRechargeId());
return UnifyPaySelectVO.of(PayStateEnum.PAY_FAIL.getKey(), I18n.getMessage("pay.trade-not-exist", new Object[0]));
} else {
UnifyPaySelectVO unifyPaySelectVO;
if (!PayCacheConstants.lockTrade(tradeRecord.getId())) {
log.warn("[支付查询]交易锁定失败");
unifyPaySelectVO = UnifyPaySelectVO.of(PayStateEnum.PAY_INPROCESS.getKey(), PayStateEnum.PAY_INPROCESS.getDesc());
unifyPaySelectVO.setTradeId(tradeRecord.getId());
return unifyPaySelectVO;
} else {
try {
if (!PayStateEnum.isPaidState(tradeRecord.getTradeState()) && (unifyPaySelectDTO.isFromAutoQuery() || !tradeRecord.getCreateTime().plusSeconds((long) OrderMQConstants.PAY_QUERY_MAX_SECOND).isAfter(LocalDateTime.now()))) {
UnifyPayVO payVO = this.selectAndStartPayFlow(tradeRecord);
LogUtil.info("[支付查询]支付结果", payVO);
UnifyPaySelectVO var4;
if (PayStateEnum.isPayingState(payVO.getCode())) {
var4 = UnifyPaySelectVO.of(payVO);
return var4;
}
this.tradeRecordService.updateTradeRecordState(tradeRecord.getId(), payVO);
if (unifyPaySelectDTO.isSendNoticeMQ()) {
this.payTradeService.sendResultMq(tradeRecord.getId());
}
var4 = this.payCustomBusiness.didPaySelectV2(unifyPaySelectDTO, UnifyPaySelectVO.of(payVO));
return var4;
}
if (unifyPaySelectDTO.isSendNoticeMQ()) {
this.payTradeService.sendResultMq(tradeRecord.getId());
}
unifyPaySelectVO = this.payCustomBusiness.didPaySelectV2(unifyPaySelectDTO, UnifyPaySelectVO.of(tradeRecord));
} finally {
PayCacheConstants.unlockTrade(tradeRecord.getId());
}
return unifyPaySelectVO;
}
}
}
protected UnifyPayVO selectAndStartPayFlow(TradeRecord tradeRecord) {
List<TradeChannelVO> tradeChannels = this.tradeChannelService.listChannelDetailByTradeId(tradeRecord.getId());
UnifyPayDTO unifyPayDTO = UnifyPayDTO.of(tradeRecord);
TradeChannelVO lastTradeChannelVO = (TradeChannelVO)CollUtil.getLast(tradeChannels);
if (lastTradeChannelVO != null && PayStateEnum.isPayingState(lastTradeChannelVO.getTradeState())) {
PaySelectDTO paySelectDTO = new PaySelectDTO();
this.fillPaySelectDTO(paySelectDTO, unifyPayDTO);
AndroidPayVO androidPayVO = this.channelPaySelect(lastTradeChannelVO, paySelectDTO);
if (PayStateEnum.isPayingState(androidPayVO.getCode())) {
return UnifyPayVO.of(tradeRecord, tradeChannels);
}
lastTradeChannelVO.setTradeState(androidPayVO.getCode());
lastTradeChannelVO.setTradeResult(androidPayVO.getMsg());
if (LeNumUtil.isValidId(androidPayVO.getCustId()) && !LeNumUtil.isValidId(unifyPayDTO.getCustId())) {
unifyPayDTO.fillCustInfo(this.custInfoApi.getCustInfoByCustId(androidPayVO.getCustId()));
}
unifyPayDTO.fillCustInfoIfNecessary(androidPayVO);
}
tradeChannels = this.tradeChannelService.listChannelDetailByTradeId(tradeRecord.getId());
return this.startPayFlow(unifyPayDTO, tradeChannels);
}
protected void fillPaySelectDTO(PaySelectDTO paySelectDTO, UnifyPayDTO unifyPayDTO) {
paySelectDTO.setCanteenId(unifyPayDTO.getCanteenId());
paySelectDTO.setMachineSn(unifyPayDTO.getMachineSn());
paySelectDTO.setCouponId(unifyPayDTO.getCouponId());
paySelectDTO.setPayType(unifyPayDTO.getPayType());
paySelectDTO.setOrderRechargeId(CollUtil.isNotEmpty(unifyPayDTO.getOrderList()) ? ((UnifyPayDTO.Order)unifyPayDTO.getOrderList().get(0)).getOrderId() : null);
paySelectDTO.setMacOrderId(unifyPayDTO.getMacOrderId());
}
protected AndroidPayVO channelPaySelect(TradeChannelVO tradeChannel, PaySelectDTO paySelectDTO) {
paySelectDTO.setPayType(tradeChannel.getPayType());
paySelectDTO.setTradeChannelId(tradeChannel.getTradeChannelId());
paySelectDTO.setTradeTime(tradeChannel.getTradeTime());
paySelectDTO.setAmount(tradeChannel.getAmount());
paySelectDTO.setOutTradeNo(tradeChannel.getOutTradeNo());
AndroidPayVO androidPayVO = new AndroidPayVO();
try {
PayService payService = this.channelBusiness.beanOfChannel(tradeChannel.getPayChannel());
androidPayVO = payService.paySelect(paySelectDTO);
} catch (Exception var5) {
log.error("[支付查询]异常", var5);
androidPayVO.setCode(PayStateEnum.PAY_INPROCESS.getKey());
androidPayVO.setMsg(PayStateEnum.PAY_INPROCESS.getDesc());
}
log.info("[支付查询]返回结果:{}", JacksonUtil.writeValueAsStringIgnoreNull(androidPayVO));
this.fillVoFields(androidPayVO, tradeChannel);
if (PayStateEnum.PAY_INPROCESS.getKey().equals(androidPayVO.getCode())) {
return androidPayVO;
} else {
this.tradeChannelService.updateTradeRecordChannelState(androidPayVO.getTradeChannelId(), androidPayVO.getCode(), androidPayVO.getMsg(), androidPayVO.getOutTradeNo(), androidPayVO.getRealAmount(), (JsonNode)null, (LocalDateTime)null);
return androidPayVO;
}
}
protected void fillVoFields(AndroidPayVO payVO, TradeChannelVO channelVO) {
payVO.setTradeId(channelVO.getTradeChannelId());
payVO.setTradeChannelId(channelVO.getTradeChannelId());
payVO.setAmount(channelVO.getAmount());
if (payVO.getRealAmount() == null && PayStateEnum.isPaidState(payVO.getCode())) {
payVO.setRealAmount(payVO.getAmount());
}
if (payVO.getUnpaidBalance() == null) {
payVO.setUnpaidBalance(BigDecimal.ZERO);
}
if (payVO.getPayChannel() == null) {
payVO.setPayChannel(channelVO.getPayChannel());
}
if (payVO.getPayType() == null) {
payVO.setPayType(channelVO.getPayType());
}
}
}

View File

@ -0,0 +1,123 @@
package com.bonus.core.pay.common.dto;
import java.math.BigDecimal;
import java.time.LocalDateTime;
public class PaySelectDTO {
/** @deprecated */
@Deprecated
private Long tradeId;
private Long tradeChannelId;
private String outTradeNo;
private Long orderRechargeId;
private String macOrderId;
private Long canteenId;
private String machineSn;
private String couponId;
private Integer payType;
private LocalDateTime tradeTime;
private BigDecimal amount;
/** @deprecated */
@Deprecated
public Long getTradeId() {
return this.tradeChannelId;
}
public Long getTradeChannelId() {
return this.tradeChannelId;
}
public String getOutTradeNo() {
return this.outTradeNo;
}
public Long getOrderRechargeId() {
return this.orderRechargeId;
}
public String getMacOrderId() {
return this.macOrderId;
}
public Long getCanteenId() {
return this.canteenId;
}
public String getMachineSn() {
return this.machineSn;
}
public String getCouponId() {
return this.couponId;
}
public Integer getPayType() {
return this.payType;
}
public LocalDateTime getTradeTime() {
return this.tradeTime;
}
public BigDecimal getAmount() {
return this.amount;
}
/** @deprecated */
@Deprecated
public PaySelectDTO setTradeId(final Long tradeId) {
this.tradeId = tradeId;
return this;
}
public PaySelectDTO setTradeChannelId(final Long tradeChannelId) {
this.tradeChannelId = tradeChannelId;
return this;
}
public PaySelectDTO setOutTradeNo(final String outTradeNo) {
this.outTradeNo = outTradeNo;
return this;
}
public PaySelectDTO setOrderRechargeId(final Long orderRechargeId) {
this.orderRechargeId = orderRechargeId;
return this;
}
public PaySelectDTO setMacOrderId(final String macOrderId) {
this.macOrderId = macOrderId;
return this;
}
public PaySelectDTO setCanteenId(final Long canteenId) {
this.canteenId = canteenId;
return this;
}
public PaySelectDTO setMachineSn(final String machineSn) {
this.machineSn = machineSn;
return this;
}
public PaySelectDTO setCouponId(final String couponId) {
this.couponId = couponId;
return this;
}
public PaySelectDTO setPayType(final Integer payType) {
this.payType = payType;
return this;
}
public PaySelectDTO setTradeTime(final LocalDateTime tradeTime) {
this.tradeTime = tradeTime;
return this;
}
public PaySelectDTO setAmount(final BigDecimal amount) {
this.amount = amount;
return this;
}
}

View File

@ -4,8 +4,14 @@ import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bonus.core.pay.common.model.TradeRecord;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
@Mapper
@InterceptorIgnore
public interface TradeRecordMapper extends BaseMapper<TradeRecord> {
List<TradeRecord> listTradeRecordByOrderRechargeId(@Param("orderRechargeId") Long orderRechargeId, @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime, @Param("tradeState") Integer... tradeState);
}

View File

@ -0,0 +1,138 @@
package com.bonus.core.pay.common.po;
import com.bonus.core.common.utils.LogUtil;
import com.bonus.core.common.utils.TenantContextHolder;
import com.bonus.core.pay.api.vo.UnifyPayVO;
import com.bonus.core.pay.common.constants.PayStateEnum;
import com.bonus.core.pay.common.model.TradeRecord;
import com.bonus.framework.config.deserializer.DateTimeDeserializer;
import com.bonus.framework.config.serializer.DateTimeSerializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.time.LocalDateTime;
public class PayResultPO {
private Long tradeId;
private String traceId;
private Long merchantId;
private String outTradeNo;
private Integer tradeType;
private Integer tradeState;
private String tradeResult;
private Integer payChannel;
@JsonSerialize(
using = DateTimeSerializer.YYYY_MM_DD_HH_MM_SS.class
)
@JsonDeserialize(
using = DateTimeDeserializer.class
)
private LocalDateTime payTime;
public static PayResultPO of(TradeRecord tradeRecord) {
PayResultPO payResultPO = new PayResultPO();
payResultPO.setTradeId(tradeRecord.getId());
payResultPO.setOutTradeNo(tradeRecord.getOutTradeNo());
payResultPO.setTradeState(tradeRecord.getTradeState());
payResultPO.setPayChannel(tradeRecord.getPayChannel());
payResultPO.setMerchantId(TenantContextHolder.getTenantId());
payResultPO.setTradeType(tradeRecord.getTradeType());
payResultPO.setTradeResult(tradeRecord.getTradeResult());
if (PayStateEnum.isPaidState(tradeRecord.getTradeState())) {
payResultPO.setPayTime(tradeRecord.getTradeTime());
}
payResultPO.setTraceId(LogUtil.getCurrentTraceId());
return payResultPO;
}
public static PayResultPO of(UnifyPayVO unifyPayVO) {
PayResultPO payResultPO = new PayResultPO();
payResultPO.setTradeId(unifyPayVO.getTradeId());
payResultPO.setOutTradeNo(unifyPayVO.getOutTradeNo());
payResultPO.setTradeState(unifyPayVO.getCode());
payResultPO.setPayChannel(unifyPayVO.getPayChannel());
payResultPO.setMerchantId(TenantContextHolder.getTenantId());
payResultPO.setTradeType(unifyPayVO.getTradeType());
payResultPO.setTradeResult(unifyPayVO.getMsg());
payResultPO.setPayTime(unifyPayVO.getPayTime());
payResultPO.setTraceId(LogUtil.getCurrentTraceId());
return payResultPO;
}
public Long getTradeId() {
return this.tradeId;
}
public String getTraceId() {
return this.traceId;
}
public Long getMerchantId() {
return this.merchantId;
}
public String getOutTradeNo() {
return this.outTradeNo;
}
public Integer getTradeType() {
return this.tradeType;
}
public Integer getTradeState() {
return this.tradeState;
}
public String getTradeResult() {
return this.tradeResult;
}
public Integer getPayChannel() {
return this.payChannel;
}
public LocalDateTime getPayTime() {
return this.payTime;
}
public void setTradeId(final Long tradeId) {
this.tradeId = tradeId;
}
public void setTraceId(final String traceId) {
this.traceId = traceId;
}
public void setMerchantId(final Long merchantId) {
this.merchantId = merchantId;
}
public void setOutTradeNo(final String outTradeNo) {
this.outTradeNo = outTradeNo;
}
public void setTradeType(final Integer tradeType) {
this.tradeType = tradeType;
}
public void setTradeState(final Integer tradeState) {
this.tradeState = tradeState;
}
public void setTradeResult(final String tradeResult) {
this.tradeResult = tradeResult;
}
public void setPayChannel(final Integer payChannel) {
this.payChannel = payChannel;
}
@JsonDeserialize(
using = DateTimeDeserializer.class
)
public void setPayTime(final LocalDateTime payTime) {
this.payTime = payTime;
}
}

View File

@ -0,0 +1,142 @@
package com.bonus.core.pay.common.po;
import com.bonus.core.common.utils.TenantContextHolder;
import com.bonus.core.pay.common.constants.PayStateEnum;
import com.bonus.core.pay.common.model.TradeRecord;
import com.bonus.core.pay.common.vo.TradeChannelVO;
import com.bonus.framework.config.deserializer.DateTimeDeserializer;
import com.bonus.framework.config.serializer.DateTimeSerializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
public class RefundResultPO {
private Long refundTradeId;
private String traceId;
private Long merchantId;
private String outTradeNo;
private Integer payState;
private Integer payChannel;
private Integer tradeType;
private BigDecimal amount;
@JsonSerialize(
using = DateTimeSerializer.YYYY_MM_DD_HH_MM_SS.class
)
@JsonDeserialize(
using = DateTimeDeserializer.class
)
private LocalDateTime tradeTime;
private List<TradeChannelVO> detailList;
public static RefundResultPO of(TradeRecord tradeRecord, List<TradeChannelVO> tradeChannels) {
RefundResultPO payResultPO = new RefundResultPO();
if (tradeRecord == null) {
payResultPO.setPayState(PayStateEnum.PAY_FAIL.getKey());
return payResultPO;
} else {
payResultPO.setRefundTradeId(tradeRecord.getId());
payResultPO.setOutTradeNo(tradeRecord.getOutTradeNo());
payResultPO.setPayState(tradeRecord.getTradeState());
payResultPO.setPayChannel(tradeRecord.getPayChannel());
payResultPO.setAmount(tradeRecord.getAmount());
payResultPO.setMerchantId(TenantContextHolder.getTenantId());
payResultPO.setTradeType(tradeRecord.getTradeType());
payResultPO.setTradeTime(tradeRecord.getCreateTime());
payResultPO.setDetailList(tradeChannels);
return payResultPO;
}
}
public BigDecimal calcRealAmount() {
return PayStateEnum.isPaidState(this.payState) ? (BigDecimal)this.detailList.stream().filter((s) -> {
return PayStateEnum.isPaySuccessState(s.getTradeState());
}).map(TradeChannelVO::getAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add) : BigDecimal.ZERO;
}
public Long getRefundTradeId() {
return this.refundTradeId;
}
public String getTraceId() {
return this.traceId;
}
public Long getMerchantId() {
return this.merchantId;
}
public String getOutTradeNo() {
return this.outTradeNo;
}
public Integer getPayState() {
return this.payState;
}
public Integer getPayChannel() {
return this.payChannel;
}
public Integer getTradeType() {
return this.tradeType;
}
public BigDecimal getAmount() {
return this.amount;
}
public LocalDateTime getTradeTime() {
return this.tradeTime;
}
public List<TradeChannelVO> getDetailList() {
return this.detailList;
}
public void setRefundTradeId(final Long refundTradeId) {
this.refundTradeId = refundTradeId;
}
public void setTraceId(final String traceId) {
this.traceId = traceId;
}
public void setMerchantId(final Long merchantId) {
this.merchantId = merchantId;
}
public void setOutTradeNo(final String outTradeNo) {
this.outTradeNo = outTradeNo;
}
public void setPayState(final Integer payState) {
this.payState = payState;
}
public void setPayChannel(final Integer payChannel) {
this.payChannel = payChannel;
}
public void setTradeType(final Integer tradeType) {
this.tradeType = tradeType;
}
public void setAmount(final BigDecimal amount) {
this.amount = amount;
}
@JsonDeserialize(
using = DateTimeDeserializer.class
)
public void setTradeTime(final LocalDateTime tradeTime) {
this.tradeTime = tradeTime;
}
public void setDetailList(final List<TradeChannelVO> detailList) {
this.detailList = detailList;
}
}

View File

@ -113,4 +113,11 @@ public interface PayService {
qrCodeApplyVO.setMsg("暂不支持收款二维码");
return qrCodeApplyVO;
}
default AndroidPayVO paySelect(PaySelectDTO paySelectDTO) {
AndroidPayVO androidPayVO = new AndroidPayVO();
androidPayVO.setCode(PayStateEnum.PAY_INPROCESS.getKey());
androidPayVO.setMsg("当前渠道暂不支持查询支付结果");
return androidPayVO;
}
}

View File

@ -9,4 +9,5 @@ public interface PayTradeService {
boolean sendAutoPayResultQuery(UnifyPaySelectDTO paySelectDTO, LocalDateTime startTime, boolean cancelWhenEnd);
void sendResultMq(Long tradeId, int... delayMilliSeconds);
}

View File

@ -1,13 +1,19 @@
package com.bonus.core.pay.common.service;
import com.bonus.core.pay.common.model.TradeChannel;
import com.bonus.core.pay.common.vo.TradeChannelVO;
import com.fasterxml.jackson.databind.JsonNode;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
public interface TradeChannelService {
void insert(TradeChannel tradeChannel);
void updateTradeRecordChannelState(Long channelId, Integer tradeState, String tradeResult, String outTradeNo, BigDecimal realAmount, JsonNode param, LocalDateTime tradeTime);
List<TradeChannelVO> listChannelDetailByTradeId(Long tradeId);
List<TradeChannelVO> listChannelDetailByTradeIds(List<Long> tradeId);
}

View File

@ -18,4 +18,6 @@ public interface TradeRecordService {
TradeRecord getTradeRecordById(Long tradeId);
List<TradeOrderRecharge> queryOrderRechargeTrade(Long tradeId);
TradeRecord getTradeRecordByOrderRechargeId(Long orderRechargeId, Integer... tradeState);
}

View File

@ -1,5 +1,6 @@
package com.bonus.core.pay.common.service.impl;
import cn.hutool.core.util.ArrayUtil;
import com.bonus.core.common.constant.LeMqConstant;
import com.bonus.core.common.redis.RedisUtil;
import com.bonus.core.common.utils.JacksonUtil;
@ -9,18 +10,35 @@ import com.bonus.core.order.common.constants.OrderCacheConstants;
//import com.bonus.core.order.mq.MqUtil;
import com.bonus.core.order.mq.constants.OrderMQConstants;
import com.bonus.core.pay.api.dto.UnifyPaySelectDTO;
import com.bonus.core.pay.common.constants.PayStateEnum;
import com.bonus.core.pay.common.constants.TradeTypeEnum;
import com.bonus.core.pay.common.model.TradeRecord;
import com.bonus.core.pay.common.po.PayResultPO;
import com.bonus.core.pay.common.po.PayResultQueryPO;
import com.bonus.core.pay.common.po.RefundResultPO;
import com.bonus.core.pay.common.service.PayTradeService;
import com.bonus.core.pay.common.service.TradeChannelService;
import com.bonus.core.pay.common.service.TradeRecordService;
import com.bonus.core.pay.common.vo.TradeChannelVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class PayTradeServiceImpl implements PayTradeService {
private static final Logger log = LoggerFactory.getLogger(PayTradeServiceImpl.class);
@Lazy
@Resource
private TradeRecordService tradeRecordService;
@Lazy
@Resource
private TradeChannelService tradeChannelService;
@Override
public boolean sendAutoPayResultQuery(UnifyPaySelectDTO paySelectDTO, LocalDateTime startTime, boolean endWithCancel) {
@ -45,4 +63,31 @@ public class PayTradeServiceImpl implements PayTradeService {
return false;
}
}
@Override
public void sendResultMq(Long tradeId, int... delayMilliSeconds) {
TradeRecord tradeRecord = this.tradeRecordService.getTradeRecordById(tradeId);
try {
if (TradeTypeEnum.isPayCategory(tradeRecord.getTradeType()) && PayStateEnum.isFinishedState(tradeRecord.getTradeState())) {
PayResultPO payResultPO = PayResultPO.of(tradeRecord);
if (ArrayUtil.isNotEmpty(delayMilliSeconds)) {
// MqUtil.sendDelay(JacksonUtil.writeValueAsString(payResultPO), LeMqConstant.Topic.PAY_RESULT, delayMilliSeconds[0]);
} else {
// MqUtil.sendByTxEnd(JacksonUtil.writeValueAsString(payResultPO), LeMqConstant.Topic.PAY_RESULT);
}
} else if (TradeTypeEnum.isRefundCategory(tradeRecord.getTradeType()) && PayStateEnum.isFinishedState(tradeRecord.getTradeState())) {
List<TradeChannelVO> tradeChannels = this.tradeChannelService.listChannelDetailByTradeId(tradeId);
RefundResultPO payResultPO = RefundResultPO.of(tradeRecord, tradeChannels);
if (ArrayUtil.isNotEmpty(delayMilliSeconds)) {
// MqUtil.sendDelay(JacksonUtil.writeValueAsString(payResultPO), LeMqConstant.Topic.REFUND_RESULT, delayMilliSeconds[0]);
} else {
// MqUtil.sendByTxEnd(JacksonUtil.writeValueAsString(payResultPO), LeMqConstant.Topic.REFUND_RESULT);
}
}
} catch (Exception var6) {
log.error("[支付结果通知]发送失败", var6);
}
}
}

View File

@ -2,6 +2,7 @@ package com.bonus.core.pay.common.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.core.order.utils.LeNumUtil;
@ -10,6 +11,7 @@ import com.bonus.core.pay.common.constants.PayStateEnum;
import com.bonus.core.pay.common.mapper.TradeRecordChannelMapper;
import com.bonus.core.pay.common.model.TradeChannel;
import com.bonus.core.pay.common.service.TradeChannelService;
import com.bonus.core.pay.common.vo.TradeChannelVO;
import com.fasterxml.jackson.databind.JsonNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -18,6 +20,7 @@ import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class TradeChannelServiceImpl extends ServiceImpl<TradeRecordChannelMapper, TradeChannel> implements TradeChannelService {
@ -50,4 +53,23 @@ public class TradeChannelServiceImpl extends ServiceImpl<TradeRecordChannelMappe
((TradeRecordChannelMapper) this.baseMapper).insert(tradeChannel);
log.info("[渠道支付]插入渠道明细 结束");
}
@Override
public List<TradeChannelVO> listChannelDetailByTradeId(Long tradeId) {
return (List)(!LeNumUtil.isValidId(tradeId) ? CollUtil.newArrayList(new TradeChannelVO[0]) : this.listChannelDetailByTradeIds(CollUtil.toList(new Long[]{tradeId})));
}
@Override
public List<TradeChannelVO> listChannelDetailByTradeIds(List<Long> tradeIds) {
if (CollUtil.isEmpty(tradeIds)) {
return CollUtil.newArrayList(new TradeChannelVO[0]);
} else {
List<LocalDateTime> createTimeRange = LeOrderUtil.queryCreateTimeRange(tradeIds);
return ((TradeRecordChannelMapper)this.baseMapper).selectList(Wrappers.lambdaQuery(TradeChannel.class)
.in(TradeChannel::getTradeId, tradeIds)
.between(TradeChannel::getCreateTime, createTimeRange.get(0), createTimeRange.get(1)))
.stream().map(TradeChannelVO::of)
.collect(Collectors.toList());
}
}
}

View File

@ -16,6 +16,7 @@ import com.bonus.core.pay.common.mapper.TradeRecordMapper;
import com.bonus.core.pay.common.model.TradeOrderRecharge;
import com.bonus.core.pay.common.model.TradeRecord;
import com.bonus.core.pay.common.service.TradeRecordService;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@ -94,4 +95,14 @@ public class TradeRecordServiceImpl extends ServiceImpl<TradeRecordMapper, Trade
log.info("[交易记录] queryOrderRechargeTrade 结束");
return tradeOrderRechargeList;
}
@Override
public TradeRecord getTradeRecordByOrderRechargeId(Long orderRechargeId, Integer... tradeState) {
log.info("[交易记录] getTradeRecordByOrderRechargeId 开始");
List<LocalDateTime> timeRange = LeOrderUtil.queryCreateTimeRange();
List<TradeRecord> tradeRecords = ((TradeRecordMapper)this.baseMapper).listTradeRecordByOrderRechargeId(orderRechargeId, (LocalDateTime)timeRange.get(0), (LocalDateTime)timeRange.get(1), tradeState);
log.info("[交易记录] getTradeRecordByOrderRechargeId 结束");
return (TradeRecord)CollUtil.getFirst(tradeRecords);
}
}

View File

@ -1,6 +1,8 @@
package com.bonus.core.pay.custom;
import com.bonus.core.common.custom.business.CustomBusiness;
import com.bonus.core.pay.api.dto.UnifyPayDTO;
import com.bonus.core.pay.api.dto.UnifyPaySelectDTO;
import com.bonus.core.pay.api.vo.UnifyPaySelectVO;
import com.bonus.core.pay.api.vo.UnifyPayVO;
import com.bonus.core.pay.common.constants.PayChannelSelectEnum;
import com.bonus.core.pay.common.dto.ChannelPayDTO;
@ -43,4 +45,11 @@ public class PayCustomBusiness implements CustomBusiness {
}
public void willChannelPay(ChannelPayDTO channelPayDTO) {
}
public void willPaySelectV2(UnifyPaySelectDTO paySelectDTO) {
}
public UnifyPaySelectVO didPaySelectV2(UnifyPaySelectDTO paySelectDTO, UnifyPaySelectVO paySelectVO) {
return paySelectVO;
}
}

View File

@ -4,5 +4,39 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bonus.core.pay.common.mapper.TradeRecordMapper">
<select id="listTradeRecordByOrderRechargeId" resultType="com.bonus.core.pay.common.model.TradeRecord">
SELECT tr.id,
tr.related_trade_id,
tr.cust_id custId,
tr.amount,
tr.trade_state tradeState,
tr.trade_result tradeResult,
tr.trade_type tradeType,
tr.pay_type payType,
tr.pay_channel payChannel,
tr.source_type sourceType,
tr.out_trade_no outTradeNo,
tr.canteen_id canteenId,
tr.create_time createTime,
tr.param
FROM trade_record tr INNER JOIN trade_order_recharge ort ON tr.id = ort.trade_id
WHERE ort.order_recharge_id = #{orderRechargeId}
<if test="tradeState != null and tradeState.length > 0">
AND tr.trade_state IN
<foreach collection="tradeState" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="startTime != null">
AND tr.create_time <![CDATA[ >= ]]> #{startTime}
AND ort.create_time <![CDATA[ >= ]]> #{startTime}
</if>
<if test="endTime != null">
AND tr.create_time <![CDATA[ <= ]]> #{endTime}
AND ort.create_time <![CDATA[ <= ]]> #{endTime}
</if>
ORDER BY tr.id DESC
</select>
</mapper>

View File

@ -112,5 +112,20 @@
</where>
</select>
<!-- 移动端根据交易id获取交易记录-->
<select id="getOneTradeApp" resultType="com.bonus.core.account.v3.app.vo.AppAccTradePageVO">
SELECT
id AS tradeId,
amount,
acc_all_bal as walletBalTotal,
trade_type,
trade_time,
pay_state,
pay_type,
remark
FROM acc_trade
WHERE id = #{tradeId}
</select>
</mapper>