支付网关系统

# 支付网关系统

在跨境电商的世界里,支付就像是连接买家和卖家的桥梁。想象一下,当一位美国的消费者想要购买来自中国的商品时,他们需要用美元支付,而商家希望收到人民币。这个看似简单的过程背后,隐藏着复杂的技术挑战:多币种转换、汇率计算、风险控制、合规检查等。今天,我们就来揭开支付网关系统的神秘面纱,看看它是如何让全球贸易变得如此便捷。

# 📋 系统概述

# 核心功能

支付网关系统是跨境电商的金融中枢,主要负责:

  • 多渠道支付接入:支持信用卡、PayPal、支付宝、微信支付等
  • 多币种处理:实时汇率转换和多币种结算
  • 风险控制:反欺诈检测和风险评估
  • 合规管理:满足各国金融监管要求
  • 资金清算:自动化的资金分账和清算
  • 支付路由:智能选择最优支付通道

# 🏗️ 系统架构设计

graph TB
    subgraph "客户端层"
        A[Web前端] --> B[移动端]
        B --> C[第三方应用]
    end
    
    subgraph "网关层"
        D[API网关] --> E[负载均衡器]
        E --> F[支付网关服务]
    end
    
    subgraph "核心服务层"
        F --> G[支付路由服务]
        F --> H[风控服务]
        F --> I[汇率服务]
        F --> J[合规服务]
        
        G --> K[渠道管理服务]
        H --> L[反欺诈引擎]
        I --> M[汇率计算引擎]
        J --> N[KYC/AML服务]
    end
    
    subgraph "支付渠道层"
        K --> O[信用卡通道]
        K --> P[PayPal]
        K --> Q[支付宝]
        K --> R[微信支付]
        K --> S[银行直连]
    end
    
    subgraph "数据层"
        T[支付数据库] --> U[风控数据库]
        U --> V[汇率数据库]
        V --> W[合规数据库]
        W --> X[Redis缓存]
    end
    
    subgraph "外部服务"
        Y[银行系统] --> Z[监管机构]
        Z --> AA[汇率提供商]
        AA --> BB[风控服务商]
    end

# 💻 核心代码实现

# 1. 支付网关核心服务

/**
 * 支付网关核心服务
 * 负责统一的支付处理流程
 */
@Service
@Transactional
public class PaymentGatewayService {
    
    private final PaymentRouterService paymentRouterService;
    private final RiskControlService riskControlService;
    private final ExchangeRateService exchangeRateService;
    private final ComplianceService complianceService;
    private final PaymentRepository paymentRepository;
    private final PaymentEventPublisher paymentEventPublisher;
    
    /**
     * 创建支付订单
     */
    public PaymentCreationResult createPayment(PaymentCreationRequest request) {
        
        log.info("开始创建支付订单: {}", request);
        
        try {
            // 1. 参数验证
            validatePaymentRequest(request);
            
            // 2. 风险评估
            RiskAssessmentResult riskResult = riskControlService.assessRisk(request);
            if (riskResult.getRiskLevel() == RiskLevel.HIGH) {
                return PaymentCreationResult.rejected("高风险交易被拒绝", riskResult);
            }
            
            // 3. 合规检查
            ComplianceCheckResult complianceResult = complianceService.checkCompliance(request);
            if (!complianceResult.isPassed()) {
                return PaymentCreationResult.rejected("合规检查未通过", complianceResult);
            }
            
            // 4. 汇率计算
            ExchangeRateCalculationResult rateResult = exchangeRateService
                .calculateExchangeRate(request.getSourceCurrency(), request.getTargetCurrency(), 
                                     request.getAmount());
            
            // 5. 支付路由选择
            PaymentRouteResult routeResult = paymentRouterService.selectOptimalRoute(request, riskResult);
            
            // 6. 创建支付记录
            Payment payment = createPaymentRecord(request, riskResult, complianceResult, 
                                                rateResult, routeResult);
            
            // 7. 发布支付创建事件
            paymentEventPublisher.publishPaymentCreated(payment);
            
            log.info("支付订单创建成功: {}", payment.getPaymentId());
            
            return PaymentCreationResult.success(payment, routeResult);
            
        } catch (Exception e) {
            log.error("创建支付订单失败: {}", request, e);
            return PaymentCreationResult.failure(e.getMessage());
        }
    }
    
    /**
     * 执行支付
     */
    public PaymentExecutionResult executePayment(String paymentId, PaymentExecutionRequest request) {
        
        log.info("开始执行支付: {}", paymentId);
        
        try {
            // 1. 获取支付记录
            Payment payment = paymentRepository.findByPaymentId(paymentId)
                .orElseThrow(() -> new PaymentNotFoundException("支付记录不存在: " + paymentId));
            
            // 2. 验证支付状态
            if (payment.getStatus() != PaymentStatus.CREATED) {
                throw new InvalidPaymentStatusException(
                    "支付状态无效: " + payment.getStatus());
            }
            
            // 3. 更新支付状态为处理中
            payment.setStatus(PaymentStatus.PROCESSING);
            payment.setProcessingStartTime(Instant.now());
            paymentRepository.save(payment);
            
            // 4. 获取支付渠道处理器
            PaymentChannelProcessor processor = getPaymentChannelProcessor(payment.getChannelCode());
            
            // 5. 执行支付
            PaymentChannelResult channelResult = processor.processPayment(payment, request);
            
            // 6. 更新支付结果
            updatePaymentResult(payment, channelResult);
            
            // 7. 发布支付结果事件
            if (channelResult.isSuccess()) {
                paymentEventPublisher.publishPaymentSuccess(payment);
            } else {
                paymentEventPublisher.publishPaymentFailure(payment, channelResult.getErrorMessage());
            }
            
            log.info("支付执行完成: {}, 结果: {}", paymentId, channelResult.isSuccess());
            
            return PaymentExecutionResult.from(payment, channelResult);
            
        } catch (Exception e) {
            log.error("执行支付失败: {}", paymentId, e);
            
            // 更新支付状态为失败
            updatePaymentStatusToFailed(paymentId, e.getMessage());
            
            return PaymentExecutionResult.failure(e.getMessage());
        }
    }
    
    /**
     * 查询支付状态
     */
    @Transactional(readOnly = true)
    public PaymentStatusResult queryPaymentStatus(String paymentId) {
        
        Payment payment = paymentRepository.findByPaymentId(paymentId)
            .orElseThrow(() -> new PaymentNotFoundException("支付记录不存在: " + paymentId));
        
        // 如果支付状态为处理中,尝试从渠道查询最新状态
        if (payment.getStatus() == PaymentStatus.PROCESSING) {
            try {
                PaymentChannelProcessor processor = getPaymentChannelProcessor(payment.getChannelCode());
                PaymentChannelStatusResult channelStatus = processor.queryPaymentStatus(payment);
                
                if (channelStatus.isStatusChanged()) {
                    updatePaymentStatusFromChannel(payment, channelStatus);
                }
                
            } catch (Exception e) {
                log.warn("查询渠道支付状态失败: {}", paymentId, e);
            }
        }
        
        return PaymentStatusResult.from(payment);
    }
    
    /**
     * 支付退款
     */
    public RefundResult refundPayment(String paymentId, RefundRequest request) {
        
        log.info("开始处理退款: {}, 退款金额: {}", paymentId, request.getRefundAmount());
        
        try {
            // 1. 获取原支付记录
            Payment originalPayment = paymentRepository.findByPaymentId(paymentId)
                .orElseThrow(() -> new PaymentNotFoundException("支付记录不存在: " + paymentId));
            
            // 2. 验证退款条件
            validateRefundRequest(originalPayment, request);
            
            // 3. 创建退款记录
            Refund refund = createRefundRecord(originalPayment, request);
            
            // 4. 执行渠道退款
            PaymentChannelProcessor processor = getPaymentChannelProcessor(originalPayment.getChannelCode());
            RefundChannelResult channelResult = processor.processRefund(originalPayment, refund);
            
            // 5. 更新退款结果
            updateRefundResult(refund, channelResult);
            
            // 6. 发布退款事件
            if (channelResult.isSuccess()) {
                paymentEventPublisher.publishRefundSuccess(refund);
            } else {
                paymentEventPublisher.publishRefundFailure(refund, channelResult.getErrorMessage());
            }
            
            log.info("退款处理完成: {}, 结果: {}", refund.getRefundId(), channelResult.isSuccess());
            
            return RefundResult.from(refund, channelResult);
            
        } catch (Exception e) {
            log.error("处理退款失败: {}", paymentId, e);
            return RefundResult.failure(e.getMessage());
        }
    }
    
    /**
     * 创建支付记录
     */
    private Payment createPaymentRecord(PaymentCreationRequest request, 
                                      RiskAssessmentResult riskResult,
                                      ComplianceCheckResult complianceResult,
                                      ExchangeRateCalculationResult rateResult,
                                      PaymentRouteResult routeResult) {
        
        Payment payment = new Payment();
        payment.setPaymentId(generatePaymentId());
        payment.setOrderId(request.getOrderId());
        payment.setUserId(request.getUserId());
        payment.setMerchantId(request.getMerchantId());
        
        // 金额信息
        payment.setSourceAmount(request.getAmount());
        payment.setSourceCurrency(request.getSourceCurrency());
        payment.setTargetAmount(rateResult.getTargetAmount());
        payment.setTargetCurrency(rateResult.getTargetCurrency());
        payment.setExchangeRate(rateResult.getExchangeRate());
        payment.setExchangeRateProvider(rateResult.getProvider());
        
        // 路由信息
        payment.setChannelCode(routeResult.getChannelCode());
        payment.setChannelName(routeResult.getChannelName());
        payment.setPaymentMethod(routeResult.getPaymentMethod());
        
        // 风控信息
        payment.setRiskLevel(riskResult.getRiskLevel());
        payment.setRiskScore(riskResult.getRiskScore());
        payment.setRiskFactors(riskResult.getRiskFactors());
        
        // 合规信息
        payment.setComplianceStatus(complianceResult.getStatus());
        payment.setComplianceChecks(complianceResult.getChecks());
        
        // 状态信息
        payment.setStatus(PaymentStatus.CREATED);
        payment.setCreatedAt(Instant.now());
        payment.setExpiresAt(Instant.now().plus(Duration.ofMinutes(30))); // 30分钟后过期
        
        return paymentRepository.save(payment);
    }
    
    /**
     * 生成支付ID
     */
    private String generatePaymentId() {
        return "PAY_" + System.currentTimeMillis() + "_" + 
               ThreadLocalRandom.current().nextInt(1000, 9999);
    }
    
    /**
     * 获取支付渠道处理器
     */
    private PaymentChannelProcessor getPaymentChannelProcessor(String channelCode) {
        return paymentChannelProcessorFactory.getProcessor(channelCode);
    }
    
    /**
     * 验证支付请求
     */
    private void validatePaymentRequest(PaymentCreationRequest request) {
        
        if (request.getAmount() == null || request.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new InvalidPaymentRequestException("支付金额必须大于0");
        }
        
        if (StringUtils.isBlank(request.getSourceCurrency())) {
            throw new InvalidPaymentRequestException("源币种不能为空");
        }
        
        if (StringUtils.isBlank(request.getTargetCurrency())) {
            throw new InvalidPaymentRequestException("目标币种不能为空");
        }
        
        if (request.getUserId() == null) {
            throw new InvalidPaymentRequestException("用户ID不能为空");
        }
        
        if (StringUtils.isBlank(request.getOrderId())) {
            throw new InvalidPaymentRequestException("订单ID不能为空");
        }
    }
    
    /**
     * 更新支付结果
     */
    private void updatePaymentResult(Payment payment, PaymentChannelResult channelResult) {
        
        if (channelResult.isSuccess()) {
            payment.setStatus(PaymentStatus.SUCCESS);
            payment.setChannelTransactionId(channelResult.getTransactionId());
            payment.setChannelResponseCode(channelResult.getResponseCode());
            payment.setChannelResponseMessage(channelResult.getResponseMessage());
            payment.setCompletedAt(Instant.now());
        } else {
            payment.setStatus(PaymentStatus.FAILED);
            payment.setChannelErrorCode(channelResult.getErrorCode());
            payment.setChannelErrorMessage(channelResult.getErrorMessage());
            payment.setFailedAt(Instant.now());
        }
        
        payment.setProcessingEndTime(Instant.now());
        payment.setProcessingDuration(
            Duration.between(payment.getProcessingStartTime(), payment.getProcessingEndTime()));
        
        paymentRepository.save(payment);
    }
    
    /**
     * 更新支付状态为失败
     */
    private void updatePaymentStatusToFailed(String paymentId, String errorMessage) {
        try {
            Payment payment = paymentRepository.findByPaymentId(paymentId).orElse(null);
            if (payment != null) {
                payment.setStatus(PaymentStatus.FAILED);
                payment.setChannelErrorMessage(errorMessage);
                payment.setFailedAt(Instant.now());
                paymentRepository.save(payment);
            }
        } catch (Exception e) {
            log.error("更新支付状态失败: {}", paymentId, e);
        }
    }
}

# 2. 支付路由服务

/**
 * 支付路由服务
 * 根据多种因素选择最优的支付渠道
 */
@Service
public class PaymentRouterService {
    
    private final PaymentChannelRepository channelRepository;
    private final PaymentChannelConfigService channelConfigService;
    private final PaymentStatisticsService statisticsService;
    private final RedisTemplate<String, Object> redisTemplate;
    
    /**
     * 选择最优支付路由
     */
    public PaymentRouteResult selectOptimalRoute(PaymentCreationRequest request, 
                                               RiskAssessmentResult riskResult) {
        
        log.info("开始选择支付路由: {}", request);
        
        try {
            // 1. 获取可用的支付渠道
            List<PaymentChannel> availableChannels = getAvailableChannels(request, riskResult);
            
            if (availableChannels.isEmpty()) {
                throw new NoAvailableChannelException("没有可用的支付渠道");
            }
            
            // 2. 计算每个渠道的评分
            List<ChannelScore> channelScores = calculateChannelScores(availableChannels, request);
            
            // 3. 选择评分最高的渠道
            ChannelScore bestChannel = channelScores.stream()
                .max(Comparator.comparing(ChannelScore::getScore))
                .orElseThrow(() -> new RouteSelectionException("无法选择最优渠道"));
            
            // 4. 构建路由结果
            PaymentRouteResult result = PaymentRouteResult.builder()
                .channelCode(bestChannel.getChannel().getChannelCode())
                .channelName(bestChannel.getChannel().getChannelName())
                .paymentMethod(bestChannel.getChannel().getPaymentMethod())
                .routingReason(bestChannel.getReason())
                .alternativeChannels(getAlternativeChannels(channelScores, bestChannel))
                .build();
            
            log.info("支付路由选择完成: {}, 选中渠道: {}", 
                request.getOrderId(), result.getChannelCode());
            
            return result;
            
        } catch (Exception e) {
            log.error("选择支付路由失败: {}", request, e);
            throw new RouteSelectionException("支付路由选择失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 获取可用的支付渠道
     */
    private List<PaymentChannel> getAvailableChannels(PaymentCreationRequest request, 
                                                    RiskAssessmentResult riskResult) {
        
        // 1. 基础过滤条件
        List<PaymentChannel> channels = channelRepository.findByStatusAndCurrency(
            ChannelStatus.ACTIVE, request.getSourceCurrency());
        
        // 2. 金额范围过滤
        channels = channels.stream()
            .filter(channel -> isAmountInRange(channel, request.getAmount()))
            .collect(Collectors.toList());
        
        // 3. 地区限制过滤
        channels = channels.stream()
            .filter(channel -> isRegionSupported(channel, request.getUserRegion()))
            .collect(Collectors.toList());
        
        // 4. 风险等级过滤
        channels = channels.stream()
            .filter(channel -> isRiskLevelAcceptable(channel, riskResult.getRiskLevel()))
            .collect(Collectors.toList());
        
        // 5. 渠道可用性检查
        channels = channels.stream()
            .filter(this::isChannelHealthy)
            .collect(Collectors.toList());
        
        return channels;
    }
    
    /**
     * 计算渠道评分
     */
    private List<ChannelScore> calculateChannelScores(List<PaymentChannel> channels, 
                                                    PaymentCreationRequest request) {
        
        return channels.stream()
            .map(channel -> calculateSingleChannelScore(channel, request))
            .collect(Collectors.toList());
    }
    
    /**
     * 计算单个渠道评分
     */
    private ChannelScore calculateSingleChannelScore(PaymentChannel channel, 
                                                   PaymentCreationRequest request) {
        
        double score = 0.0;
        List<String> reasons = new ArrayList<>();
        
        // 1. 成功率权重 (40%)
        double successRate = getChannelSuccessRate(channel.getChannelCode());
        double successScore = successRate * 0.4;
        score += successScore;
        reasons.add(String.format("成功率: %.2f%% (权重40%%)", successRate * 100));
        
        // 2. 费率权重 (30%)
        BigDecimal feeRate = channel.getFeeRate();
        double feeScore = (1.0 - feeRate.doubleValue()) * 0.3; // 费率越低分数越高
        score += feeScore;
        reasons.add(String.format("费率: %.2f%% (权重30%%)", feeRate.multiply(new BigDecimal("100"))));
        
        // 3. 处理速度权重 (20%)
        Duration avgProcessingTime = getChannelAvgProcessingTime(channel.getChannelCode());
        double speedScore = calculateSpeedScore(avgProcessingTime) * 0.2;
        score += speedScore;
        reasons.add(String.format("处理速度: %d秒 (权重20%%)", avgProcessingTime.getSeconds()));
        
        // 4. 用户偏好权重 (10%)
        double preferenceScore = getUserChannelPreference(request.getUserId(), channel.getChannelCode()) * 0.1;
        score += preferenceScore;
        reasons.add(String.format("用户偏好: %.2f (权重10%%)", preferenceScore));
        
        return ChannelScore.builder()
            .channel(channel)
            .score(score)
            .reason(String.join(", ", reasons))
            .build();
    }
    
    /**
     * 获取渠道成功率
     */
    private double getChannelSuccessRate(String channelCode) {
        
        String cacheKey = "channel_success_rate:" + channelCode;
        Double cachedRate = (Double) redisTemplate.opsForValue().get(cacheKey);
        
        if (cachedRate != null) {
            return cachedRate;
        }
        
        // 计算最近24小时的成功率
        Instant startTime = Instant.now().minus(Duration.ofHours(24));
        PaymentStatistics stats = statisticsService.getChannelStatistics(channelCode, startTime, Instant.now());
        
        double successRate = stats.getTotalCount() > 0 ? 
            (double) stats.getSuccessCount() / stats.getTotalCount() : 0.8; // 默认80%
        
        // 缓存5分钟
        redisTemplate.opsForValue().set(cacheKey, successRate, Duration.ofMinutes(5));
        
        return successRate;
    }
    
    /**
     * 获取渠道平均处理时间
     */
    private Duration getChannelAvgProcessingTime(String channelCode) {
        
        String cacheKey = "channel_avg_time:" + channelCode;
        Long cachedSeconds = (Long) redisTemplate.opsForValue().get(cacheKey);
        
        if (cachedSeconds != null) {
            return Duration.ofSeconds(cachedSeconds);
        }
        
        // 计算最近24小时的平均处理时间
        Instant startTime = Instant.now().minus(Duration.ofHours(24));
        Duration avgTime = statisticsService.getChannelAvgProcessingTime(channelCode, startTime, Instant.now());
        
        if (avgTime == null) {
            avgTime = Duration.ofSeconds(30); // 默认30秒
        }
        
        // 缓存5分钟
        redisTemplate.opsForValue().set(cacheKey, avgTime.getSeconds(), Duration.ofMinutes(5));
        
        return avgTime;
    }
    
    /**
     * 计算速度评分
     */
    private double calculateSpeedScore(Duration processingTime) {
        
        long seconds = processingTime.getSeconds();
        
        if (seconds <= 10) {
            return 1.0; // 10秒以内满分
        } else if (seconds <= 30) {
            return 0.8; // 30秒以内80分
        } else if (seconds <= 60) {
            return 0.6; // 60秒以内60分
        } else if (seconds <= 120) {
            return 0.4; // 120秒以内40分
        } else {
            return 0.2; // 超过120秒20分
        }
    }
    
    /**
     * 获取用户渠道偏好
     */
    private double getUserChannelPreference(Long userId, String channelCode) {
        
        // 查询用户历史支付记录,计算对该渠道的偏好度
        PaymentStatistics userStats = statisticsService.getUserChannelStatistics(userId, channelCode);
        
        if (userStats.getTotalCount() == 0) {
            return 0.5; // 无历史记录,中等偏好
        }
        
        // 根据使用频率和成功率计算偏好度
        double usageFrequency = Math.min(userStats.getTotalCount() / 10.0, 1.0); // 最多10次达到满分
        double userSuccessRate = (double) userStats.getSuccessCount() / userStats.getTotalCount();
        
        return (usageFrequency * 0.3 + userSuccessRate * 0.7);
    }
    
    /**
     * 检查金额是否在范围内
     */
    private boolean isAmountInRange(PaymentChannel channel, BigDecimal amount) {
        
        BigDecimal minAmount = channel.getMinAmount();
        BigDecimal maxAmount = channel.getMaxAmount();
        
        return (minAmount == null || amount.compareTo(minAmount) >= 0) &&
               (maxAmount == null || amount.compareTo(maxAmount) <= 0);
    }
    
    /**
     * 检查地区是否支持
     */
    private boolean isRegionSupported(PaymentChannel channel, String userRegion) {
        
        if (StringUtils.isBlank(userRegion)) {
            return true; // 无地区信息,默认支持
        }
        
        List<String> supportedRegions = channel.getSupportedRegions();
        return supportedRegions == null || supportedRegions.isEmpty() || 
               supportedRegions.contains(userRegion);
    }
    
    /**
     * 检查风险等级是否可接受
     */
    private boolean isRiskLevelAcceptable(PaymentChannel channel, RiskLevel riskLevel) {
        
        RiskLevel maxAcceptableRisk = channel.getMaxAcceptableRiskLevel();
        return maxAcceptableRisk == null || riskLevel.ordinal() <= maxAcceptableRisk.ordinal();
    }
    
    /**
     * 检查渠道健康状态
     */
    private boolean isChannelHealthy(PaymentChannel channel) {
        
        String healthKey = "channel_health:" + channel.getChannelCode();
        Boolean isHealthy = (Boolean) redisTemplate.opsForValue().get(healthKey);
        
        if (isHealthy != null) {
            return isHealthy;
        }
        
        // 检查渠道健康状态(成功率、响应时间等)
        boolean healthy = checkChannelHealth(channel);
        
        // 缓存1分钟
        redisTemplate.opsForValue().set(healthKey, healthy, Duration.ofMinutes(1));
        
        return healthy;
    }
    
    /**
     * 检查渠道健康状态
     */
    private boolean checkChannelHealth(PaymentChannel channel) {
        
        // 检查最近5分钟的成功率
        Instant startTime = Instant.now().minus(Duration.ofMinutes(5));
        PaymentStatistics recentStats = statisticsService.getChannelStatistics(
            channel.getChannelCode(), startTime, Instant.now());
        
        if (recentStats.getTotalCount() == 0) {
            return true; // 无交易记录,认为健康
        }
        
        double recentSuccessRate = (double) recentStats.getSuccessCount() / recentStats.getTotalCount();
        
        // 成功率低于50%认为不健康
        return recentSuccessRate >= 0.5;
    }
    
    /**
     * 获取备选渠道
     */
    private List<String> getAlternativeChannels(List<ChannelScore> channelScores, ChannelScore selectedChannel) {
        
        return channelScores.stream()
            .filter(score -> !score.getChannel().getChannelCode().equals(selectedChannel.getChannel().getChannelCode()))
            .sorted(Comparator.comparing(ChannelScore::getScore).reversed())
            .limit(3) // 最多3个备选渠道
            .map(score -> score.getChannel().getChannelCode())
            .collect(Collectors.toList());
    }
}

# 3. 风险控制服务

/**
 * 风险控制服务
 * 实现多维度的风险评估和反欺诈检测
 */
@Service
public class RiskControlService {
    
    private final RiskRuleEngine riskRuleEngine;
    private final FraudDetectionService fraudDetectionService;
    private final BlacklistService blacklistService;
    private final DeviceFingerprintService deviceFingerprintService;
    private final GeoLocationService geoLocationService;
    private final RiskModelService riskModelService;
    
    /**
     * 风险评估
     */
    public RiskAssessmentResult assessRisk(PaymentCreationRequest request) {
        
        log.info("开始风险评估: {}", request.getOrderId());
        
        try {
            // 1. 基础风险检查
            List<RiskFactor> riskFactors = new ArrayList<>();
            
            // 2. 黑名单检查
            BlacklistCheckResult blacklistResult = blacklistService.checkBlacklist(request);
            if (blacklistResult.isBlacklisted()) {
                riskFactors.add(RiskFactor.builder()
                    .type(RiskFactorType.BLACKLIST)
                    .severity(RiskSeverity.HIGH)
                    .description("用户在黑名单中: " + blacklistResult.getReason())
                    .score(100)
                    .build());
            }
            
            // 3. 设备指纹检查
            DeviceFingerprintResult deviceResult = deviceFingerprintService.analyzeDevice(request);
            if (deviceResult.isSuspicious()) {
                riskFactors.add(RiskFactor.builder()
                    .type(RiskFactorType.DEVICE_FINGERPRINT)
                    .severity(deviceResult.getSeverity())
                    .description("可疑设备: " + deviceResult.getReason())
                    .score(deviceResult.getRiskScore())
                    .build());
            }
            
            // 4. 地理位置检查
            GeoLocationResult geoResult = geoLocationService.analyzeLocation(request);
            if (geoResult.isAnomalous()) {
                riskFactors.add(RiskFactor.builder()
                    .type(RiskFactorType.GEO_LOCATION)
                    .severity(geoResult.getSeverity())
                    .description("异常地理位置: " + geoResult.getReason())
                    .score(geoResult.getRiskScore())
                    .build());
            }
            
            // 5. 交易行为分析
            TransactionBehaviorResult behaviorResult = analyzeTransactionBehavior(request);
            if (behaviorResult.isAnomalous()) {
                riskFactors.add(RiskFactor.builder()
                    .type(RiskFactorType.TRANSACTION_BEHAVIOR)
                    .severity(behaviorResult.getSeverity())
                    .description("异常交易行为: " + behaviorResult.getReason())
                    .score(behaviorResult.getRiskScore())
                    .build());
            }
            
            // 6. 机器学习模型评分
            MLModelResult mlResult = riskModelService.predict(request);
            if (mlResult.getRiskScore() > 0.7) {
                riskFactors.add(RiskFactor.builder()
                    .type(RiskFactorType.ML_MODEL)
                    .severity(RiskSeverity.MEDIUM)
                    .description("机器学习模型识别为高风险")
                    .score((int) (mlResult.getRiskScore() * 100))
                    .build());
            }
            
            // 7. 规则引擎评估
            RuleEngineResult ruleResult = riskRuleEngine.evaluate(request, riskFactors);
            riskFactors.addAll(ruleResult.getAdditionalRiskFactors());
            
            // 8. 计算综合风险评分
            int totalRiskScore = calculateTotalRiskScore(riskFactors);
            RiskLevel riskLevel = determineRiskLevel(totalRiskScore);
            
            // 9. 生成风险评估结果
            RiskAssessmentResult result = RiskAssessmentResult.builder()
                .riskLevel(riskLevel)
                .riskScore(totalRiskScore)
                .riskFactors(riskFactors)
                .recommendation(generateRiskRecommendation(riskLevel, riskFactors))
                .assessmentTime(Instant.now())
                .build();
            
            log.info("风险评估完成: {}, 风险等级: {}, 评分: {}", 
                request.getOrderId(), riskLevel, totalRiskScore);
            
            return result;
            
        } catch (Exception e) {
            log.error("风险评估失败: {}", request.getOrderId(), e);
            
            // 发生异常时返回高风险
            return RiskAssessmentResult.builder()
                .riskLevel(RiskLevel.HIGH)
                .riskScore(100)
                .riskFactors(Arrays.asList(
                    RiskFactor.builder()
                        .type(RiskFactorType.SYSTEM_ERROR)
                        .severity(RiskSeverity.HIGH)
                        .description("风险评估系统异常: " + e.getMessage())
                        .score(100)
                        .build()
                ))
                .recommendation(RiskRecommendation.REJECT)
                .assessmentTime(Instant.now())
                .build();
        }
    }
    
    /**
     * 交易行为分析
     */
    private TransactionBehaviorResult analyzeTransactionBehavior(PaymentCreationRequest request) {
        
        List<String> anomalies = new ArrayList<>();
        int riskScore = 0;
        
        // 1. 检查交易金额异常
        BigDecimal avgAmount = getUserAverageTransactionAmount(request.getUserId());
        if (avgAmount != null && request.getAmount().compareTo(avgAmount.multiply(new BigDecimal("5"))) > 0) {
            anomalies.add("交易金额异常偏高");
            riskScore += 30;
        }
        
        // 2. 检查交易频率异常
        int recentTransactionCount = getUserRecentTransactionCount(request.getUserId(), Duration.ofHours(1));
        if (recentTransactionCount > 10) {
            anomalies.add("交易频率异常偏高");
            riskScore += 40;
        }
        
        // 3. 检查交易时间异常
        LocalTime transactionTime = LocalTime.now();
        if (transactionTime.isBefore(LocalTime.of(6, 0)) || transactionTime.isAfter(LocalTime.of(23, 0))) {
            anomalies.add("非正常交易时间");
            riskScore += 20;
        }
        
        // 4. 检查新用户大额交易
        if (isNewUser(request.getUserId()) && request.getAmount().compareTo(new BigDecimal("1000")) > 0) {
            anomalies.add("新用户大额交易");
            riskScore += 50;
        }
        
        RiskSeverity severity = riskScore > 70 ? RiskSeverity.HIGH : 
                               riskScore > 40 ? RiskSeverity.MEDIUM : RiskSeverity.LOW;
        
        return TransactionBehaviorResult.builder()
            .isAnomalous(!anomalies.isEmpty())
            .reason(String.join(", ", anomalies))
            .riskScore(riskScore)
            .severity(severity)
            .build();
    }
    
    /**
     * 计算总风险评分
     */
    private int calculateTotalRiskScore(List<RiskFactor> riskFactors) {
        
        if (riskFactors.isEmpty()) {
            return 0;
        }
        
        // 使用加权平均算法,高严重性的风险因子权重更大
        double totalWeightedScore = 0.0;
        double totalWeight = 0.0;
        
        for (RiskFactor factor : riskFactors) {
            double weight = getFactorWeight(factor.getSeverity());
            totalWeightedScore += factor.getScore() * weight;
            totalWeight += weight;
        }
        
        return totalWeight > 0 ? (int) (totalWeightedScore / totalWeight) : 0;
    }
    
    /**
     * 获取风险因子权重
     */
    private double getFactorWeight(RiskSeverity severity) {
        switch (severity) {
            case HIGH:
                return 3.0;
            case MEDIUM:
                return 2.0;
            case LOW:
                return 1.0;
            default:
                return 1.0;
        }
    }
    
    /**
     * 确定风险等级
     */
    private RiskLevel determineRiskLevel(int riskScore) {
        if (riskScore >= 80) {
            return RiskLevel.HIGH;
        } else if (riskScore >= 50) {
            return RiskLevel.MEDIUM;
        } else {
            return RiskLevel.LOW;
        }
    }
    
    /**
     * 生成风险建议
     */
    private RiskRecommendation generateRiskRecommendation(RiskLevel riskLevel, List<RiskFactor> riskFactors) {
        
        switch (riskLevel) {
            case HIGH:
                return RiskRecommendation.REJECT;
            case MEDIUM:
                // 检查是否有高严重性的风险因子
                boolean hasHighSeverityFactor = riskFactors.stream()
                    .anyMatch(factor -> factor.getSeverity() == RiskSeverity.HIGH);
                return hasHighSeverityFactor ? RiskRecommendation.MANUAL_REVIEW : RiskRecommendation.ADDITIONAL_VERIFICATION;
            case LOW:
                return RiskRecommendation.APPROVE;
            default:
                return RiskRecommendation.MANUAL_REVIEW;
        }
    }
    
    /**
     * 获取用户平均交易金额
     */
    private BigDecimal getUserAverageTransactionAmount(Long userId) {
        // 查询用户最近30天的平均交易金额
        // 这里简化实现
        return new BigDecimal("500");
    }
    
    /**
     * 获取用户最近交易次数
     */
    private int getUserRecentTransactionCount(Long userId, Duration duration) {
        // 查询用户在指定时间内的交易次数
        // 这里简化实现
        return 3;
    }
    
    /**
     * 检查是否为新用户
     */
    private boolean isNewUser(Long userId) {
        // 检查用户注册时间是否在7天内
        // 这里简化实现
        return false;
    }
}