feat 同步支付通道记录功能和支付相关功能调整

This commit is contained in:
xxm1995
2024-02-19 17:52:38 +08:00
parent 5fa06c4504
commit aa77586656
28 changed files with 501 additions and 102 deletions

View File

@@ -10,7 +10,7 @@ import lombok.Getter;
*/
@Getter
@AllArgsConstructor
public enum CashrRecordTypeEnum {
public enum CashRecordTypeEnum {
/** 支付 */
PAY("pay", "支付"),
@@ -19,10 +19,7 @@ public enum CashrRecordTypeEnum {
REFUND("refund", "退款"),
/** 支付关闭 */
CLOSE_PAY("close_pay", "支付关闭"),
/** 退款关闭 */
CLOSE_REFUND("close_refund", "退款关闭");
CLOSE_PAY("close_pay", "支付关闭");
private final String code;
private final String name;

View File

@@ -22,10 +22,7 @@ public enum VoucherRecordTypeEnum {
REFUND("refund", "退款"),
/** 支付关闭 */
CLOSE_PAY("close_pay", "支付关闭"),
/** 退款关闭 */
CLOSE_REFUND("close_refund", "退款关闭");
CLOSE_PAY("close_pay", "支付关闭");
private final String code;
private final String name;

View File

@@ -15,6 +15,12 @@ public enum WalletRecordTypeEnum {
/** 创建 */
CREATE("create", "创建"),
/** 余额充值 */
RECHARGE("recharge", "充值"),
/** 余额扣减 */
DEDUCT("deduct", "扣减"),
/** 支付 */
PAY("pay", "支付"),
@@ -22,10 +28,7 @@ public enum WalletRecordTypeEnum {
REFUND("refund", "退款"),
/** 支付关闭 */
CLOSE_PAY("close_pay", "支付关闭"),
/** 退款关闭 */
CLOSE_REFUND("close_refund", "退款关闭");
CLOSE_PAY("close_pay", "支付关闭");
private final String code;
private final String name;

View File

@@ -2,7 +2,7 @@ package cn.bootx.platform.daxpay.service.core.channel.cash.entity;
import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
import cn.bootx.platform.daxpay.service.code.VoucherRecordTypeEnum;
import cn.bootx.platform.daxpay.service.code.CashRecordTypeEnum;
import cn.bootx.platform.daxpay.service.core.channel.cash.convert.CashPayConfigConvert;
import cn.bootx.platform.daxpay.service.dto.channel.cash.CashRecordDto;
import cn.bootx.table.modify.annotation.DbColumn;
@@ -24,7 +24,7 @@ public class CashRecord extends MpCreateEntity implements EntityBaseFunction<Cas
/**
* 业务类型
* @see VoucherRecordTypeEnum
* @see CashRecordTypeEnum
*/
@DbColumn(comment = "业务类型")
private String type;

View File

@@ -3,8 +3,11 @@ package cn.bootx.platform.daxpay.service.core.channel.cash.service;
import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.daxpay.service.code.CashRecordTypeEnum;
import cn.bootx.platform.daxpay.service.core.channel.cash.dao.CashRecordManager;
import cn.bootx.platform.daxpay.service.core.channel.cash.entity.CashRecord;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
import cn.bootx.platform.daxpay.service.core.order.refund.entity.PayRefundChannelOrder;
import cn.bootx.platform.daxpay.service.dto.channel.cash.CashRecordDto;
import cn.bootx.platform.daxpay.service.param.channel.cash.CashRecordQuery;
import lombok.RequiredArgsConstructor;
@@ -21,19 +24,53 @@ import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class CashRecordService {
private final CashRecordManager manager;
private final CashRecordManager cashRecordManager;
/**
* 支付保存
*/
public void pay(PayChannelOrder channelOrder){
CashRecord record = new CashRecord()
.setType(CashRecordTypeEnum.PAY.getCode())
.setAmount(channelOrder.getAmount())
.setOrderId(String.valueOf(channelOrder.getPaymentId()));
cashRecordManager.save(record);
}
/**
* 退款保存
*/
public void refund(PayRefundChannelOrder channelOrder){
CashRecord record = new CashRecord()
.setType(CashRecordTypeEnum.REFUND.getCode())
.setAmount(channelOrder.getAmount())
.setOrderId(String.valueOf(channelOrder.getRefundId()));
cashRecordManager.save(record);
}
/**
* 支付关闭
*/
public void payClose(PayChannelOrder channelOrder){
CashRecord record = new CashRecord()
.setType(CashRecordTypeEnum.CLOSE_PAY.getCode())
.setAmount(channelOrder.getAmount())
.setOrderId(String.valueOf(channelOrder.getPaymentId()));
cashRecordManager.save(record);
}
/**
* 分页查询
*/
public PageResult<CashRecordDto> page(PageParam pageParam, CashRecordQuery param) {
return MpUtil.convert2DtoPageResult(manager.page(pageParam, param));
return MpUtil.convert2DtoPageResult(cashRecordManager.page(pageParam, param));
}
/**
* 查询详情
*/
public CashRecordDto findById(Long id){
return manager.findById(id).map(CashRecord::toDto).orElseGet(CashRecordDto::new);
return cashRecordManager.findById(id).map(CashRecord::toDto).orElseGet(CashRecordDto::new);
}
}

View File

@@ -5,7 +5,6 @@ import cn.bootx.platform.daxpay.param.channel.VoucherPayParam;
import cn.bootx.platform.daxpay.service.core.channel.voucher.dao.VoucherManager;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.Voucher;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -27,20 +26,6 @@ public class VoucherPayService {
private final VoucherQueryService voucherQueryService;
/**
* 获取并检查储值卡
*/
public Voucher getAndCheckVoucher(VoucherPayParam voucherPayParam) {
String cardNo = voucherPayParam.getCardNo();
Voucher voucher = voucherManager.findByCardNo(cardNo).orElseThrow(()->new PayFailureException("储值卡不存在"));
// 卡信息校验
String timeCheck = voucherQueryService.check(voucher);
if (StrUtil.isNotBlank(timeCheck)) {
throw new PayFailureException(timeCheck);
}
return voucher;
}
/**
* 支付
@@ -70,11 +55,7 @@ public class VoucherPayService {
* 退款
*/
@Transactional(rollbackFor = Exception.class)
public void refund(PayChannelOrder channelOrder, int amount) {
String channelExtra = channelOrder.getChannelExtra();
VoucherPayParam voucherPayParam = JSONUtil.toBean(channelExtra, VoucherPayParam.class);
Voucher voucher = voucherManager.findByCardNo(voucherPayParam.getCardNo())
.orElseThrow(() -> new PayFailureException("储值卡不存在"));
public void refund(int amount, Voucher voucher) {
voucher.setBalance(voucher.getBalance()+amount);
voucherManager.updateById(voucher);
}

View File

@@ -6,6 +6,7 @@ import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.param.channel.VoucherPayParam;
import cn.bootx.platform.daxpay.service.core.channel.voucher.dao.VoucherManager;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.Voucher;
import cn.bootx.platform.daxpay.service.dto.channel.voucher.VoucherDto;
@@ -53,6 +54,30 @@ public class VoucherQueryService {
.orElseThrow(() -> new DataNotExistException("储值卡不存在"));
}
/**
* 根据卡号查询
*/
public Voucher getVoucherByCardNo(String cardNo) {
return voucherManager.findByCardNo(cardNo)
.orElseThrow(() -> new DataNotExistException("储值卡不存在"));
}
/**
* 获取并检查储值卡
*/
public Voucher getAndCheckVoucher(VoucherPayParam voucherPayParam) {
String cardNo = voucherPayParam.getCardNo();
Voucher voucher = voucherManager.findByCardNo(cardNo).orElseThrow(()->new PayFailureException("储值卡不存在"));
// 卡信息校验
String timeCheck = this.check(voucher);
if (StrUtil.isNotBlank(timeCheck)) {
throw new PayFailureException(timeCheck);
}
return voucher;
}
/**
* 判断卡号是否存在
*/

View File

@@ -3,8 +3,12 @@ package cn.bootx.platform.daxpay.service.core.channel.voucher.service;
import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.daxpay.service.code.VoucherRecordTypeEnum;
import cn.bootx.platform.daxpay.service.core.channel.voucher.dao.VoucherRecordManager;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.Voucher;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.VoucherRecord;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
import cn.bootx.platform.daxpay.service.core.order.refund.entity.PayRefundChannelOrder;
import cn.bootx.platform.daxpay.service.dto.channel.voucher.VoucherRecordDto;
import cn.bootx.platform.daxpay.service.param.channel.voucher.VoucherRecordQuery;
import lombok.RequiredArgsConstructor;
@@ -22,6 +26,61 @@ import org.springframework.stereotype.Service;
public class VoucherRecordService {
private final VoucherRecordManager manager;
/**
* 导入保存
*/
public void importVoucher(Voucher voucher){
VoucherRecord voucherRecord = new VoucherRecord()
.setType(VoucherRecordTypeEnum.IMPORT.getCode())
.setAmount(voucher.getBalance())
.setNewAmount(voucher.getBalance())
.setOldAmount(0)
.setVoucherId(voucher.getId());
manager.save(voucherRecord);
}
/**
* 支付保存
*/
public void pay(PayChannelOrder channelOrder, Voucher voucher){
VoucherRecord voucherRecord = new VoucherRecord()
.setType(VoucherRecordTypeEnum.PAY.getCode())
.setAmount(channelOrder.getAmount())
.setNewAmount(voucher.getBalance())
.setOldAmount(voucher.getBalance() - channelOrder.getAmount())
.setOrderId(String.valueOf(channelOrder.getPaymentId()))
.setVoucherId(voucher.getId());
manager.save(voucherRecord);
}
/**
* 退款保存
*/
public void refund(PayRefundChannelOrder channelOrder, Voucher voucher){
VoucherRecord voucherRecord = new VoucherRecord()
.setType(VoucherRecordTypeEnum.REFUND.getCode())
.setAmount(channelOrder.getAmount())
.setNewAmount(voucher.getBalance())
.setOldAmount(voucher.getBalance() + channelOrder.getAmount())
.setOrderId(String.valueOf(channelOrder.getRefundId()))
.setVoucherId(voucher.getId());
manager.save(voucherRecord);
}
/**
* 支付关闭
*/
public void payClose(PayChannelOrder channelOrder, Voucher voucher){
VoucherRecord voucherRecord = new VoucherRecord()
.setType(VoucherRecordTypeEnum.CLOSE_PAY.getCode())
.setAmount(channelOrder.getAmount())
.setNewAmount(voucher.getBalance())
.setOldAmount(voucher.getBalance() - channelOrder.getAmount())
.setOrderId(String.valueOf(channelOrder.getPaymentId()))
.setVoucherId(voucher.getId());
manager.save(voucherRecord);
}
/**
* 分页查询

View File

@@ -28,6 +28,8 @@ public class VoucherService {
private final VoucherManager voucherManager;
private final VoucherRecordService recordService;
/**
* 导入
*/
@@ -39,6 +41,7 @@ public class VoucherService {
throw new BizException("储值卡已存在");
}
voucherManager.save(voucher);
recordService.importVoucher(voucher);
}
/**

View File

@@ -1,18 +1,13 @@
package cn.bootx.platform.daxpay.service.core.channel.wallet.service;
import cn.bootx.platform.common.core.exception.DataNotExistException;
import cn.bootx.platform.daxpay.param.channel.WalletPayParam;
import cn.bootx.platform.daxpay.service.core.channel.wallet.dao.WalletManager;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.Wallet;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Objects;
/**
* 钱包支付操作
*
@@ -49,23 +44,9 @@ public class WalletPayService {
* 退款
*/
@Transactional(rollbackFor = Exception.class)
public void refund(PayChannelOrder channelOrder, int amount) {
// 从通道扩展参数中取出钱包参数
String channelExtra = channelOrder.getChannelExtra();
WalletPayParam walletPayParam = JSONUtil.toBean(channelExtra, WalletPayParam.class);
// 获取钱包
Wallet wallet = null;
if (Objects.nonNull(walletPayParam.getWalletId())){
wallet = walletManager.findById(walletPayParam.getWalletId()).orElseThrow(DataNotExistException::new);
}
if (Objects.nonNull(walletPayParam.getUserId())){
wallet = walletManager.findByUser(walletPayParam.getUserId()).orElseThrow(DataNotExistException::new);
}
public void refund(Wallet wallet, int amount) {
// 将金额退款到钱包中
wallet.setBalance(wallet.getBalance() + amount);
walletManager.updateById(wallet);
}
}

View File

@@ -4,6 +4,7 @@ import cn.bootx.platform.common.core.exception.DataNotExistException;
import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.daxpay.service.code.WalletRecordTypeEnum;
import cn.bootx.platform.daxpay.service.core.channel.wallet.dao.WalletRecordManager;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.Wallet;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.WalletRecord;
@@ -25,13 +26,13 @@ import org.springframework.stereotype.Service;
@RequiredArgsConstructor
public class WalletRecordService {
private final WalletRecordManager walletRecordManager;
private final WalletQueryService walletQueryService;
/**
* 创建保存
*/
public void create(Wallet wallet){
WalletRecord walletRecord = new WalletRecord()
.setType(WalletRecordTypeEnum.CREATE.getCode())
.setAmount(wallet.getBalance())
.setNewAmount(wallet.getBalance())
.setOldAmount(0)
@@ -39,11 +40,38 @@ public class WalletRecordService {
walletRecordManager.save(walletRecord);
}
/**
* 充值保存
*/
public void recharge(Wallet wallet, int amount){
WalletRecord walletRecord = new WalletRecord()
.setType(WalletRecordTypeEnum.RECHARGE.getCode())
.setAmount(wallet.getBalance())
.setNewAmount(wallet.getBalance())
.setOldAmount(wallet.getBalance() + amount)
.setWalletId(wallet.getId());
walletRecordManager.save(walletRecord);
}
/**
* 扣减保存
*/
public void deduct(Wallet wallet, int amount){
WalletRecord walletRecord = new WalletRecord()
.setType(WalletRecordTypeEnum.DEDUCT.getCode())
.setWalletId(wallet.getId())
.setAmount(wallet.getBalance())
.setNewAmount(wallet.getBalance())
.setOldAmount(wallet.getBalance() + amount);
walletRecordManager.save(walletRecord);
}
/**
* 支付保存
*/
public void pay(PayChannelOrder channelOrder, Wallet wallet){
WalletRecord walletRecord = new WalletRecord()
.setType(WalletRecordTypeEnum.PAY.getCode())
.setAmount(channelOrder.getAmount())
.setNewAmount(wallet.getBalance())
.setOldAmount(wallet.getBalance() - channelOrder.getAmount())
@@ -57,6 +85,7 @@ public class WalletRecordService {
*/
public void refund(PayRefundChannelOrder channelOrder, Wallet wallet){
WalletRecord walletRecord = new WalletRecord()
.setType(WalletRecordTypeEnum.REFUND.getCode())
.setAmount(channelOrder.getAmount())
.setNewAmount(wallet.getBalance())
.setOldAmount(wallet.getBalance() + channelOrder.getAmount())
@@ -70,6 +99,7 @@ public class WalletRecordService {
*/
public void payClose(PayChannelOrder channelOrder, Wallet wallet){
WalletRecord walletRecord = new WalletRecord()
.setType(WalletRecordTypeEnum.CLOSE_PAY.getCode())
.setAmount(channelOrder.getAmount())
.setNewAmount(wallet.getBalance())
.setOldAmount(wallet.getBalance() - channelOrder.getAmount())
@@ -78,19 +108,6 @@ public class WalletRecordService {
walletRecordManager.save(walletRecord);
}
/**
* 退款关闭
*/
public void refundClose(PayRefundChannelOrder channelOrder, Wallet wallet){
WalletRecord walletRecord = new WalletRecord()
.setAmount(channelOrder.getAmount())
.setNewAmount(wallet.getBalance())
.setOldAmount(wallet.getBalance() - channelOrder.getAmount())
.setOrderId(String.valueOf(channelOrder.getRefundId()))
.setWalletId(wallet.getId());
walletRecordManager.save(walletRecord);
}
/**
* 分页
*/

View File

@@ -25,6 +25,7 @@ import java.util.Objects;
@RequiredArgsConstructor
public class WalletService {
private final WalletManager walletManager;
private final WalletRecordService walletRecordService;
/**
* 创建钱包操作,默认为启用状态, 不传输余额则默认为0
@@ -79,6 +80,7 @@ public class WalletService {
}
wallet.setBalance(wallet.getBalance() + param.getAmount());
walletManager.updateById(wallet);
walletRecordService.recharge(wallet, param.getAmount());
}
/**
@@ -98,5 +100,6 @@ public class WalletService {
}
wallet.setBalance(wallet.getBalance() - param.getAmount());
walletManager.updateById(wallet);
walletRecordService.deduct(wallet, param.getAmount());
}
}

View File

@@ -1,8 +1,13 @@
package cn.bootx.platform.daxpay.service.core.payment.close.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.param.channel.VoucherPayParam;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.Voucher;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherPayService;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherQueryService;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherRecordService;
import cn.bootx.platform.daxpay.service.func.AbsPayCloseStrategy;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
@@ -23,17 +28,33 @@ public class VoucherPayCloseStrategy extends AbsPayCloseStrategy {
private final VoucherPayService voucherPayService;
private final VoucherRecordService voucherRecordService;
private final VoucherQueryService voucherQueryService;
private Voucher voucher;
@Override
public PayChannelEnum getChannel() {
return PayChannelEnum.VOUCHER;
}
/**
* 关闭前的处理方式
*/
@Override
public void doBeforeCloseHandler() {
String channelExtra = this.getChannelOrder().getChannelExtra();
VoucherPayParam params = JSONUtil.toBean(channelExtra, VoucherPayParam.class);
this.voucher = voucherQueryService.getVoucherByCardNo(params.getCardNo());
}
/**
* 关闭操作
*/
@Override
public void doCloseHandler() {
voucherPayService.close(this.getChannelOrder());
voucherRecordService.payClose(this.getChannelOrder(),this.voucher);
}
}

View File

@@ -3,6 +3,7 @@ package cn.bootx.platform.daxpay.service.core.payment.pay.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.exception.pay.PayAmountAbnormalException;
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
import cn.bootx.platform.daxpay.service.core.channel.cash.service.CashRecordService;
import cn.bootx.platform.daxpay.service.func.AbsPayStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -23,6 +24,8 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@RequiredArgsConstructor
public class CashPayStrategy extends AbsPayStrategy {
private final CashRecordService cashRecordService;
/**
* 现金支付
*/
@@ -48,7 +51,7 @@ public class CashPayStrategy extends AbsPayStrategy {
*/
@Override
public void doPayHandler() {
// 不需要做处理,
cashRecordService.pay(this.getChannelOrder());
}
}

View File

@@ -5,6 +5,8 @@ import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.param.channel.VoucherPayParam;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.Voucher;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherPayService;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherQueryService;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherRecordService;
import cn.bootx.platform.daxpay.service.func.AbsPayStrategy;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
@@ -32,6 +34,10 @@ public class VoucherPayStrategy extends AbsPayStrategy {
private final VoucherPayService voucherPayService;
private final VoucherQueryService voucherQueryService;
private final VoucherRecordService voucherRecordService;
private Voucher voucher;
@Override
@@ -57,7 +63,7 @@ public class VoucherPayStrategy extends AbsPayStrategy {
catch (JSONException e) {
throw new PayFailureException("储值卡支付参数错误");
}
this.voucher = voucherPayService.getAndCheckVoucher(voucherPayParam);
this.voucher = voucherQueryService.getAndCheckVoucher(voucherPayParam);
// 金额是否满足
if (this.getPayChannelParam().getAmount() > this.voucher.getBalance()) {
throw new PayFailureException("储值卡余额不足");
@@ -70,6 +76,7 @@ public class VoucherPayStrategy extends AbsPayStrategy {
@Override
public void doPayHandler() {
voucherPayService.pay(this.getPayChannelParam().getAmount(), this.voucher);
voucherRecordService.pay(this.getChannelOrder(), this.voucher);
}
}

View File

@@ -1,6 +1,9 @@
package cn.bootx.platform.daxpay.service.core.payment.refund.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.code.RefundStatusEnum;
import cn.bootx.platform.daxpay.service.core.channel.cash.service.CashRecordService;
import cn.bootx.platform.daxpay.service.func.AbsRefundStrategy;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Scope;
@@ -17,6 +20,7 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@Component
@RequiredArgsConstructor
public class CashPayRefundStrategy extends AbsRefundStrategy {
private final CashRecordService cashRecordService;
/**
* 策略标识
@@ -26,11 +30,30 @@ public class CashPayRefundStrategy extends AbsRefundStrategy {
return PayChannelEnum.CASH;
}
/**
* 退款, 不需要进行操作
* 退款操作
*/
@Override
public void doRefundHandler() {
// 不包含异步支付
if (!this.getPayOrder().isAsyncPay()){
cashRecordService.refund(this.getRefundChannelOrder());
}
}
/**
* 退款发起成功操作
*/
@Override
public void doSuccessHandler() {
// 包含异步支付, 变更状态到退款中
if (this.getPayOrder().isAsyncPay()) {
this.getPayChannelOrder().setStatus(PayStatusEnum.REFUNDING.getCode());
this.getRefundChannelOrder().setStatus(RefundStatusEnum.PROGRESS.getCode());
} else{
// 同步支付, 直接标识状态为退款完成
super.doSuccessHandler();
}
}
}

View File

@@ -1,8 +1,15 @@
package cn.bootx.platform.daxpay.service.core.payment.refund.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.code.RefundStatusEnum;
import cn.bootx.platform.daxpay.param.channel.VoucherPayParam;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.Voucher;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherPayService;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherQueryService;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherRecordService;
import cn.bootx.platform.daxpay.service.func.AbsRefundStrategy;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -20,6 +27,12 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
public class VoucherPayRefundStrategy extends AbsRefundStrategy {
private final VoucherPayService voucherPayService;
private final VoucherQueryService voucherQueryService;
private final VoucherRecordService voucherRecordService;
private Voucher voucher;
/**
* 策略标识
*
@@ -30,12 +43,46 @@ public class VoucherPayRefundStrategy extends AbsRefundStrategy {
return PayChannelEnum.VOUCHER;
}
/**
* 退款前对处理
*/
@Override
public void doBeforeRefundHandler() {
// 从通道扩展参数中取出钱包参数
if (!this.getPayOrder().isAsyncPay()) {
String channelExtra = this.getPayChannelOrder().getChannelExtra();
VoucherPayParam voucherPayParam = JSONUtil.toBean(channelExtra, VoucherPayParam.class);
this.voucher = voucherQueryService.getVoucherByCardNo(voucherPayParam.getCardNo());
}
}
/**
* 退款
*/
@Override
public void doRefundHandler() {
voucherPayService.refund(this.getPayChannelOrder(), this.getRefundChannelParam().getAmount());
// 不包含异步支付
if (!this.getPayOrder().isAsyncPay()){
voucherPayService.refund(this.getRefundChannelParam().getAmount(), this.voucher);
voucherRecordService.refund(this.getRefundChannelOrder(), this.voucher);
}
}
/**
* 退款发起成功操作, 异步支付通道需要进行重写
*/
@Override
public void doSuccessHandler() {
// 包含异步支付, 变更状态到退款中
if (this.getPayOrder().isAsyncPay()) {
this.getPayChannelOrder().setStatus(PayStatusEnum.REFUNDING.getCode());
this.getRefundChannelOrder().setStatus(RefundStatusEnum.PROGRESS.getCode());
} else{
// 同步支付, 直接标识状态为退款完成
super.doSuccessHandler();
}
}
}

View File

@@ -1,8 +1,15 @@
package cn.bootx.platform.daxpay.service.core.payment.refund.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.code.RefundStatusEnum;
import cn.bootx.platform.daxpay.param.channel.WalletPayParam;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.Wallet;
import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletPayService;
import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletQueryService;
import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletRecordService;
import cn.bootx.platform.daxpay.service.func.AbsRefundStrategy;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -18,7 +25,15 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@Component
@RequiredArgsConstructor
public class WalletPayRefundStrategy extends AbsRefundStrategy {
private final WalletPayService walletPayService;
private final WalletRecordService walletRecordService;
private final WalletQueryService walletQueryService;
private Wallet wallet;
/**
* 策略标识
*
@@ -30,10 +45,42 @@ public class WalletPayRefundStrategy extends AbsRefundStrategy {
}
/**
* 退款
* 退款前对处理
*/
@Override
public void doBeforeRefundHandler() {
// 从通道扩展参数中取出钱包参数
if (!this.getPayOrder().isAsyncPay()) {
String channelExtra = this.getPayChannelOrder().getChannelExtra();
WalletPayParam walletPayParam = JSONUtil.toBean(channelExtra, WalletPayParam.class);
this.wallet = walletQueryService.getWallet(walletPayParam);
}
}
/**
* 退款操作
*/
@Override
public void doRefundHandler() {
walletPayService.refund(this.getPayChannelOrder(), this.getRefundChannelParam().getAmount());
// 不包含异步支付
if (!this.getPayOrder().isAsyncPay()){
walletPayService.refund(this.wallet, this.getRefundChannelParam().getAmount());
walletRecordService.refund(this.getRefundChannelOrder(), this.wallet);
}
}
/**
* 退款发起成功操作, 异步支付通道需要进行重写
*/
@Override
public void doSuccessHandler() {
// 包含异步支付, 变更状态到退款中
if (this.getPayOrder().isAsyncPay()) {
this.getPayChannelOrder().setStatus(PayStatusEnum.REFUNDING.getCode());
this.getRefundChannelOrder().setStatus(RefundStatusEnum.PROGRESS.getCode());
} else{
// 同步支付, 直接标识状态为退款完成
super.doSuccessHandler();
}
}
}

View File

@@ -97,7 +97,6 @@ public class RefundRepairService {
// 退款修复记录
PayRepairRecord refundRepairRecord = this.refundRepairRecord(refundOrder, repairType, repairResult);
recordService.saveAllRecord(Arrays.asList(payRepairRecord, refundRepairRecord));
return repairResult;
}

View File

@@ -2,6 +2,7 @@ package cn.bootx.platform.daxpay.service.core.payment.repair.strategy.pay;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.service.core.channel.cash.service.CashRecordService;
import cn.bootx.platform.daxpay.service.func.AbsPayRepairStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -21,7 +22,7 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@RequiredArgsConstructor
public class CashPayRepairStrategy extends AbsPayRepairStrategy {
private final CashRecordService cashRecordService;
/**
* 策略标识
*/
@@ -31,10 +32,11 @@ public class CashPayRepairStrategy extends AbsPayRepairStrategy {
}
/**
* 取消支付
* 关闭支付
*/
@Override
public void doCloseLocalHandler() {
this.getChannelOrder().setStatus(PayStatusEnum.CLOSE.getCode());
cashRecordService.payClose(this.getChannelOrder());
}
}

View File

@@ -2,8 +2,13 @@ package cn.bootx.platform.daxpay.service.core.payment.repair.strategy.pay;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.param.channel.VoucherPayParam;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.Voucher;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherPayService;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherQueryService;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherRecordService;
import cn.bootx.platform.daxpay.service.func.AbsPayRepairStrategy;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
@@ -23,6 +28,12 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
public class VoucherPayRepairStrategy extends AbsPayRepairStrategy {
private final VoucherPayService voucherPayService;
private final VoucherRecordService voucherRecordService;
private final VoucherQueryService voucherQueryService;
private Voucher voucher;
/**
* 策略标识
@@ -32,12 +43,24 @@ public class VoucherPayRepairStrategy extends AbsPayRepairStrategy {
return PayChannelEnum.VOUCHER;
}
/**
* 取消支付
* 关闭前的处理方式
*/
@Override
public void doBeforeHandler() {
String channelExtra = this.getChannelOrder().getChannelExtra();
VoucherPayParam params = JSONUtil.toBean(channelExtra, VoucherPayParam.class);
this.voucher = voucherQueryService.getVoucherByCardNo(params.getCardNo());
}
/**
* 关闭本地支付订单
*/
@Override
public void doCloseLocalHandler() {
voucherPayService.close(this.getChannelOrder());
voucherRecordService.payClose(this.getChannelOrder(), this.voucher);
this.getChannelOrder().setStatus(PayStatusEnum.CLOSE.getCode());
}
}

View File

@@ -2,8 +2,13 @@ package cn.bootx.platform.daxpay.service.core.payment.repair.strategy.pay;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.param.channel.WalletPayParam;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.Wallet;
import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletPayService;
import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletQueryService;
import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletRecordService;
import cn.bootx.platform.daxpay.service.func.AbsPayRepairStrategy;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
@@ -24,6 +29,12 @@ public class WalletPayRepairStrategy extends AbsPayRepairStrategy {
private final WalletPayService walletPayService;
private final WalletQueryService walletQueryService;
private final WalletRecordService walletRecordService;
private Wallet wallet;
/**
* 策略标识
@@ -34,11 +45,23 @@ public class WalletPayRepairStrategy extends AbsPayRepairStrategy {
}
/**
* 取消支付
* 修复前处理
*/
@Override
public void doBeforeHandler() {
// 从通道扩展参数中取出钱包参数
String channelExtra = this.getChannelOrder().getChannelExtra();
WalletPayParam walletPayParam = JSONUtil.toBean(channelExtra, WalletPayParam.class);
this.wallet = walletQueryService.getWallet(walletPayParam);
}
/**
* 关闭支付, 将订单的金额退还到钱包中
*/
@Override
public void doCloseLocalHandler() {
walletPayService.close(this.getChannelOrder());
walletPayService.close(this.getChannelOrder(),this.wallet);
walletRecordService.payClose(this.getChannelOrder(),this.wallet);
this.getChannelOrder().setStatus(PayStatusEnum.CLOSE.getCode());
}
}

View File

@@ -1,6 +1,7 @@
package cn.bootx.platform.daxpay.service.core.payment.repair.strategy.refund;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.service.core.channel.cash.service.CashRecordService;
import cn.bootx.platform.daxpay.service.func.AbsRefundRepairStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -10,7 +11,7 @@ import org.springframework.stereotype.Service;
import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;
/**
*
* 现金退款修复策略
* @author xxm
* @since 2024/1/30
*/
@@ -19,6 +20,8 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@Service
@RequiredArgsConstructor
public class CashRefundRepairStrategy extends AbsRefundRepairStrategy {
private final CashRecordService cashRecordService;
/**
* 策略标识
*/
@@ -26,4 +29,12 @@ public class CashRefundRepairStrategy extends AbsRefundRepairStrategy {
public PayChannelEnum getChannel() {
return PayChannelEnum.CASH;
}
/**
* 退款成功修复
*/
@Override
public void doSuccessHandler() {
cashRecordService.refund(this.getRefundChannelOrder());
}
}

View File

@@ -1,7 +1,13 @@
package cn.bootx.platform.daxpay.service.core.payment.repair.strategy.refund;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.param.channel.VoucherPayParam;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.Voucher;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherPayService;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherQueryService;
import cn.bootx.platform.daxpay.service.core.channel.voucher.service.VoucherRecordService;
import cn.bootx.platform.daxpay.service.func.AbsRefundRepairStrategy;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
@@ -19,6 +25,14 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@Service
@RequiredArgsConstructor
public class VoucherRefundRepairStrategy extends AbsRefundRepairStrategy {
private final VoucherQueryService voucherQueryService;
private final VoucherRecordService voucherRecordService;
private final VoucherPayService voucherPayService;
private Voucher voucher;
/**
* 策略标识
*/
@@ -26,4 +40,23 @@ public class VoucherRefundRepairStrategy extends AbsRefundRepairStrategy {
public PayChannelEnum getChannel() {
return PayChannelEnum.VOUCHER;
}
/**
* 修复前处理
*/
@Override
public void doBeforeHandler() {
String channelExtra = this.getPayChannelOrder().getChannelExtra();
VoucherPayParam params = JSONUtil.toBean(channelExtra, VoucherPayParam.class);
this.voucher = voucherQueryService.getVoucherByCardNo(params.getCardNo());
}
/**
* 退款成功修复
*/
@Override
public void doSuccessHandler() {
voucherPayService.refund(this.getPayChannelOrder().getAmount(), this.voucher);
voucherRecordService.refund(this.getRefundChannelOrder(), this.voucher);
}
}

View File

@@ -1,16 +1,28 @@
package cn.bootx.platform.daxpay.service.core.payment.repair.strategy.refund;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.code.RefundStatusEnum;
import cn.bootx.platform.daxpay.param.channel.WalletPayParam;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.Wallet;
import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletPayService;
import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletQueryService;
import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletRecordService;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
import cn.bootx.platform.daxpay.service.core.order.refund.entity.PayRefundChannelOrder;
import cn.bootx.platform.daxpay.service.func.AbsRefundRepairStrategy;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import java.util.Objects;
import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;
/**
*
* 钱包退款订单修复策略
* @author xxm
* @since 2024/1/30
*/
@@ -19,6 +31,15 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@Service
@RequiredArgsConstructor
public class WalletRefundRepairStrategy extends AbsRefundRepairStrategy {
private final WalletPayService walletPayService;
private final WalletRecordService walletRecordService;
private final WalletQueryService walletQueryService;
private Wallet wallet;
/**
* 策略标识
*/
@@ -26,4 +47,36 @@ public class WalletRefundRepairStrategy extends AbsRefundRepairStrategy {
public PayChannelEnum getChannel() {
return PayChannelEnum.WALLET;
}
/**
* 修复前处理
*/
@Override
public void doBeforeHandler() {
// 从通道扩展参数中取出钱包参数
String channelExtra = this.getPayChannelOrder().getChannelExtra();
WalletPayParam walletPayParam = JSONUtil.toBean(channelExtra, WalletPayParam.class);
this.wallet = walletQueryService.getWallet(walletPayParam);
}
/**
* 退款成功修复, 只有异步支付的退款才会执行到这
*/
@Override
public void doSuccessHandler() {
PayChannelOrder payChannelOrder = this.getPayChannelOrder();
PayRefundChannelOrder refundChannelOrder = this.getRefundChannelOrder();
// 判断是全部退款还是部分退款
if (Objects.equals(payChannelOrder.getRefundableBalance(), 0)){
//全部退款
payChannelOrder.setStatus(PayStatusEnum.REFUNDED.getCode());
} else {
// 部分退款
payChannelOrder.setStatus(PayStatusEnum.PARTIAL_REFUND.getCode());
}
refundChannelOrder.setStatus(RefundStatusEnum.SUCCESS.getCode());
// 退款真正执行和保存
walletPayService.refund(this.wallet, this.getRefundChannelOrder().getAmount());
walletRecordService.refund(this.getRefundChannelOrder(), this.wallet);
}
}

View File

@@ -21,7 +21,6 @@ import java.time.LocalDateTime;
@Setter
public abstract class AbsPayStrategy implements PayStrategy{
/** 支付订单 */
private PayOrder order = null;

View File

@@ -11,7 +11,7 @@ import lombok.Getter;
import java.util.Objects;
/**
* 支付退款修复策略
* 支付退款修复策略, 只要异步支付订单的退款才会有修复选项
* @author xxm
* @since 2024/1/25
*/
@@ -22,6 +22,12 @@ public abstract class AbsRefundRepairStrategy implements PayStrategy{
private PayOrder payOrder;
private PayChannelOrder payChannelOrder;
/**
* 修复前处理
*/
public void doBeforeHandler() {
}
/**
* 初始化参数
*/
@@ -35,7 +41,6 @@ public abstract class AbsRefundRepairStrategy implements PayStrategy{
this.payChannelOrder = payChannelOrder;
}
/**
* 退款成功修复
*/
@@ -43,15 +48,15 @@ public abstract class AbsRefundRepairStrategy implements PayStrategy{
PayChannelOrder payChannelOrder = this.getPayChannelOrder();
PayRefundChannelOrder refundChannelOrder = this.getRefundChannelOrder();
// 判断是全部退款还是部分退款
// 判断是全部退款还是部分退款, 更新订单状态
if (Objects.equals(payChannelOrder.getRefundableBalance(), 0)){
//全部退款
payChannelOrder.setStatus(PayStatusEnum.REFUNDED.getCode());
} else {
// 部分退款
payChannelOrder.setStatus(PayStatusEnum.PARTIAL_REFUND.getCode());
}
// 退款订单状态
refundChannelOrder.setStatus(RefundStatusEnum.SUCCESS.getCode());
}
@@ -63,18 +68,16 @@ public abstract class AbsRefundRepairStrategy implements PayStrategy{
PayRefundChannelOrder refundChannelOrder = this.getRefundChannelOrder();
int refundableBalance = payChannelOrder.getRefundableBalance() + payChannelOrder.getAmount();
payChannelOrder.setRefundableBalance(refundableBalance);
// 判断是支付完成还是部分退款
// 判断是支付完成还是部分退款, 修改支付订单状态
if (Objects.equals(payChannelOrder.getRefundableBalance(), payChannelOrder.getAmount())){
// 全部退款
payChannelOrder.setStatus(PayStatusEnum.SUCCESS.getCode());
} else {
// 部分退款
payChannelOrder.setStatus(PayStatusEnum.PARTIAL_REFUND.getCode());
}
// 如果失败, 可退余额设置为null
refundChannelOrder.setRefundableAmount(null);
refundChannelOrder.setStatus(RefundStatusEnum.CLOSE.getCode());
refundChannelOrder.setRefundableAmount(null).setStatus(RefundStatusEnum.CLOSE.getCode());
}
}

View File

@@ -72,19 +72,21 @@ public abstract class AbsRefundStrategy implements PayStrategy{
public abstract void doRefundHandler();
/**
* 退款发起成功操作, 异步支付通道需要进行重写
* 退款发起成功操作
*/
public void doSuccessHandler() {
// 更新退款订单数据状态和完成时间
this.refundChannelOrder
.setStatus(RefundStatusEnum.SUCCESS.getCode()).
setRefundTime(LocalDateTime.now());
this.getRefundChannelOrder()
.setStatus(RefundStatusEnum.SUCCESS.getCode())
.setRefundTime(LocalDateTime.now());
// 支付通道订单可退余额
int refundableBalance = this.getPayChannelOrder().getRefundableBalance() - this.refundChannelOrder.getAmount();
int refundableBalance = this.getPayChannelOrder()
.getRefundableBalance() - this.getRefundChannelOrder().getAmount();
// 如果可退金额为0说明已经全部退款
PayStatusEnum status = refundableBalance == 0 ? PayStatusEnum.REFUNDED : PayStatusEnum.PARTIAL_REFUND;
this.payChannelOrder.setRefundableBalance(refundableBalance)
this.getPayChannelOrder()
.setRefundableBalance(refundableBalance)
.setStatus(status.getCode());
}