mirror of
https://gitee.com/dromara/dax-pay.git
synced 2025-09-03 19:16:21 +00:00
feat 通知消息功能收尾, 支付订单超时任务改为quartz定时任务方式
This commit is contained in:
@@ -37,15 +37,16 @@ public class PayOrderExtra extends MpBaseEntity implements EntityBaseFunction<Pa
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String returnUrl;
|
||||
|
||||
/** 回调通知时是否需要进行签名, 以最后一次为准 */
|
||||
@DbColumn(comment = "回调通知时是否需要进行签名")
|
||||
private boolean noticeSign;
|
||||
|
||||
/** 异步通知地址 */
|
||||
/** 异步通知地址 以最后一次为准 */
|
||||
@DbColumn(comment = "异步通知地址,以最后一次为准")
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String notifyUrl;
|
||||
|
||||
/** 商户扩展参数,回调时会原样返回 */
|
||||
/** 商户扩展参数,回调时会原样返回 以最后一次为准 */
|
||||
@DbColumn(comment = "商户扩展参数")
|
||||
private String attach;
|
||||
|
||||
@@ -57,24 +58,18 @@ public class PayOrderExtra extends MpBaseEntity implements EntityBaseFunction<Pa
|
||||
@DbColumn(comment = "签名")
|
||||
private String reqSign;
|
||||
|
||||
/** 商户扩展参数,回调时会原样返回 */
|
||||
@DbColumn(comment = "商户扩展参数")
|
||||
private String attach;
|
||||
|
||||
/** 请求时间,时间戳转时间, 以最后一次为准 */
|
||||
@DbColumn(comment = "请求时间,传输时间戳,以最后一次为准")
|
||||
private LocalDateTime reqTime;
|
||||
|
||||
/** 支付终端ip */
|
||||
/** 支付终端ip 以最后一次为准 */
|
||||
@DbColumn(comment = "支付终端ip")
|
||||
private String clientIp;
|
||||
|
||||
|
||||
/** 请求链路ID */
|
||||
/** 请求链路ID 以最后一次为准 */
|
||||
@DbColumn(comment = "请求链路ID")
|
||||
private String reqId;
|
||||
|
||||
|
||||
/** 错误码 */
|
||||
@DbColumn(comment = "错误码")
|
||||
private String errorCode;
|
||||
|
@@ -3,7 +3,7 @@ package cn.bootx.platform.daxpay.service.core.order.pay.service;
|
||||
import cn.bootx.platform.daxpay.code.PayStatusEnum;
|
||||
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.core.payment.pay.service.PayExpiredTimeService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@@ -7,22 +7,24 @@ import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 各支付通道参数
|
||||
* 支付通道信息
|
||||
* @author xxm
|
||||
* @since 2024/1/7
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "各支付通道参数")
|
||||
@Schema(title = "支付通道信息")
|
||||
public class PayChannelResult {
|
||||
/**
|
||||
* 支付通道编码
|
||||
* @see PayChannelEnum#getCode()
|
||||
*/
|
||||
@Schema(description = "支付通道编码")
|
||||
private String channel;
|
||||
|
||||
/**
|
||||
* @see PayWayEnum#getCode()
|
||||
* 支付方式编码
|
||||
* @see PayWayEnum
|
||||
*/
|
||||
@Schema(description = "支付方式编码")
|
||||
private String way;
|
||||
|
@@ -334,7 +334,7 @@ public class ClientNoticeService {
|
||||
task.setSendCount(task.getSendCount() + 1);
|
||||
// 判断发送次数是否未超过15次, 注册任务到redis中
|
||||
if (task.getSendCount() < 16){
|
||||
// 根据当前次数和时间计算出毫秒值
|
||||
// 根据当前次数和时间计算出毫秒值, 然后写入到Redis中
|
||||
Integer delay = DELAY_TIME.get(task.getSendCount());
|
||||
long taskTime = LocalDateTimeUtil.timestamp(now) + delay;
|
||||
redisClient.zadd(KEY, String.valueOf(task.getId()), taskTime);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
package cn.bootx.platform.daxpay.service.core.timeout.dao;
|
||||
package cn.bootx.platform.daxpay.service.core.payment.pay.dao;
|
||||
|
||||
import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
|
||||
import cn.bootx.platform.common.redis.RedisClient;
|
@@ -6,10 +6,7 @@ import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayParam;
|
||||
import cn.bootx.platform.daxpay.service.common.context.ApiInfoLocal;
|
||||
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.context.*;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.builder.PayBuilder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager;
|
||||
@@ -163,6 +160,8 @@ public class PayAssistService {
|
||||
*/
|
||||
public PayOrderExtra updatePayOrderExtra(PayParam payParam,Long paymentId){
|
||||
ApiInfoLocal apiInfo = PaymentContextLocal.get().getApiInfo();
|
||||
RequestLocal requestInfo = PaymentContextLocal.get().getRequestInfo();
|
||||
PlatformLocal platformInfo = PaymentContextLocal.get().getPlatformInfo();
|
||||
PayOrderExtra payOrderExtra = payOrderExtraManager.findById(paymentId)
|
||||
.orElseThrow(() -> new DataNotExistException("支付订单不存在"));
|
||||
|
||||
@@ -172,12 +171,14 @@ public class PayAssistService {
|
||||
String returnUrl = noticeInfo.getReturnUrl();
|
||||
|
||||
payOrderExtra.setReqTime(payParam.getReqTime())
|
||||
.setReqSignType(platformInfo.getSignType())
|
||||
.setReqSign(payParam.getSign())
|
||||
.setNotifyUrl(notifyUrl)
|
||||
.setReturnUrl(returnUrl)
|
||||
.setNoticeSign(apiInfo.isNoticeSign())
|
||||
.setAttach(payParam.getAttach())
|
||||
.setClientIp(payParam.getClientIp());
|
||||
.setClientIp(payParam.getClientIp())
|
||||
.setReqId(requestInfo.getReqId());
|
||||
return payOrderExtraManager.updateById(payOrderExtra);
|
||||
}
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
package cn.bootx.platform.daxpay.service.core.timeout.service;
|
||||
package cn.bootx.platform.daxpay.service.core.payment.pay.service;
|
||||
|
||||
import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
|
||||
import cn.bootx.platform.common.spring.exception.RetryableException;
|
||||
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.timeout.dao.PayExpiredTimeRepository;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.pay.dao.PayExpiredTimeRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.retry.annotation.Retryable;
|
@@ -1,9 +1,9 @@
|
||||
package cn.bootx.platform.daxpay.service.core.timeout.task;
|
||||
package cn.bootx.platform.daxpay.service.core.payment.pay.task;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.RepetitiveOperationException;
|
||||
import cn.bootx.platform.daxpay.param.pay.PaySyncParam;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.pay.dao.PayExpiredTimeRepository;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.sync.service.PaySyncService;
|
||||
import cn.bootx.platform.daxpay.service.core.timeout.dao.PayExpiredTimeRepository;
|
||||
import com.baomidou.lock.LockInfo;
|
||||
import com.baomidou.lock.LockTemplate;
|
||||
import lombok.RequiredArgsConstructor;
|
@@ -186,6 +186,7 @@ public class RefundAssistService {
|
||||
|
||||
RefundOrderExtra refundOrderExtra = this.createRefundOrderExtra(refundParam, refundOrder.getId());
|
||||
refundChannelOrders.forEach(r->r.setRefundId(refundOrder.getId()));
|
||||
refundOrderExtraManager.save(refundOrderExtra);
|
||||
payRefundChannelOrderManager.saveAll(refundChannelOrders);
|
||||
return refundOrderManager.save(refundOrder);
|
||||
}
|
||||
|
@@ -7,7 +7,6 @@ import cn.bootx.platform.daxpay.service.code.PayRepairWayEnum;
|
||||
import cn.bootx.platform.daxpay.service.code.PaymentTypeEnum;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderExtraManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService;
|
||||
@@ -49,8 +48,6 @@ public class PayRepairService {
|
||||
|
||||
private final PayRepairRecordService recordService;
|
||||
|
||||
private final PayOrderExtraManager payOrderExtraManager;
|
||||
|
||||
/**
|
||||
* 修复支付单
|
||||
*/
|
||||
@@ -96,6 +93,12 @@ public class PayRepairService {
|
||||
}
|
||||
// 设置修复iD
|
||||
repairResult.setRepairNo(IdUtil.getSnowflakeNextIdStr());
|
||||
|
||||
// 发送通知
|
||||
List<PayChannelOrder> channelOrders = repairStrategies.stream()
|
||||
.map(AbsPayRepairStrategy::getChannelOrder)
|
||||
.collect(Collectors.toList());
|
||||
clientNoticeService.registerPayNotice(order, null, channelOrders);
|
||||
this.saveRecord(order, repairType, repairResult);
|
||||
return repairResult;
|
||||
}
|
||||
@@ -128,11 +131,6 @@ public class PayRepairService {
|
||||
// 读取支付网关中的时间
|
||||
order.setPayTime(payTime);
|
||||
payOrderService.updateById(order);
|
||||
List<PayChannelOrder> channelOrders = strategies.stream()
|
||||
.map(AbsPayRepairStrategy::getChannelOrder)
|
||||
.collect(Collectors.toList());
|
||||
// 发送通知
|
||||
clientNoticeService.registerPayNotice(order, null, channelOrders);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -99,6 +99,9 @@ public class RefundRepairService {
|
||||
PayRepairRecord payRepairRecord = this.payRepairRecord(payOrder, repairType, repairResult);
|
||||
// 退款修复记录
|
||||
PayRepairRecord refundRepairRecord = this.refundRepairRecord(refundOrder, repairType, repairResult);
|
||||
|
||||
// 发送通知
|
||||
clientNoticeService.registerRefundNotice(refundOrder, null, new ArrayList<>(refundChannelOrderMap.values()));
|
||||
recordService.saveAllRecord(Arrays.asList(payRepairRecord, refundRepairRecord));
|
||||
return repairResult;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
|
||||
public class CashPayRepairStrategy extends AbsPayRepairStrategy {
|
||||
|
||||
private final CashRecordService cashRecordService;
|
||||
|
||||
/**
|
||||
* 策略标识
|
||||
*/
|
||||
|
@@ -0,0 +1,36 @@
|
||||
package cn.bootx.platform.daxpay.service.task;
|
||||
|
||||
import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.notice.service.ClientNoticeService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 消息通知任务
|
||||
* @author xxm
|
||||
* @since 2024/2/22
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@DisallowConcurrentExecution
|
||||
@PersistJobDataAfterExecution
|
||||
@RequiredArgsConstructor
|
||||
public class ClientNoticeTask implements Job {
|
||||
|
||||
private final ClientNoticeService clientNoticeService;
|
||||
|
||||
|
||||
/**
|
||||
* 通知任务执行
|
||||
*/
|
||||
@Override
|
||||
public void execute(JobExecutionContext context){
|
||||
// 获取当前时间, 然后查询当前时间及以前需要进行通知的消息
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
clientNoticeService.taskStart(0, LocalDateTimeUtil.timestamp(now));
|
||||
}
|
||||
}
|
@@ -1,15 +1,16 @@
|
||||
package cn.bootx.platform.daxpay.service.core.timeout.task;
|
||||
package cn.bootx.platform.daxpay.service.task;
|
||||
|
||||
import cn.bootx.platform.daxpay.param.pay.PaySyncParam;
|
||||
import cn.bootx.platform.daxpay.service.code.PayRepairSourceEnum;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.pay.dao.PayExpiredTimeRepository;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.sync.service.PaySyncService;
|
||||
import cn.bootx.platform.daxpay.service.core.timeout.dao.PayExpiredTimeRepository;
|
||||
import com.baomidou.lock.LockInfo;
|
||||
import com.baomidou.lock.LockTemplate;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@@ -17,27 +18,23 @@ import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* 支付超时处理
|
||||
* @author xxm
|
||||
* @since 2024/1/2
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PayExpiredTimeTask {
|
||||
public class PayExpiredTimeTask implements Job {
|
||||
private final PayExpiredTimeRepository repository;
|
||||
|
||||
private final PaySyncService paySyncService;
|
||||
|
||||
private final LockTemplate lockTemplate;
|
||||
|
||||
/**
|
||||
* 先使用定时任务实现, 五秒轮训一下
|
||||
*
|
||||
*/
|
||||
@Scheduled(cron = "*/5 * * * * ?")
|
||||
public void task(){
|
||||
// log.debug("执行超时取消任务....");
|
||||
@Override
|
||||
public void execute(JobExecutionContext context) {
|
||||
// 获取超时的任务Key
|
||||
Set<String> expiredKeys = repository.getExpiredKeys(LocalDateTime.now());
|
||||
for (String expiredKey : expiredKeys) {
|
||||
LockInfo lock = lockTemplate.lock("payment:expired:" + expiredKey,10000,200);
|
||||
@@ -62,10 +59,6 @@ public class PayExpiredTimeTask {
|
||||
} finally {
|
||||
lockTemplate.releaseLock(lock);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user