S SmartDocs
系列: Bridget java 73 行 · 更新于 2026-05-08

FraudEngine.java

Bridget/payment-gateway-microservices/services/fraud-check-service/src/main/java/com/checkout/paymentgw/fraud/engine/FraudEngine.java

package com.checkout.paymentgw.fraud.engine;

import com.checkout.paymentgw.fraud.api.FraudCheckController.Decision;
import com.checkout.paymentgw.fraud.api.FraudCheckController.ScreenRequest;
import com.checkout.paymentgw.fraud.domain.BlockedBin;
import com.checkout.paymentgw.fraud.domain.BlockedBinRepository;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class FraudEngine {

    private final BlockedBinRepository blockedBins;
    private final StringRedisTemplate redis;
    private final int velocityLimit;
    private final Duration velocityWindow;
    private final int amountThreshold;

    public FraudEngine(BlockedBinRepository blockedBins,
                       StringRedisTemplate redis,
                       @Value("${fraud.velocity.limit:5}") int velocityLimit,
                       @Value("${fraud.velocity.window-seconds:60}") long windowSeconds,
                       @Value("${fraud.amount.threshold:1000000}") int amountThreshold) {
        this.blockedBins = blockedBins;
        this.redis = redis;
        this.velocityLimit = velocityLimit;
        this.velocityWindow = Duration.ofSeconds(windowSeconds);
        this.amountThreshold = amountThreshold;
    }

    public Decision evaluate(String merchantId, ScreenRequest request) {
        List<String> reasons = new ArrayList<>();
        String decision = "ALLOW";

        // 1. BIN blacklist
        String bin = request.cardNumber().substring(0, Math.min(6, request.cardNumber().length()));
        Optional<BlockedBin> hit = blockedBins.findById(bin);
        if (hit.isPresent()) {
            reasons.add("BIN_BLOCKED:" + bin);
            decision = "BLOCK";
        }

        // 2. Velocity (per-merchant attempts in a sliding window)
        long count = bumpAndGetVelocity(merchantId);
        if (count > velocityLimit) {
            reasons.add("VELOCITY_EXCEEDED:" + count);
            if (!"BLOCK".equals(decision)) decision = "REVIEW";
        }

        // 3. Amount threshold
        if (request.amount() != null && request.amount() > amountThreshold) {
            reasons.add("AMOUNT_THRESHOLD:" + request.amount());
            if (!"BLOCK".equals(decision)) decision = "REVIEW";
        }

        return new Decision(decision, reasons);
    }

    private long bumpAndGetVelocity(String merchantId) {
        String key = "vel:" + merchantId;
        Long c = redis.opsForValue().increment(key);
        if (c != null && c == 1L) {
            redis.expire(key, velocityWindow);
        }
        return c == null ? 0L : c;
    }
}

相关文章

Bridget java 更新于 2026-03-30

PaymentGatewayApplication.java

PaymentGatewayApplication.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/PaymentGatewayApplication.java).

阅读文章 →
Bridget java 更新于 2026-03-20

ApplicationConfiguration.java

ApplicationConfiguration.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/configuration/ApplicationConfiguration.java).

阅读文章 →
Bridget java 更新于 2026-03-30

RequestResponseLogger.java

RequestResponseLogger.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/configuration/RequestResponseLogger.java).

阅读文章 →
Bridget java 更新于 2026-04-14

PaymentGatewayController.java

PaymentGatewayController.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/controller/PaymentGatewayController.java).

阅读文章 →
Bridget java 更新于 2026-03-20

PaymentStatus.java

PaymentStatus.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/enums/PaymentStatus.java).

阅读文章 →
Bridget java 更新于 2026-03-29

BankErrorException.java

BankErrorException.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/exception/BankErrorException.java).

阅读文章 →