feat 开放接口新增查询类接口, 支付相关接口联调问题修改

This commit is contained in:
xxm1995
2024-01-16 16:07:53 +08:00
parent ca10f1b1f8
commit 9b541302f2
47 changed files with 514 additions and 151 deletions

View File

@@ -15,8 +15,11 @@ import java.time.LocalDateTime;
@Accessors(chain = true)
public class AsyncPayLocal {
/** 异步支付方式 */
private PayWayEnum payWay;
/**
* 异步支付方式
* @see PayWayEnum
*/
private String payWay;
/**
* 第三方支付平台订单号

View File

@@ -12,8 +12,8 @@ import lombok.experimental.Accessors;
@Accessors(chain = true)
public class AsyncRefundLocal {
/** 退款 */
private String refundNo;
/** 退款请求号(调用支付网关时用的) */
private String refundRequestNo;
/** 错误码 */
private String errorCode;

View File

@@ -20,8 +20,6 @@ import java.time.LocalDateTime;
@Accessors(chain = true)
public class BasePayOrder extends MpIdEntity {
/** 交易记录ID */
@DbColumn(comment = "交易记录ID")
@DbMySqlIndex(comment = "交易记录ID")

View File

@@ -1,25 +0,0 @@
package cn.bootx.platform.daxpay.service.common.entity;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 可退款信息(不持久化,直接保存为json)
* @author xxm
* @since 2023/12/18
*/
@Data
@Accessors(chain = true)
public class RefundableInfo {
/**
* 通道
* @see PayChannelEnum#getCode()
*/
private String channel;
/**
* 可退款金额
*/
private Integer amount;
}

View File

@@ -1,7 +1,7 @@
package cn.bootx.platform.daxpay.service.common.typehandler;
import cn.bootx.platform.common.mybatisplus.handler.JacksonTypeReferenceHandler;
import cn.bootx.platform.daxpay.service.common.entity.RefundableInfo;
import cn.bootx.platform.daxpay.entity.RefundableInfo;
import com.fasterxml.jackson.core.type.TypeReference;
import java.util.List;

View File

@@ -2,7 +2,7 @@ package cn.bootx.platform.daxpay.service.core.channel.alipay.service;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.service.common.entity.RefundableInfo;
import cn.bootx.platform.daxpay.entity.RefundableInfo;
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.service.core.channel.alipay.dao.AliPayOrderManager;
import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayOrder;
@@ -76,7 +76,7 @@ public class AliPayOrderService {
AliPayOrder aliPayOrder = new AliPayOrder();
aliPayOrder.setTradeNo(tradeNo)
.setPayWay(PaymentContextLocal.get().getAsyncPayInfo().getPayWay().getCode())
.setPayWay(PaymentContextLocal.get().getAsyncPayInfo().getPayWay())
.setPaymentId(payOrder.getId())
.setAmount(amount)
.setRefundableBalance(amount)

View File

@@ -38,8 +38,8 @@ public class AliPayRefundService {
// 设置退款信息
AsyncRefundLocal refundInfo = PaymentContextLocal.get().getAsyncRefundInfo();
refundInfo.setRefundNo(PayUtil.getRefundNo());
refundModel.setOutRequestNo(refundInfo.getRefundNo());
refundInfo.setRefundRequestNo(PayUtil.getRefundNo());
refundModel.setOutRequestNo(refundInfo.getRefundRequestNo());
try {
AlipayTradeRefundResponse response = AliPayApi.tradeRefundToResponse(refundModel);
if (!Objects.equals(AliPayCode.SUCCESS, response.getCode())) {

View File

@@ -3,7 +3,7 @@ package cn.bootx.platform.daxpay.service.core.channel.wechat.service;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.service.common.context.AsyncPayLocal;
import cn.bootx.platform.daxpay.service.common.entity.RefundableInfo;
import cn.bootx.platform.daxpay.entity.RefundableInfo;
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.service.core.channel.wechat.dao.WeChatPayOrderManager;
import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayOrder;
@@ -77,7 +77,7 @@ public class WeChatPayOrderService {
// 创建微信支付记录
WeChatPayOrder wechatPayOrder = new WeChatPayOrder();
wechatPayOrder.setTradeNo(tradeNo)
.setPayWay(PaymentContextLocal.get().getAsyncPayInfo().getPayWay().getCode())
.setPayWay(PaymentContextLocal.get().getAsyncPayInfo().getPayWay())
.setPaymentId(payOrder.getId())
.setAmount(amount)
.setRefundableBalance(amount)

View File

@@ -48,13 +48,13 @@ public class WechatRefundService {
String totalFee = String.valueOf(orderChannel.getAmount());
// 设置退款信息
AsyncRefundLocal refundInfo = PaymentContextLocal.get().getAsyncRefundInfo();
refundInfo.setRefundNo(PayUtil.getRefundNo());
refundInfo.setRefundRequestNo(PayUtil.getRefundNo());
Map<String, String> params = RefundModel.builder()
.appid(weChatPayConfig.getWxAppId())
.mch_id(weChatPayConfig.getWxMchId())
.out_trade_no(String.valueOf(payOrder.getId()))
.out_refund_no(refundInfo.getRefundNo())
.out_refund_no(refundInfo.getRefundRequestNo())
.total_fee(totalFee)
.refund_fee(refundFee)
.nonce_str(WxPayKit.generateStr())

View File

@@ -9,7 +9,7 @@ import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderChannel;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra;
import cn.bootx.platform.daxpay.service.common.entity.RefundableInfo;
import cn.bootx.platform.daxpay.entity.RefundableInfo;
import cn.bootx.platform.daxpay.param.pay.PayParam;
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
import cn.bootx.platform.daxpay.result.pay.PayResult;

View File

@@ -1,5 +1,6 @@
package cn.bootx.platform.daxpay.service.core.order.pay.convert;
import cn.bootx.platform.daxpay.result.order.PayOrderChannelResult;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderChannel;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra;
@@ -23,4 +24,6 @@ public interface PayOrderConvert {
PayOrderDto convert(PayOrder in);
PayOrderChannelDto convert(PayOrderChannel in);
PayOrderChannelResult convertResult(PayOrderChannel in);
}

View File

@@ -5,7 +5,7 @@ import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.service.common.entity.RefundableInfo;
import cn.bootx.platform.daxpay.entity.RefundableInfo;
import cn.bootx.platform.daxpay.service.common.typehandler.RefundableInfoTypeHandler;
import cn.bootx.platform.daxpay.service.core.order.pay.convert.PayOrderConvert;
import cn.bootx.platform.daxpay.service.dto.order.pay.PayOrderDto;

View File

@@ -0,0 +1,106 @@
package cn.bootx.platform.daxpay.service.core.order.pay.service;
import cn.bootx.platform.common.core.exception.DataNotExistException;
import cn.bootx.platform.common.core.exception.ValidationFailedException;
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.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.param.pay.QueryPayParam;
import cn.bootx.platform.daxpay.result.order.PayOrderChannelResult;
import cn.bootx.platform.daxpay.result.order.PayOrderResult;
import cn.bootx.platform.daxpay.service.core.order.pay.convert.PayOrderConvert;
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderChannelManager;
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderExtraManager;
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderManager;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderChannel;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra;
import cn.bootx.platform.daxpay.service.dto.order.pay.PayOrderDto;
import cn.bootx.platform.daxpay.service.param.order.PayOrderQuery;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* 支付查询服务
* @author xxm
* @since 2024/1/16
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class PayOrderQueryService {
private final PayOrderManager payOrderManager;
private final PayOrderExtraManager payOrderExtraManager;
private final PayOrderChannelManager payOrderChannelManager;
/**
* 分页
*/
public PageResult<PayOrderDto> page(PageParam pageParam, PayOrderQuery param) {
Page<PayOrder> page = payOrderManager.page(pageParam, param);
return MpUtil.convert2DtoPageResult(page);
}
/**
* 根据id查询
*/
public Optional<PayOrder> findById(Long paymentId) {
return payOrderManager.findById(paymentId);
}
/**
* 根据业务号查询
*/
public Optional<PayOrder> findByBusinessNo(String businessNo) {
return payOrderManager.findByBusinessNo(businessNo);
}
/**
* 查询支付记录
*/
public PayOrderResult queryPayOrder(QueryPayParam param) {
// 校验参数
if (StrUtil.isBlank(param.getBusinessNo()) && Objects.isNull(param.getPaymentId())){
throw new ValidationFailedException("业务号或支付单ID不能都为空");
}
// 查询支付单
PayOrder payOrder = null;
if (Objects.nonNull(param.getPaymentId())){
payOrder = payOrderManager.findById(param.getPaymentId())
.orElseThrow(() -> new DataNotExistException("未查询到支付订单"));
}
if (Objects.isNull(payOrder)){
payOrder = payOrderManager.findByBusinessNo(param.getBusinessNo())
.orElseThrow(() -> new DataNotExistException("未查询到支付订单"));
}
// 查询扩展数据
PayOrderExtra payOrderExtra = payOrderExtraManager.findById(payOrder.getId())
.orElseThrow(() -> new PayFailureException("支付订单不完整"));
// 查询通道数据
List<PayOrderChannel> orderChannelList = payOrderChannelManager.findAllByPaymentId(payOrder.getId());
List<PayOrderChannelResult> channels = orderChannelList.stream()
.map(PayOrderConvert.CONVERT::convertResult)
.collect(Collectors.toList());
PayOrderResult payOrderResult = new PayOrderResult();
BeanUtil.copyProperties(payOrder, payOrderResult);
payOrderResult.setDescription(payOrderExtra.getDescription())
.setChannels(channels);
return payOrderResult;
}
}

View File

@@ -1,18 +1,12 @@
package cn.bootx.platform.daxpay.service.core.order.pay.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.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.service.common.entity.RefundableInfo;
import cn.bootx.platform.daxpay.entity.RefundableInfo;
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderManager;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.timeout.service.PayExpiredTimeService;
import cn.bootx.platform.daxpay.service.dto.order.pay.PayOrderDto;
import cn.bootx.platform.daxpay.service.param.order.PayOrderQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -20,7 +14,6 @@ import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
/**
* 支付订单服务
@@ -38,27 +31,6 @@ public class PayOrderService {
// 支付完成常量集合
private final List<String> ORDER_FINISH = Arrays.asList(PayStatusEnum.CLOSE.getCode(), PayStatusEnum.SUCCESS.getCode());
/**
* 根据id查询
*/
public PageResult<PayOrderDto> page(PageParam pageParam, PayOrderQuery param) {
Page<PayOrder> page = payOrderManager.page(pageParam, param);
return MpUtil.convert2DtoPageResult(page);
}
/**
* 根据id查询
*/
public Optional<PayOrder> findById(Long paymentId) {
return payOrderManager.findById(paymentId);
}
/**
* 根据业务号查询
*/
public Optional<PayOrder> findByBusinessNo(String businessNo) {
return payOrderManager.findByBusinessNo(businessNo);
}
/**
* 新增

View File

@@ -1,5 +1,6 @@
package cn.bootx.platform.daxpay.service.core.order.refund.convert;
import cn.bootx.platform.daxpay.result.order.RefundOrderResult;
import cn.bootx.platform.daxpay.service.core.order.refund.entity.PayRefundOrder;
import cn.bootx.platform.daxpay.service.dto.order.refund.PayRefundOrderDto;
import org.mapstruct.Mapper;
@@ -10,10 +11,12 @@ import org.mapstruct.factory.Mappers;
* @since 2022/3/2
*/
@Mapper
public interface RefundConvert {
public interface PayRefundConvert {
RefundConvert CONVERT = Mappers.getMapper(RefundConvert.class);
PayRefundConvert CONVERT = Mappers.getMapper(PayRefundConvert.class);
PayRefundOrderDto convert(PayRefundOrder in);
RefundOrderResult convertResult(PayRefundOrder in);
}

View File

@@ -12,6 +12,8 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import java.util.Optional;
/**
* 支付退款订单管理
* @author xxm
@@ -28,10 +30,20 @@ public class PayRefundOrderManager extends BaseManager<PayRefundOrderMapper, Pay
public Page<PayRefundOrder> page(PageParam pageParam, PayRefundOrderQuery query) {
Page<PayRefundOrder> mpPage = MpUtil.getMpPage(pageParam, PayRefundOrder.class);
QueryWrapper<PayRefundOrder> generator = QueryGenerator.generator(query);
// if (Objects.nonNull(query.getSortField())){
// generator.orderBy(true, query.getAsc(), NamingCase.toUnderlineCase(query.getSortField()));
// }
return page(mpPage,generator);
}
/**
* 根据退款号查询
*/
public Optional<PayRefundOrder> findByRefundNo(String refundNo) {
return findByField(PayRefundOrder::getRefundNo, refundNo);
}
/**
* 查询支付号是否重复
*/
public boolean existsByRefundNo(String refundNo){
return this.existedByField(PayRefundOrder::getRefundNo,refundNo);
}
}

View File

@@ -3,9 +3,9 @@ package cn.bootx.platform.daxpay.service.core.order.refund.entity;
import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
import cn.bootx.platform.daxpay.code.PayRefundStatusEnum;
import cn.bootx.platform.daxpay.service.common.entity.RefundableInfo;
import cn.bootx.platform.daxpay.entity.RefundableInfo;
import cn.bootx.platform.daxpay.service.common.typehandler.RefundableInfoTypeHandler;
import cn.bootx.platform.daxpay.service.core.order.refund.convert.RefundConvert;
import cn.bootx.platform.daxpay.service.core.order.refund.convert.PayRefundConvert;
import cn.bootx.platform.daxpay.service.dto.order.refund.PayRefundOrderDto;
import cn.bootx.table.modify.annotation.DbColumn;
import cn.bootx.table.modify.annotation.DbTable;
@@ -33,14 +33,20 @@ import java.util.List;
@TableName(value = "pay_refund_order", autoResultMap = true)
public class PayRefundOrder extends MpBaseEntity implements EntityBaseFunction<PayRefundOrderDto> {
/** 支付id */
@DbColumn(comment = "支付id")
/** 关联支付id */
@DbColumn(comment = "关联支付id")
private Long paymentId;
/** 业务号 */
@DbColumn(comment = "业务号")
/** 关联业务号 */
@DbColumn(comment = "关联业务号")
private String businessNo;
/**
* 需要保证全局唯一
*/
@DbColumn(comment = "退款号")
private String refundNo;
/** 异步方式关联退款请求号(部分退款情况) */
@DbColumn(comment = "异步方式关联退款请求号(部分退款情况)")
private String refundRequestNo;
@@ -98,7 +104,7 @@ public class PayRefundOrder extends MpBaseEntity implements EntityBaseFunction<P
@Override
public PayRefundOrderDto toDto() {
return RefundConvert.CONVERT.convert(this);
return PayRefundConvert.CONVERT.convert(this);
}
}

View File

@@ -1,18 +1,25 @@
package cn.bootx.platform.daxpay.service.core.order.refund.service;
import cn.bootx.platform.common.core.exception.DataNotExistException;
import cn.bootx.platform.common.core.exception.ValidationFailedException;
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.param.pay.QueryRefundParam;
import cn.bootx.platform.daxpay.result.order.RefundOrderResult;
import cn.bootx.platform.daxpay.service.core.order.refund.convert.PayRefundConvert;
import cn.bootx.platform.daxpay.service.core.order.refund.dao.PayRefundOrderManager;
import cn.bootx.platform.daxpay.service.core.order.refund.entity.PayRefundOrder;
import cn.bootx.platform.daxpay.service.dto.order.refund.PayRefundOrderDto;
import cn.bootx.platform.daxpay.service.param.order.PayRefundOrderQuery;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Objects;
/**
* 退款
*
@@ -24,13 +31,13 @@ import org.springframework.stereotype.Service;
@RequiredArgsConstructor
public class PayRefundOrderService {
private final PayRefundOrderManager refundRecordManager;
private final PayRefundOrderManager refundOrderManager;
/**
* 分页查询
*/
public PageResult<PayRefundOrderDto> page(PageParam pageParam, PayRefundOrderQuery query) {
Page<PayRefundOrder> page = refundRecordManager.page(pageParam, query);
Page<PayRefundOrder> page = refundOrderManager.page(pageParam, query);
return MpUtil.convert2DtoPageResult(page);
}
@@ -38,7 +45,28 @@ public class PayRefundOrderService {
* 根据id查询
*/
public PayRefundOrderDto findById(Long id) {
return refundRecordManager.findById(id).map(PayRefundOrder::toDto).orElseThrow(DataNotExistException::new);
return refundOrderManager.findById(id).map(PayRefundOrder::toDto).orElseThrow(DataNotExistException::new);
}
/**
* 查询退款订单
*/
public RefundOrderResult queryRefundOrder(QueryRefundParam param) {
// 校验参数
if (StrUtil.isBlank(param.getRefundNo()) && Objects.isNull(param.getRefundId())){
throw new ValidationFailedException("退款号或退款ID不能都为空");
}
// 查询支付单
PayRefundOrder refundOrder = null;
if (Objects.nonNull(param.getRefundId())){
refundOrder = refundOrderManager.findById(param.getRefundId())
.orElseThrow(() -> new DataNotExistException("未查询到支付订单"));
}
if (Objects.isNull(refundOrder)){
refundOrder = refundOrderManager.findByRefundNo(param.getRefundNo())
.orElseThrow(() -> new DataNotExistException("未查询到支付订单"));
}
return PayRefundConvert.CONVERT.convertResult(refundOrder);
}
}

View File

@@ -1,15 +1,15 @@
package cn.bootx.platform.daxpay.service.core.payment.callback.service;
import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.service.code.PayCallbackStatusEnum;
import cn.bootx.platform.daxpay.service.code.PayRepairSourceEnum;
import cn.bootx.platform.daxpay.service.code.PayRepairTypeEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderQueryService;
import cn.bootx.platform.daxpay.service.core.payment.callback.result.PayCallbackResult;
import cn.bootx.platform.daxpay.service.core.payment.repair.param.PayRepairParam;
import cn.bootx.platform.daxpay.service.core.payment.repair.service.PayRepairService;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -28,7 +28,7 @@ import java.util.Objects;
@RequiredArgsConstructor
public class PayCallbackService {
private final PayOrderService payOrderService;
private final PayOrderQueryService payOrderQueryService;
private final PayRepairService payRepairService;
@@ -39,7 +39,7 @@ public class PayCallbackService {
public PayCallbackResult callback(Long paymentId, String tradeStatus) {
// 获取支付单
PayOrder payOrder = payOrderService.findById(paymentId).orElse(null);
PayOrder payOrder = payOrderQueryService.findById(paymentId).orElse(null);
// 支付单不存在,记录回调记录, TODO 取消支付网关的订单支付情况
if (Objects.isNull(payOrder)) {

View File

@@ -5,8 +5,9 @@ import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.exception.pay.PayUnsupportedMethodException;
import cn.bootx.platform.daxpay.param.pay.PayCloseParam;
import cn.bootx.platform.daxpay.service.common.entity.RefundableInfo;
import cn.bootx.platform.daxpay.entity.RefundableInfo;
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderQueryService;
import cn.bootx.platform.daxpay.service.core.payment.close.factory.PayCloseStrategyFactory;
import cn.bootx.platform.daxpay.service.core.record.close.entity.PayCloseRecord;
import cn.bootx.platform.daxpay.service.core.record.close.service.PayCloseRecordService;
@@ -35,6 +36,7 @@ import java.util.stream.Collectors;
@RequiredArgsConstructor
public class PayCloseService {
private final PayOrderService payOrderService;
private final PayOrderQueryService payOrderQueryService;
private final PayCloseRecordService payCloseRecordService;
private final LockTemplate lockTemplate;
@@ -46,11 +48,11 @@ public class PayCloseService {
public void close(PayCloseParam param){
PayOrder payOrder = null;
if (Objects.nonNull(param.getPaymentId())){
payOrder = payOrderService.findById(param.getPaymentId())
payOrder = payOrderQueryService.findById(param.getPaymentId())
.orElseThrow(() -> new PayFailureException("未查询到支付订单"));
}
if (Objects.isNull(payOrder)){
payOrder = payOrderService.findByBusinessNo(param.getBusinessNo())
payOrder = payOrderQueryService.findByBusinessNo(param.getBusinessNo())
.orElseThrow(() -> new PayFailureException("未查询到支付订单"));
}
LockInfo lock = lockTemplate.lock("payment:close:" + payOrder.getId());

View File

@@ -11,6 +11,7 @@ import cn.bootx.platform.daxpay.service.common.context.AsyncPayLocal;
import cn.bootx.platform.daxpay.service.common.context.NoticeLocal;
import cn.bootx.platform.daxpay.service.common.context.PlatformLocal;
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderQueryService;
import cn.bootx.platform.daxpay.service.core.payment.sync.service.PaySyncService;
import cn.bootx.platform.daxpay.service.core.order.pay.builder.PaymentBuilder;
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderChannelManager;
@@ -44,7 +45,11 @@ public class PayAssistService {
private final PaySyncService paySyncService;
private final PayOrderService payOrderService;
private final PayOrderQueryService payOrderQueryService;
private final PayOrderExtraManager payOrderExtraManager;
private final PayOrderChannelManager payOrderChannelManager;
/**
@@ -170,7 +175,7 @@ public class PayAssistService {
*/
public PayOrder getOrderAndCheck(String businessNo) {
// 根据订单查询支付记录
PayOrder payOrder = payOrderService.findByBusinessNo(businessNo).orElse(null);
PayOrder payOrder = payOrderQueryService.findByBusinessNo(businessNo).orElse(null);
if (Objects.nonNull(payOrder)) {
// 待支付
if (Objects.equals(payOrder.getStatus(), PayStatusEnum.PROGRESS.getCode())){

View File

@@ -4,17 +4,18 @@ import cn.bootx.platform.common.core.exception.ValidationFailedException;
import cn.bootx.platform.common.core.util.CollUtil;
import cn.bootx.platform.daxpay.code.PayRefundStatusEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.param.pay.RefundChannelParam;
import cn.bootx.platform.daxpay.param.pay.RefundParam;
import cn.bootx.platform.daxpay.service.common.context.AsyncRefundLocal;
import cn.bootx.platform.daxpay.service.common.context.NoticeLocal;
import cn.bootx.platform.daxpay.service.common.context.PlatformLocal;
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderQueryService;
import cn.bootx.platform.daxpay.service.core.order.refund.dao.PayRefundOrderManager;
import cn.bootx.platform.daxpay.service.core.order.refund.entity.PayRefundOrder;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.param.pay.RefundChannelParam;
import cn.bootx.platform.daxpay.param.pay.RefundParam;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -36,7 +37,7 @@ import java.util.Objects;
@Service
@RequiredArgsConstructor
public class PayRefundAssistService {
private final PayOrderService payOrderService;
private final PayOrderQueryService payOrderQueryService;
private final PayRefundOrderManager payRefundOrderManager;
@@ -67,6 +68,7 @@ public class PayRefundAssistService {
* 根据退款参数获取支付订单, 并进行检查
*/
public PayOrder getPayOrderAndCheckByRefundParam(RefundParam param, boolean simple){
// 全额退款和部分退款校验
if (!param.isRefundAll()) {
if (CollUtil.isEmpty(param.getRefundChannels())) {
throw new ValidationFailedException("退款通道参数不能为空");
@@ -75,14 +77,19 @@ public class PayRefundAssistService {
throw new ValidationFailedException("部分退款时退款单号必传");
}
}
// 退款号唯一校验
if (StrUtil.isNotBlank(param.getRefundNo())
&& payRefundOrderManager.existsByRefundNo(param.getRefundNo())){
throw new PayFailureException("退款单号已存在");
}
PayOrder payOrder = null;
if (Objects.nonNull(param.getPaymentId())){
payOrder = payOrderService.findById(param.getPaymentId())
payOrder = payOrderQueryService.findById(param.getPaymentId())
.orElseThrow(() -> new PayFailureException("未查询到支付订单"));
}
if (Objects.isNull(payOrder)){
payOrder = payOrderService.findByBusinessNo(param.getBusinessNo())
payOrder = payOrderQueryService.findByBusinessNo(param.getBusinessNo())
.orElseThrow(() -> new PayFailureException("未查询到支付订单"));
}
@@ -125,18 +132,25 @@ public class PayRefundAssistService {
.reduce(0, Integer::sum);
PayRefundOrder refundOrder = new PayRefundOrder()
.setRefundRequestNo(asyncRefundInfo.getRefundNo())
.setAmount(amount)
.setRefundableBalance(payOrder.getRefundableBalance())
.setPaymentId(payOrder.getId())
.setBusinessNo(payOrder.getBusinessNo())
.setRefundNo(refundParam.getRefundNo())
.setAmount(amount)
.setRefundableBalance(payOrder.getRefundableBalance())
.setRefundRequestNo(asyncRefundInfo.getRefundRequestNo())
.setRefundTime(LocalDateTime.now())
.setTitle(payOrder.getTitle())
.setErrorMsg(asyncRefundInfo.getErrorMsg())
.setErrorCode(asyncRefundInfo.getErrorCode())
.setErrorMsg(asyncRefundInfo.getErrorMsg())
.setStatus(Objects.isNull(asyncRefundInfo.getErrorCode()) ? PayRefundStatusEnum.SUCCESS.getCode() : PayRefundStatusEnum.FAIL.getCode())
.setClientIp(refundParam.getClientIp())
.setReqId(PaymentContextLocal.get().getRequest().getReqId());
// 退款号, 如不传输, 使用ID作为退款号
if(StrUtil.isBlank(refundOrder.getRefundNo())){
long id = IdUtil.getSnowflakeNextId();
refundOrder.setRefundNo(String.valueOf(id))
.setId(id);
}
payRefundOrderManager.save(refundOrder);
}
}

View File

@@ -1,7 +1,7 @@
package cn.bootx.platform.daxpay.service.core.payment.repair.service;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.service.common.entity.RefundableInfo;
import cn.bootx.platform.daxpay.entity.RefundableInfo;
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.service.core.payment.repair.factory.PayRepairStrategyFactory;
import cn.bootx.platform.daxpay.service.core.payment.repair.param.PayRepairParam;

View File

@@ -2,6 +2,7 @@ package cn.bootx.platform.daxpay.service.core.payment.repair.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayConfig;
import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayCloseService;
import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayConfigService;
@@ -47,6 +48,8 @@ public class AliPayRepairStrategy extends AbsPayRepairStrategy {
public void doSuccessHandler() {
PayOrderChannel orderChannel = orderChannelManager.findByPaymentIdAndChannel(this.getOrder().getId(), PayChannelEnum.ALI.getCode())
.orElseThrow(() -> new PayFailureException("支付宝订单不存在"));
// 将支付方式写入上下文
PaymentContextLocal.get().getAsyncPayInfo().setPayWay(orderChannel.getPayWay());
orderService.updateAsyncSuccess(this.getOrder(), orderChannel.getAmount());
}

View File

@@ -11,13 +11,13 @@ import cn.bootx.platform.daxpay.result.pay.PaySyncResult;
import cn.bootx.platform.daxpay.service.code.PayRepairSourceEnum;
import cn.bootx.platform.daxpay.service.code.PayRepairTypeEnum;
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderQueryService;
import cn.bootx.platform.daxpay.service.core.payment.repair.param.PayRepairParam;
import cn.bootx.platform.daxpay.service.core.payment.repair.result.RepairResult;
import cn.bootx.platform.daxpay.service.core.payment.repair.service.PayRepairService;
import cn.bootx.platform.daxpay.service.core.payment.sync.factory.PaySyncStrategyFactory;
import cn.bootx.platform.daxpay.service.core.payment.sync.result.GatewaySyncResult;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService;
import cn.bootx.platform.daxpay.service.core.record.sync.entity.PaySyncRecord;
import cn.bootx.platform.daxpay.service.core.record.sync.service.PaySyncRecordService;
import cn.bootx.platform.daxpay.service.func.AbsPaySyncStrategy;
@@ -46,7 +46,7 @@ import static cn.bootx.platform.daxpay.code.PaySyncStatusEnum.*;
@Service
@RequiredArgsConstructor
public class PaySyncService {
private final PayOrderService payOrderService;
private final PayOrderQueryService payOrderQueryService;
private final PaySyncRecordService paySyncRecordService;
@@ -61,11 +61,11 @@ public class PaySyncService {
public PaySyncResult sync(PaySyncParam param) {
PayOrder payOrder = null;
if (Objects.nonNull(param.getPaymentId())){
payOrder = payOrderService.findById(param.getPaymentId())
payOrder = payOrderQueryService.findById(param.getPaymentId())
.orElseThrow(() -> new PayFailureException("未查询到支付订单"));
}
if (Objects.isNull(payOrder)){
payOrder = payOrderService.findByBusinessNo(param.getBusinessNo())
payOrder = payOrderQueryService.findByBusinessNo(param.getBusinessNo())
.orElseThrow(() -> new PayFailureException("未查询到支付订单"));
}
// 如果不是异步支付, 直接返回返回

View File

@@ -1,11 +1,13 @@
package cn.bootx.platform.daxpay.service.core.system.config.dao;
import cn.bootx.platform.common.mybatisplus.base.MpIdEntity;
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
import cn.bootx.platform.daxpay.service.core.system.config.entity.PayApiConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
/**
@@ -32,4 +34,11 @@ public class PayApiConfigManager extends BaseManager<PayApiConfigMapper, PayApiC
return findByField(PayApiConfig::getApi,api);
}
/**
* 查询全部
*/
@Override
public List<PayApiConfig> findAll() {
return lambdaQuery().orderByDesc(MpIdEntity::getId).list();
}
}

View File

@@ -1,35 +0,0 @@
package cn.bootx.platform.daxpay.service.core.system.config.entity;
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
import cn.bootx.table.modify.annotation.DbTable;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 订单超时配置
* @author xxm
* @since 2024/1/1
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Accessors(chain = true)
@DbTable(comment = "订单超时配置")
@TableName("pay_order_timeout_config")
public class OrderTimeoutConfig extends MpBaseEntity {
/**
* 超时时间
*/
private Integer timeout;
/**
* 是否开启定时任务
*/
private boolean cron;
/**
*
*/
}

View File

@@ -1,7 +1,6 @@
package cn.bootx.platform.daxpay.service.core.system.config.entity;
import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
import cn.bootx.table.modify.annotation.DbTable;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -15,7 +14,7 @@ import lombok.experimental.Accessors;
@EqualsAndHashCode(callSuper = true)
@Data
@Accessors(chain = true)
@DbTable(comment = "支付接口调用记录")
//@DbTable(comment = "支付接口调用记录")
@TableName("pay_api_call_record")
public class PayApiCallRecord extends MpCreateEntity {
}

View File

@@ -1,11 +1,13 @@
package cn.bootx.platform.daxpay.service.core.system.payinfo.dao;
import cn.bootx.platform.common.mybatisplus.base.MpIdEntity;
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
import cn.bootx.platform.daxpay.service.core.system.payinfo.entity.PayChannelInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
/**
@@ -24,4 +26,12 @@ public class PayChannelInfoManager extends BaseManager<PayChannelInfoMapper, Pay
public Optional<PayChannelInfo> findByCode(String code){
return findByField(PayChannelInfo::getCode, code);
}
/**
* 查询全部
*/
@Override
public List<PayChannelInfo> findAll() {
return lambdaQuery().orderByDesc(MpIdEntity::getId).list();
}
}

View File

@@ -3,7 +3,7 @@ package cn.bootx.platform.daxpay.service.dto.order.pay;
import cn.bootx.platform.common.core.rest.dto.BaseDto;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.service.common.entity.RefundableInfo;
import cn.bootx.platform.daxpay.entity.RefundableInfo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -54,10 +54,10 @@ public class PayOrderDto extends BaseDto {
private Integer refundableBalance;
/**
* 退款信息列表
* 退款信息列表
* @see RefundableInfo
*/
@Schema(description = "退款信息列表")
@Schema(description = "退款信息列表")
private List<RefundableInfo> refundableInfos;
/**

View File

@@ -2,7 +2,7 @@ package cn.bootx.platform.daxpay.service.dto.order.refund;
import cn.bootx.platform.common.core.rest.dto.BaseDto;
import cn.bootx.platform.daxpay.code.PayRefundStatusEnum;
import cn.bootx.platform.daxpay.service.common.entity.RefundableInfo;
import cn.bootx.platform.daxpay.entity.RefundableInfo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -24,11 +24,14 @@ import java.util.List;
@Schema(title = "退款记录")
public class PayRefundOrderDto extends BaseDto {
@Schema(description = "支付号")
private Long paymentId;
@Schema(description = "关联的业务id")
private String businessNo;
@Schema(description = "支付")
private Long paymentId;
@Schema(description = "退款")
private String refundNo;
@Schema(description = "异步方式关联退款请求号(部分退款情况)")
private String refundRequestNo;

View File

@@ -1,6 +1,7 @@
package cn.bootx.platform.daxpay.service.dto.system.payinfo;
import cn.bootx.platform.common.core.rest.dto.BaseDto;
import cn.bootx.table.modify.annotation.DbColumn;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -25,6 +26,10 @@ public class PayChannelInfoDto extends BaseDto {
@Schema(description = "名称")
private String name;
/** 是否启用 */
@DbColumn(comment = "是否启用")
private boolean enabled;
/** logo图片 */
@Schema(description = "logo图片")
private Long iconId;