支付模块重构 - 核心接口设计
本文档详细定义支付模块的核心接口和类设计
1. 枚举定义
1.1 PaymentPlatform - 支付平台枚举
package com.changfeng.pay.model.enums;
import lombok.Getter;
import lombok.AllArgsConstructor;
/**
* 支付平台枚举
*/
@Getter
@AllArgsConstructor
public enum PaymentPlatform {
WECHAT("wechat", "微信支付"),
ALIPAY("alipay", "支付宝"),
APPLE("apple", "苹果支付"),
GOOGLE("google", "谷歌支付"),
STRIPE("stripe", "Stripe支付");
private final String code;
private final String name;
public static PaymentPlatform fromCode(String code) {
for (PaymentPlatform platform : values()) {
if (platform.getCode().equalsIgnoreCase(code)) {
return platform;
}
}
throw new IllegalArgumentException("未知的支付平台: " + code);
}
}
1.2 PaymentStatus - 支付状态枚举
package com.changfeng.pay.model.enums;
import lombok.Getter;
import lombok.AllArgsConstructor;
/**
* 支付状态枚举
*/
@Getter
@AllArgsConstructor
public enum PaymentStatus {
PENDING("pending", "待支付"),
PROCESSING("processing", "处理中"),
SUCCESS("success", "支付成功"),
FAILED("failed", "支付失败"),
CANCELLED("cancelled", "已取消"),
REFUNDED("refunded", "已退款"),
PARTIAL_REFUNDED("partial_refunded", "部分退款");
private final String code;
private final String name;
public boolean isTerminal() {
return this == SUCCESS || this == FAILED ||
this == CANCELLED || this == REFUNDED;
}
}
1.3 ProductType - 产品类型枚举
package com.changfeng.pay.model.enums;
import lombok.Getter;
import lombok.AllArgsConstructor;
/**
* 产品类型枚举
*/
@Getter
@AllArgsConstructor
public enum ProductType {
YEAR_VIP("0", "包年会员", true),
MONTH_VIP("1", "包月会员", true),
CLOUD_STORAGE("2", "云存储包", false),
RECORDING_PACKAGE("3", "录音转写包", false);
private final String code;
private final String name;
private final boolean subscription; // 是否订阅类型
public static ProductType fromCode(String code) {
for (ProductType type : values()) {
if (type.getCode().equals(code)) {
return type;
}
}
throw new IllegalArgumentException("未知的产品类型: " + code);
}
}
2. 统一请求/响应模型
2.1 CreateOrderRequest - 创建订单请求
package com.changfeng.pay.model.request;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 创建订单请求(统一模型)
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CreateOrderRequest {
/** 用户ID */
@NotBlank(message = "userId不能为空")
private String userId;
/** 产品ID */
@NotBlank(message = "productId不能为空")
private String productId;
/** 支付平台 */
@NotNull(message = "支付平台不能为空")
private PaymentPlatform platform;
/** 是否海外用户 */
private Boolean isAbroad;
/** 客户端IP(用于风控) */
private String clientIp;
/** 设备信息 */
private String deviceInfo;
/** 扩展参数(各渠道特殊参数) */
private Map<String, Object> extraParams;
}
2.2 CreateOrderResponse - 创建订单响应
package com.changfeng.pay.model.response;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
/**
* 创建订单响应(统一模型)
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CreateOrderResponse {
/** 本地订单号 */
private String orderId;
/** 支付平台 */
private PaymentPlatform platform;
/** 是否成功 */
private boolean success;
/** 错误码(失败时) */
private String errorCode;
/** 错误信息(失败时) */
private String errorMsg;
// ===== 以下为各渠道特有返回 =====
/** 微信预支付ID */
private String prepayId;
/** 微信APP支付参数 */
private WechatAppPayParams wechatParams;
/** 支付宝订单字符串 */
private String alipayOrderString;
/** Stripe客户端密钥 */
private String stripeClientSecret;
/** Stripe订阅ID */
private String stripeSubscriptionId;
/**
* 微信APP支付参数
*/
@Data
@Builder
public static class WechatAppPayParams {
private String appId;
private String partnerId;
private String prepayId;
private String packageValue;
private String nonceStr;
private String timestamp;
private String sign;
}
// ===== 静态工厂方法 =====
public static CreateOrderResponse success(String orderId, PaymentPlatform platform) {
return CreateOrderResponse.builder()
.orderId(orderId)
.platform(platform)
.success(true)
.build();
}
public static CreateOrderResponse fail(String errorCode, String errorMsg) {
return CreateOrderResponse.builder()
.success(false)
.errorCode(errorCode)
.errorMsg(errorMsg)
.build();
}
}
2.3 VerifyOrderRequest - 验证订单请求
package com.changfeng.pay.model.request;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import javax.validation.constraints.NotBlank;
/**
* 验证订单请求(统一模型)
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VerifyOrderRequest {
/** 用户ID */
@NotBlank(message = "userId不能为空")
private String userId;
/** 本地订单号 */
@NotBlank(message = "orderId不能为空")
private String orderId;
/** 产品ID */
@NotBlank(message = "productId不能为空")
private String productId;
/** 支付平台 */
private PaymentPlatform platform;
/** 支付凭证(苹果receipt/谷歌purchaseToken等) */
private String receipt;
/** 平台交易ID */
private String transactionId;
/** 平台原始交易ID */
private String originalTransactionId;
/** 扩展参数 */
private Map<String, Object> extraParams;
}
2.4 VerifyOrderResponse - 验证订单响应
package com.changfeng.pay.model.response;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
/**
* 验证订单响应(统一模型)
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VerifyOrderResponse {
/** 本地订单号 */
private String orderId;
/** 支付状态 */
private PaymentStatus status;
/** 平台交易号 */
private String platformTransactionId;
/** 平台原始交易号 */
private String platformOriginalTransactionId;
/** 支付金额 */
private String payAmount;
/** 货币类型 */
private String currency;
/** 支付时间 */
private Date payTime;
/** 是否成功 */
private boolean success;
/** 错误码 */
private String errorCode;
/** 错误信息 */
private String errorMsg;
/** 权限是否已下发 */
private boolean permissionGranted;
// ===== 静态工厂方法 =====
public static VerifyOrderResponse success(String orderId, PaymentStatus status) {
return VerifyOrderResponse.builder()
.orderId(orderId)
.status(status)
.success(true)
.build();
}
public static VerifyOrderResponse fail(String errorCode, String errorMsg) {
return VerifyOrderResponse.builder()
.success(false)
.errorCode(errorCode)
.errorMsg(errorMsg)
.status(PaymentStatus.FAILED)
.build();
}
}
3. 支付网关接口
3.1 PaymentGateway - 网关接口(策略模式)
package com.changfeng.pay.gateway;
import com.changfeng.pay.model.enums.PaymentPlatform;
import com.changfeng.pay.model.request.*;
import com.changfeng.pay.model.response.*;
import com.changfeng.pay.model.dto.NotifyMessage;
import java.util.Map;
/**
* 支付网关接口 - 策略模式核心接口
* <p>
* 每个支付渠道实现此接口,提供统一的支付能力
* </p>
*/
public interface PaymentGateway {
/**
* 获取当前网关对应的支付平台
* @return 支付平台枚举
*/
PaymentPlatform getPlatform();
/**
* 创建支付订单
* <p>
* 调用第三方支付平台,创建预支付订单,返回支付凭证
* </p>
*
* @param request 创建订单请求
* @return 创建订单响应(包含预支付ID、支付参数等)
*/
CreateOrderResponse createOrder(CreateOrderRequest request);
/**
* 验证订单支付结果
* <p>
* 根据支付凭证,向第三方平台查询/验证订单支付状态
* </p>
*
* @param request 验证订单请求
* @return 验证结果响应
*/
VerifyOrderResponse verifyOrder(VerifyOrderRequest request);
/**
* 查询订单状态
*
* @param orderId 本地订单号
* @return 查询结果
*/
PaymentQueryResult queryOrder(String orderId);
/**
* 处理回调通知
* <p>
* 接收并处理来自第三方平台的支付结果通知
* </p>
*
* @param notifyBody 通知报文体
* @param headers 请求头(用于验签)
* @return 处理结果
*/
NotifyHandleResult handleNotify(String notifyBody, Map<String, String> headers);
/**
* 解析通知消息为统一格式
*
* @param notifyBody 原始通知报文
* @param headers 请求头
* @return 统一通知消息
*/
NotifyMessage parseNotifyMessage(String notifyBody, Map<String, String> headers);
/**
* 验证通知签名
*
* @param notifyBody 通知报文
* @param headers 请求头
* @return 签名是否有效
*/
boolean verifyNotifySignature(String notifyBody, Map<String, String> headers);
/**
* 退款(默认不支持,子类可覆盖)
*
* @param request 退款请求
* @return 退款响应
*/
default RefundResponse refund(RefundRequest request) {
throw new UnsupportedOperationException(
String.format("支付平台[%s]暂不支持退款", getPlatform().getName())
);
}
/**
* 关闭订单(默认不支持)
*
* @param orderId 订单号
* @return 是否成功
*/
default boolean closeOrder(String orderId) {
throw new UnsupportedOperationException(
String.format("支付平台[%s]暂不支持关闭订单", getPlatform().getName())
);
}
}
3.2 AbstractPaymentGateway - 抽象网关(模板方法模式)
package com.changfeng.pay.gateway;
import com.changfeng.pay.exception.PaymentException;
import com.changfeng.pay.exception.PaymentGatewayException;
import com.changfeng.pay.model.dto.PaymentResult;
import com.changfeng.pay.model.request.*;
import com.changfeng.pay.model.response.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import java.util.Map;
/**
* 抽象支付网关 - 模板方法模式
* <p>
* 定义支付流程的骨架,将具体步骤延迟到子类实现
* </p>
*/
@Slf4j
public abstract class AbstractPaymentGateway implements PaymentGateway {
// ==================== 创建订单模板方法 ====================
/**
* 创建订单 - 模板方法
* 定义创建订单的标准流程,子类实现具体步骤
*/
@Override
public final CreateOrderResponse createOrder(CreateOrderRequest request) {
try {
// 1. 参数校验(通用逻辑)
validateCreateOrderRequest(request);
// 2. 前置处理(钩子方法,子类可选覆盖)
beforeCreateOrder(request);
// 3. 构建渠道请求(抽象方法,子类必须实现)
Object channelRequest = buildChannelCreateRequest(request);
// 4. 调用渠道API(抽象方法,子类必须实现)
Object channelResponse = doCreateOrder(channelRequest);
// 5. 适配响应(抽象方法,子类必须实现)
CreateOrderResponse response = adaptCreateOrderResponse(channelResponse, request);
// 6. 后置处理(钩子方法)
afterCreateOrder(request, response);
return response;
} catch (PaymentException e) {
log.error("[{}] 创建订单异常: {}", getPlatform(), e.getMessage());
throw e;
} catch (Exception e) {
log.error("[{}] 创建订单系统异常", getPlatform(), e);
throw new PaymentGatewayException(getPlatform(), "创建订单失败: " + e.getMessage(), e);
}
}
// ==================== 验证订单模板方法 ====================
/**
* 验证订单 - 模板方法
*/
@Override
@Retryable(
value = {PaymentGatewayException.class},
maxAttempts = 3,
backoff = @Backoff(delay = 1000, multiplier = 2)
)
public final VerifyOrderResponse verifyOrder(VerifyOrderRequest request) {
try {
// 1. 参数校验
validateVerifyOrderRequest(request);
// 2. 前置处理
beforeVerifyOrder(request);
// 3. 调用渠道验证(抽象方法)
Object channelResponse = doVerifyOrder(request);
// 4. 解析验证结果(抽象方法)
PaymentResult result = parseVerifyResult(channelResponse);
// 5. 构建统一响应
VerifyOrderResponse response = buildVerifyResponse(result, request);
// 6. 后置处理
afterVerifyOrder(request, response);
return response;
} catch (PaymentException e) {
log.error("[{}] 验证订单异常: {}", getPlatform(), e.getMessage());
throw e;
} catch (Exception e) {
log.error("[{}] 验证订单系统异常", getPlatform(), e);
throw new PaymentGatewayException(getPlatform(), "验证订单失败: " + e.getMessage(), e);
}
}
// ==================== 抽象方法(子类必须实现) ====================
/**
* 构建渠道创建订单请求
*/
protected abstract Object buildChannelCreateRequest(CreateOrderRequest request);
/**
* 执行创建订单(调用渠道API)
*/
protected abstract Object doCreateOrder(Object channelRequest);
/**
* 适配创建订单响应
*/
protected abstract CreateOrderResponse adaptCreateOrderResponse(
Object channelResponse, CreateOrderRequest request);
/**
* 执行验证订单(调用渠道API)
*/
protected abstract Object doVerifyOrder(VerifyOrderRequest request);
/**
* 解析验证结果
*/
protected abstract PaymentResult parseVerifyResult(Object channelResponse);
// ==================== 钩子方法(子类可选覆盖) ====================
/**
* 校验创建订单请求
*/
protected void validateCreateOrderRequest(CreateOrderRequest request) {
if (request == null) {
throw new PaymentException("请求参数不能为空");
}
if (request.getUserId() == null || request.getUserId().isEmpty()) {
throw new PaymentException("用户ID不能为空");
}
if (request.getProductId() == null || request.getProductId().isEmpty()) {
throw new PaymentException("产品ID不能为空");
}
}
/**
* 校验验证订单请求
*/
protected void validateVerifyOrderRequest(VerifyOrderRequest request) {
if (request == null) {
throw new PaymentException("请求参数不能为空");
}
if (request.getOrderId() == null || request.getOrderId().isEmpty()) {
throw new PaymentException("订单ID不能为空");
}
}
/**
* 创建订单前置处理
*/
protected void beforeCreateOrder(CreateOrderRequest request) {
log.debug("[{}] 创建订单前置处理, userId={}, productId={}",
getPlatform(), request.getUserId(), request.getProductId());
}
/**
* 创建订单后置处理
*/
protected void afterCreateOrder(CreateOrderRequest request, CreateOrderResponse response) {
log.info("[{}] 创建订单完成, orderId={}, success={}",
getPlatform(), response.getOrderId(), response.isSuccess());
}
/**
* 验证订单前置处理
*/
protected void beforeVerifyOrder(VerifyOrderRequest request) {
log.debug("[{}] 验证订单前置处理, orderId={}", getPlatform(), request.getOrderId());
}
/**
* 验证订单后置处理
*/
protected void afterVerifyOrder(VerifyOrderRequest request, VerifyOrderResponse response) {
log.info("[{}] 验证订单完成, orderId={}, status={}",
getPlatform(), request.getOrderId(), response.getStatus());
}
/**
* 构建验证响应
*/
protected VerifyOrderResponse buildVerifyResponse(PaymentResult result, VerifyOrderRequest request) {
return VerifyOrderResponse.builder()
.orderId(request.getOrderId())
.status(result.getStatus())
.platformTransactionId(result.getTransactionId())
.platformOriginalTransactionId(result.getOriginalTransactionId())
.payAmount(result.getAmount())
.currency(result.getCurrency())
.payTime(result.getPayTime())
.success(result.isSuccess())
.build();
}
}
3.3 PaymentGatewayFactory - 网关工厂
package com.changfeng.pay.gateway;
import com.changfeng.pay.exception.PaymentGatewayException;
import com.changfeng.pay.model.enums.PaymentPlatform;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* 支付网关工厂 - 工厂模式
* <p>
* 根据支付平台类型获取对应的网关实现
* </p>
*/
@Slf4j
@Component
public class PaymentGatewayFactory {
private final Map<PaymentPlatform, PaymentGateway> gatewayMap = new ConcurrentHashMap<>();
@Autowired
public PaymentGatewayFactory(List<PaymentGateway> gateways) {
// Spring自动注入所有PaymentGateway实现
gateways.forEach(gateway -> {
gatewayMap.put(gateway.getPlatform(), gateway);
log.info("注册支付网关: {} -> {}", gateway.getPlatform(), gateway.getClass().getSimpleName());
});
}
@PostConstruct
public void init() {
log.info("支付网关工厂初始化完成,已注册网关: {}",
gatewayMap.keySet().stream().map(Enum::name).collect(Collectors.joining(", ")));
}
/**
* 根据平台枚举获取网关
*/
public PaymentGateway getGateway(PaymentPlatform platform) {
PaymentGateway gateway = gatewayMap.get(platform);
if (gateway == null) {
throw new PaymentGatewayException(platform, "不支持的支付平台: " + platform.getName());
}
return gateway;
}
/**
* 根据平台编码获取网关
*/
public PaymentGateway getGateway(String platformCode) {
PaymentPlatform platform = PaymentPlatform.fromCode(platformCode);
return getGateway(platform);
}
/**
* 检查平台是否支持
*/
public boolean isSupported(PaymentPlatform platform) {
return gatewayMap.containsKey(platform);
}
/**
* 获取所有已注册的网关
*/
public Map<PaymentPlatform, PaymentGateway> getAllGateways() {
return new ConcurrentHashMap<>(gatewayMap);
}
}
4. 门面层接口
4.1 PaymentFacade - 支付门面
package com.changfeng.pay.facade;
import com.changfeng.pay.model.enums.PaymentPlatform;
import com.changfeng.pay.model.request.*;
import com.changfeng.pay.model.response.*;
/**
* 支付门面接口 - 门面模式
* <p>
* 统一对外入口,隐藏内部复杂性,编排业务流程
* </p>
*/
public interface PaymentFacade {
/**
* 创建支付订单
* <p>
* 流程:参数校验 -> 幂等检查 -> 创建本地订单 -> 调用网关 -> 返回结果
* </p>
*
* @param platform 支付平台
* @param request 请求参数
* @return 创建结果
*/
CreateOrderResponse createOrder(PaymentPlatform platform, CreateOrderRequest request);
/**
* 验证订单支付结果
* <p>
* 流程:参数校验 -> 重复确认检查 -> 调用网关验证 -> 更新订单 -> 下发权限 -> 返回结果
* </p>
*
* @param platform 支付平台
* @param request 请求参数
* @return 验证结果
*/
VerifyOrderResponse verifyOrder(PaymentPlatform platform, VerifyOrderRequest request);
/**
* 查询订单状态
*
* @param orderId 订单号
* @return 查询结果
*/
PaymentQueryResult queryOrder(String orderId);
}
4.2 PaymentFacadeImpl - 支付门面实现
package com.changfeng.pay.facade;
import com.changfeng.pay.core.event.PaymentEventPublisher;
import com.changfeng.pay.core.event.PaymentSuccessEvent;
import com.changfeng.pay.core.service.OrderService;
import com.changfeng.pay.core.service.PermissionService;
import com.changfeng.pay.gateway.PaymentGateway;
import com.changfeng.pay.gateway.PaymentGatewayFactory;
import com.changfeng.pay.infrastructure.idempotent.IdempotentChecker;
import com.changfeng.pay.infrastructure.lock.DistributedLock;
import com.changfeng.pay.model.dto.PaymentOrder;
import com.changfeng.pay.model.enums.PaymentPlatform;
import com.changfeng.pay.model.enums.PaymentStatus;
import com.changfeng.pay.model.request.*;
import com.changfeng.pay.model.response.*;
import com.changfeng.pay.exception.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.concurrent.TimeUnit;
/**
* 支付门面实现
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class PaymentFacadeImpl implements PaymentFacade {
private final PaymentGatewayFactory gatewayFactory;
private final OrderService orderService;
private final PermissionService permissionService;
private final IdempotentChecker idempotentChecker;
private final DistributedLock distributedLock;
private final PaymentEventPublisher eventPublisher;
@Override
@Transactional(rollbackFor = Exception.class)
public CreateOrderResponse createOrder(PaymentPlatform platform, CreateOrderRequest request) {
log.info("[创建订单] 开始, platform={}, userId={}, productId={}",
platform, request.getUserId(), request.getProductId());
// 1. 获取对应网关
PaymentGateway gateway = gatewayFactory.getGateway(platform);
// 2. 创建本地订单
PaymentOrder order = orderService.createOrder(request);
log.info("[创建订单] 本地订单创建成功, orderId={}", order.getOrderId());
// 3. 调用支付网关
request.setPlatform(platform);
CreateOrderResponse response = gateway.createOrder(request);
response.setOrderId(order.getOrderId());
// 4. 更新订单状态
if (response.isSuccess()) {
orderService.updateOrderStatus(order.getOrderId(), PaymentStatus.PENDING);
}
log.info("[创建订单] 完成, orderId={}, success={}", order.getOrderId(), response.isSuccess());
return response;
}
@Override
@Transactional(rollbackFor = Exception.class)
public VerifyOrderResponse verifyOrder(PaymentPlatform platform, VerifyOrderRequest request) {
String orderId = request.getOrderId();
String lockKey = "payment:verify:" + orderId;
log.info("[验证订单] 开始, platform={}, orderId={}", platform, orderId);
// 1. 分布式锁保护(防止并发验证)
boolean locked = distributedLock.tryLock(lockKey, 30, TimeUnit.SECONDS);
if (!locked) {
throw new PaymentException("订单正在处理中,请稍后再试");
}
try {
// 2. 幂等性检查
if (idempotentChecker.isDuplicate("verify", orderId)) {
log.warn("[验证订单] 重复确认, orderId={}", orderId);
throw new DuplicateOrderException("订单已确认,无需重复操作");
}
// 3. 查询本地订单
PaymentOrder order = orderService.getOrder(orderId);
if (order == null) {
throw new OrderNotFoundException("订单不存在: " + orderId);
}
// 4. 检查订单状态
if (order.getStatus() == PaymentStatus.SUCCESS) {
throw new DuplicateOrderException("订单已支付成功");
}
// 5. 调用网关验证
PaymentGateway gateway = gatewayFactory.getGateway(platform);
VerifyOrderResponse response = gateway.verifyOrder(request);
// 6. 处理验证结果
if (response.isSuccess() && response.getStatus() == PaymentStatus.SUCCESS) {
// 更新订单状态
orderService.updateOrderWithPaymentResult(orderId, response);
// 下发权限
boolean permissionGranted = permissionService.grantPermission(
order.getUserId(), order.getProductId(), platform);
response.setPermissionGranted(permissionGranted);
// 发布支付成功事件
eventPublisher.publishSuccess(new PaymentSuccessEvent(order, response));
// 标记幂等
idempotentChecker.markProcessed("verify", orderId);
log.info("[验证订单] 支付成功, orderId={}, 权限下发={}", orderId, permissionGranted);
}
return response;
} finally {
distributedLock.unlock(lockKey);
}
}
@Override
public PaymentQueryResult queryOrder(String orderId) {
PaymentOrder order = orderService.getOrder(orderId);
if (order == null) {
throw new OrderNotFoundException("订单不存在: " + orderId);
}
return PaymentQueryResult.builder()
.orderId(order.getOrderId())
.status(order.getStatus())
.platformTransactionId(order.getPlatformTransactionId())
.payAmount(order.getPayAmount())
.currency(order.getCurrency())
.payTime(order.getPayTime())
.build();
}
}
5. 责任链处理器
5.1 NotifyHandler - 处理器接口
package com.changfeng.pay.handler;
import com.changfeng.pay.model.dto.NotifyContext;
/**
* 通知处理器接口 - 责任链模式
*/
public interface NotifyHandler {
/**
* 处理通知
* @param context 通知上下文
* @return 是否继续后续处理
*/
boolean handle(NotifyContext context);
/**
* 获取处理器顺序(越小越先执行)
*/
int getOrder();
}
5.2 NotifyHandlerChain - 处理器链
package com.changfeng.pay.handler;
import com.changfeng.pay.model.dto.NotifyContext;
import com.changfeng.pay.model.response.NotifyHandleResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Comparator;
import java.util.List;
/**
* 通知处理器链
*/
@Slf4j
@Component
public class NotifyHandlerChain {
private List<NotifyHandler> handlers;
@Autowired
public NotifyHandlerChain(List<NotifyHandler> handlers) {
this.handlers = handlers;
}
@PostConstruct
public void init() {
// 按顺序排序
handlers.sort(Comparator.comparingInt(NotifyHandler::getOrder));
log.info("通知处理器链初始化完成,处理器数量: {}", handlers.size());
}
/**
* 执行处理器链
*/
public NotifyHandleResult execute(NotifyContext context) {
for (NotifyHandler handler : handlers) {
try {
log.debug("执行处理器: {}", handler.getClass().getSimpleName());
boolean continueChain = handler.handle(context);
if (!continueChain) {
log.info("处理器 {} 中断链式调用", handler.getClass().getSimpleName());
break;
}
} catch (Exception e) {
log.error("处理器 {} 执行异常", handler.getClass().getSimpleName(), e);
return NotifyHandleResult.fail(e.getMessage());
}
}
return context.getResult();
}
}
6. 基础设施接口
6.1 DistributedLock - 分布式锁接口
package com.changfeng.pay.infrastructure.lock;
import java.util.concurrent.TimeUnit;
/**
* 分布式锁接口
*/
public interface DistributedLock {
/**
* 尝试获取锁
* @param key 锁的key
* @param timeout 超时时间
* @param unit 时间单位
* @return 是否获取成功
*/
boolean tryLock(String key, long timeout, TimeUnit unit);
/**
* 释放锁
* @param key 锁的key
*/
void unlock(String key);
/**
* 检查是否持有锁
* @param key 锁的key
* @return 是否持有
*/
boolean isLocked(String key);
}
6.2 IdempotentChecker - 幂等检查器接口
package com.changfeng.pay.infrastructure.idempotent;
/**
* 幂等检查器接口
*/
public interface IdempotentChecker {
/**
* 检查是否重复请求
* @param type 业务类型
* @param key 业务key
* @return 是否重复
*/
boolean isDuplicate(String type, String key);
/**
* 标记请求已处理
* @param type 业务类型
* @param key 业务key
*/
void markProcessed(String type, String key);
/**
* 标记请求已处理(带过期时间)
* @param type 业务类型
* @param key 业务key
* @param expireSeconds 过期秒数
*/
void markProcessed(String type, String key, long expireSeconds);
}
6.3 PaymentAsyncExecutor - 异步执行器
package com.changfeng.pay.infrastructure.async;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.function.Consumer;
/**
* 支付异步执行器
*/
public interface PaymentAsyncExecutor {
/**
* 提交异步任务
* @param task 任务
*/
void execute(Runnable task);
/**
* 提交异步任务(带回调)
* @param task 任务
* @param callback 回调
*/
<T> void execute(Callable<T> task, Consumer<T> callback);
/**
* 提交异步任务(带返回值)
* @param task 任务
* @return Future
*/
<T> Future<T> submit(Callable<T> task);
/**
* 提交带超时的异步任务
* @param task 任务
* @param timeoutMs 超时毫秒
* @param fallback 超时后的降级处理
*/
<T> void executeWithTimeout(Callable<T> task, long timeoutMs, Consumer<Throwable> fallback);
}
以上为核心接口设计,各具体实现类将在执行阶段编写。