支付重构方案-核心接口设计-20251127


支付模块重构 - 核心接口设计

本文档详细定义支付模块的核心接口和类设计


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);
}

以上为核心接口设计,各具体实现类将在执行阶段编写。



扫描二维码,在手机上阅读
收藏

支付重构方案-各层详细设计-20251127

支付重构方案-20251127

评 论
请登录后再评论