Architecture note for developers: All 55 checks must complete within a 1-2 second total verdict window. The existing 37 checks already run in parallel across 7 categories. The 18 new international checks must follow the same parallel execution model - they do not run sequentially. Each check is a stateless microservice that receives the transaction payload, runs its evaluation, and returns a 0-100 risk score + pass/fail flag within its SLA window. Hard blocks (sanctions hits, OFAC, hard fraud indicators) short-circuit the pipeline immediately and return NO without waiting for all 55 checks to complete.
Latency Strategy: How to Keep All 55 Checks Under 2 Seconds
Parallel Execution Tiers
Tier 1 - Synchronous hard blocks (must complete, <100ms)
- OFAC / EU / UN / HMT / CIPS sanctions screening (cached, in-memory bloom filter updated every 5 minutes from SDN list)
- IBAN checksum validation (pure algorithmic, no external call)
- Routing number / BIC format validation (local lookup table)
Tier 2 - Parallel async checks (<800ms, all fire simultaneously)
- All identity, behavioral, velocity, and rail-specific checks
- External API calls (GLEIF, OpenCorporates, DNS validation, registry lookups)
- Each check has a 750ms timeout; if timeout exceeded, check returns REVIEW signal rather than blocking verdict
Tier 3 - Post-verdict enrichment (<200ms after verdict issued)
- Correspondent chain depth analysis (can be done after verdict is sealed for logging)
- Cross-jurisdiction typology correlation (pattern match against typology library, async write to audit log)
Caching Strategy
- Sanctions lists: Redis in-memory, refreshed every 5 minutes via background job. Never make a live HTTP call to OFAC at verdict time.
- BIC/SWIFT routing table: PostgreSQL local copy, updated nightly from SWIFT BIC directory
- GLEIF LEI data: Local copy updated daily. Cache entity records for 24 hours.
- OpenCorporates: Cache company verification for 48 hours per entity
- DNS/DMARC checks: Cache per domain for 1 hour
Hard budget per external API call: 400ms max. Any integration that cannot reliably return in 400ms must be pre-cached or removed from the synchronous verdict path.
Existing 37 Checks (Reference - No Changes)
Category 1: Identity & Counterparty Integrity (6 checks, Weight: 20%)
- UBO verification
- Synthetic identity detection
- Account-to-name validation
- Real-time sanctions screening (OFAC/EU/UN/HMT)
- Deepfake detection
- Corporate synthetic fraud
Category 2: Payment Rail-Specific Fraud (8 checks, Weight: 20%)
- BEC detection
- Invoice fraud
- Account takeover
- Processor impersonation
- ACH unauthorized return risk
- APP scam detection
- Check fraud (MICR validation)
- Wire transfer anomaly
Category 3: Regulatory Compliance Flags (6 checks, Weight: 15%)
- Real-time sanctions screening
- AML typology detection
- OFAC jurisdiction screening
- GENIUS Act compliance
- BSA/SAR trigger detection
- CTR filing detection
Category 4: Transaction Behavior & Velocity (6 checks, Weight: 15%)
- Velocity anomaly (1h/24h/7d windows)
- Mule account scoring
- High-volume low-value detection
- Smurfing/structuring ($10K threshold)
- Geographic anomaly
- First-party fraud
Category 5: Settlement Instruction Integrity (4 checks, Weight: 15%)
- Routing/account change detection with 72-hour hold
- Beneficiary age scoring
- Instruction provenance attestation (hash at initiation vs settlement)
- Entity validation via credential registry
Category 6: Healthcare & Government Rails (5 checks, Weight: 5%)
- Duplicate claims detection
- Provider NPI enrollment verification
- Upcoding detection
- Remittance mismatch analysis
- Overpayment recovery tracking
Category 7: Macro & Systemic Flags (4 checks, Weight: 10%)
- Fraud ring graph analysis (IP/device/account clustering)
- Typology sharing pattern library
- Cross-rail correlation
- Four-rail coverage verification per OCC/FDIC/Fed mandate
NOTE: Check numbering above reflects 37 checks in 7 categories. The following 18 new checks bring the total to 55 across 8 categories.
New International Checks: 18 Additions Across 8 Categories
The following sections detail each new check with implementation code, verdict contribution logic, and API/data source references.
Category 2 (Expanded): Payment Rail-Specific Fraud
Adding 7 checks - new total: 15 checks in this category.
Check 38: SEPA Instant / SCT Inst APP Scam Detection
What it does: Detects Authorized Push Payment scams on SEPA Instant Credit Transfer (SCT Inst) and standard SEPA Credit Transfer rails. Scores for behavioral indicators: new beneficiary + large amount, unusually rapid initiation sequence, beneficiary account age under 90 days, amount inconsistent with originator's corridor baseline.
Implementation
// sepa-app-detection.service.ts
interface SEPAAppCheck {
iban: string;
amount: number;
currency: string;
originatorAccountAge: number; // days
beneficiaryAccountAge: number; // days - retrieved from BID registry
isFirstTransferToBeneficiary: boolean;
initiationToAuthorizationMs: number; // time pressure indicator
}
async function checkSEPAAppScam(tx: SEPAAppCheck): Promise<CheckResult> {
let score = 0;
// New beneficiary + high amount
if (tx.isFirstTransferToBeneficiary && tx.amount > 1000) score += 30;
// Very new receiving account
if (tx.beneficiaryAccountAge < 7) score += 50; // hard flag
else if (tx.beneficiaryAccountAge < 90) score += 20;
// Unusually rapid authorization (social engineering indicator)
if (tx.initiationToAuthorizationMs < 30000) score += 15; // under 30 seconds
// Amount vs originator baseline (pull from velocity/behavioral history)
const baseline = await getOriginatorCorridorBaseline(tx.iban);
if (tx.amount > baseline.p95Amount * 2) score += 25;
return { checkId: 'SEPA_APP', score: Math.min(score, 100), hardBlock: score >= 50 && tx.beneficiaryAccountAge < 7 };
}
Data Sources
- Beneficiary account age: EBA RT1 system does not expose directly - source from BID registry or partner bank API. PSD2 open banking APIs (Berlin Group PSD2 standard) expose account verification endpoints.
- Berlin Group NextGenPSD2 spec: berlin-group.org
- EBA SCT Inst rulebook: europeanpaymentscouncil.eu
Check 39: UK Faster Payments APP Fraud Detection (PSR Mandate)
What it does: Implements UK Payment Systems Regulator (PSR) APP fraud detection requirements effective October 2024. The PSR mandates that all Faster Payments participants score and reimburse APP fraud. This check flags high-risk FPS transactions using PSR-defined typologies: investment scams, romance scams, impersonation of HMRC/banks/police, purchase scams.
Implementation
// uk-fps-psr.service.ts
// PSR requires firms to use the Confirmation of Payee (CoP) service
// CoP is operated by Pay.UK - integration is mandatory for UK FPS participants
import { CoPClient } from '@payuk/cop-client'; // Pay.UK CoP API
async function checkUKFasterPayments(tx: FPSTransaction): Promise<CheckResult> {
// Step 1: Confirmation of Payee check (mandatory for UK)
const copResult = await CoPClient.verify({
accountNumber: tx.beneficiaryAccount,
sortCode: tx.beneficiarySortCode,
name: tx.beneficiaryName,
accountType: tx.accountType
});
// CoP returns: MATCH, CLOSE_MATCH, NO_MATCH, UNAVAILABLE
let score = 0;
if (copResult.result === 'NO_MATCH') score += 60;
else if (copResult.result === 'CLOSE_MATCH') score += 25;
// Step 2: PSR typology scoring
const typologyScore = await scorePSRTypologies(tx);
score += typologyScore;
return {
checkId: 'UK_FPS_PSR',
score: Math.min(score, 100),
hardBlock: copResult.result === 'NO_MATCH' && tx.amount > 10000,
regulatoryBasis: 'UK PSR APP Fraud Mandate 2024'
};
}
APIs and References
- Pay.UK Confirmation of Payee (CoP): payuk.co.uk
- CoP API documentation (requires Pay.UK membership): developer.payuk.co.uk
- PSR APP fraud requirements: psr.org.uk
- UK Finance APP fraud typology library: ukfinance.org.uk
Check 40: PIX (Brazil) Social Engineering / Device Hijack Detection
What it does: PIX is Brazil's instant payment rail operated by the Banco Central do Brasil (BCB). PIX fraud is dominated by social engineering (golpe do PIX) and device compromise leading to unauthorized transfers. This check scores for: device fingerprint inconsistency, unusual time-of-day for originator, new device + large transfer, and BCB-flagged high-risk key types.
Implementation
// pix-fraud.service.ts
// BCB operates the DICT (Diretorio de Identificadores de Transacoes do Pix)
// Access requires BCB participant registration
async function checkPIX(tx: PIXTransaction): Promise<CheckResult> {
let score = 0;
// Query BCB DICT for key validation
const dictResult = await queryBCBDict(tx.pixKey);
if (!dictResult.isRegistered) return { checkId: 'PIX_FRAUD', score: 95, hardBlock: true };
if (dictResult.keyAge < 7) score += 40; // new PIX key
// Device fingerprint check
if (tx.deviceId !== tx.originatorProfile.knownDeviceId) score += 35;
// BCB high-risk window (after 20:00, before 06:00 local Brazil time)
const brTime = new Date(tx.timestamp).toLocaleString('pt-BR', { timeZone: 'America/Sao_Paulo' });
const hour = new Date(brTime).getHours();
if (hour >= 20 || hour < 6) score += 15;
// BCB Pix Limit for after-hours (BCB mandates BRL 1,000 limit after 20:00 for individuals)
if ((hour >= 20 || hour < 6) && tx.amount > 1000 && tx.accountType === 'individual') {
return { checkId: 'PIX_FRAUD', score: 90, hardBlock: true, reason: 'BCB_AFTER_HOURS_LIMIT_EXCEEDED' };
}
return { checkId: 'PIX_FRAUD', score: Math.min(score, 100), hardBlock: false };
}
APIs and References
- BCB DICT API (requires BCB participant credentials): bcb.gov.br
- BCB Pix developer docs: bacen.github.io/pix-api
- BCB Open Data (public fraud statistics): dadosabertos.bcb.gov.br
- SFN participant registration: bcb.gov.br
Check 41: UPI (India) Fake Collect Request / QR Code Spoofing Detection
What it does: India's Unified Payments Interface (UPI) has two distinct fraud vectors: (1) fake collect requests - fraudster sends a collect/pull request disguised as a payment, tricking the victim into entering their PIN; (2) QR code spoofing - legitimate merchant QR replaced with attacker's VPA. This check validates that the transaction is a genuine push (pay) not a fraudulent pull (collect), and screens the beneficiary VPA against NPCI's known-fraud VPA database.
Implementation
// upi-fraud.service.ts
// NPCI (National Payments Corporation of India) - VPA validation
// Access via partner PSP (Payment Service Provider) registration with NPCI
async function checkUPI(tx: UPITransaction): Promise<CheckResult> {
let score = 0;
// Validate VPA format and existence
const vpaValid = await validateVPA(tx.beneficiaryVPA); // NPCI PSP API
if (!vpaValid.exists) return { checkId: 'UPI_FRAUD', score: 95, hardBlock: true };
// Collect request fraud: flag high-value collect requests from unverified VPAs
if (tx.transactionType === 'COLLECT' && !vpaValid.isVerifiedMerchant) {
score += 50;
if (tx.amount > 10000) score += 30; // INR 10,000 threshold
}
// QR code transaction: verify merchant VPA against NPCI merchant registry
if (tx.initiationMode === 'QR_CODE') {
const merchantVerified = await verifyMerchantVPA(tx.beneficiaryVPA);
if (!merchantVerified) score += 40;
}
// Check against NPCI fraud VPA database (partner API access required)
const fraudFlagged = await checkNPCIFraudDatabase(tx.beneficiaryVPA);
if (fraudFlagged) return { checkId: 'UPI_FRAUD', score: 100, hardBlock: true, reason: 'NPCI_FRAUD_VPA' };
return { checkId: 'UPI_FRAUD', score: Math.min(score, 100), hardBlock: false };
}
APIs and References
- NPCI UPI API documentation (requires PSP/TPAP registration): npci.org.in
- NPCI developer portal: developer.npci.org.in
- UPI fraud reporting API: Available through NPCI member PSP access only - requires formal onboarding
- RBI fraud reporting: rbi.org.in
Check 42: SWIFT gpi Intermediary Chain Substitution Detection
What it does: SWIFT gpi (Global Payments Innovation) introduced end-to-end tracking for cross-border wires. The primary fraud vector is MT103 instruction manipulation at an intermediary bank - the beneficiary account or bank is substituted mid-route. This check validates that the correspondent chain observed at settlement matches the chain declared at initiation, using SWIFT gpi tracker data.
Implementation
// swift-gpi-chain.service.ts
// SWIFT gpi Tracker API - requires SWIFT connectivity (Service Bureau or direct)
async function checkSWIFTChainIntegrity(tx: SWIFTTransaction): Promise<CheckResult> {
// Retrieve gpi tracker status for this UETR
const gpiStatus = await SWIFTGPIClient.getTrackerStatus(tx.uetr);
// Check if the payment chain matches what was declared at initiation
const declaredChain = tx.instructedCorrespondentBICs; // from MT103 field 56a/57a
const actualChain = gpiStatus.transactionTrackingData.map(hop => hop.institutionBIC);
const chainMismatch = !arraysEqual(declaredChain, actualChain);
const beneficiaryMismatch = gpiStatus.finalBeneficiaryBIC !== tx.instructedBeneficiaryBIC;
let score = 0;
if (chainMismatch) score += 45;
if (beneficiaryMismatch) score += 70; // hard escalation
// Hop count anomaly: more intermediaries than corridor baseline
const corridorBaseline = await getCorridorHopBaseline(tx.originCountry, tx.destinationCountry);
if (actualChain.length > corridorBaseline.p90HopCount + 2) score += 30;
return {
checkId: 'SWIFT_GPI_CHAIN',
score: Math.min(score, 100),
hardBlock: beneficiaryMismatch,
reason: beneficiaryMismatch ? 'BENEFICIARY_BIC_SUBSTITUTION' : chainMismatch ? 'CHAIN_MODIFICATION' : null
};
}
APIs and References
- SWIFT gpi Tracker API: developer.swift.com
- SWIFT Developer Portal (requires connectivity): developer.swift.com
- SWIFT Service Bureau list: swift.com
- SWIFT BIC Directory (for local copy): swift.com
Check 43: CIPS Sanctioned-Entity Intermediary Routing Detection
What it does: CIPS (Cross-Border Interbank Payment System) is China's USD/CNY cross-border settlement network. Fraud vector: transactions involving sanctioned entities routed through CIPS using non-sanctioned intermediary banks to obscure the ultimate originator or beneficiary. This check validates the full legal entity chain against US OFAC SDN, EU consolidated list, and UN Security Council sanctions, including secondary sanction risk under OFAC's 50% ownership rule.
Implementation
// cips-sanctions.service.ts
// CIPS participant list is publicly available from PBOC
// Sanctions lists: OFAC SDN (daily), EU consolidated (daily), UN Security Council (daily)
async function checkCIPSSanctions(tx: CIPSTransaction): Promise<CheckResult> {
// Build full entity chain: originator -> instructing institution -> CIPS participant -> beneficiary
const entityChain = [
tx.originator,
tx.instructingInstitution,
...tx.cipsParticipantChain,
tx.ultimateBeneficiary
];
// Screen all entities against all lists in parallel
const screeningResults = await Promise.all(
entityChain.map(entity => screenEntityAllLists(entity))
);
// Any hard hit = immediate NO
const hardHit = screeningResults.find(r => r.isMatch);
if (hardHit) {
return { checkId: 'CIPS_SANCTIONS', score: 100, hardBlock: true,
reason: `SANCTIONS_MATCH: ${hardHit.listSource} ${hardHit.matchedEntry}` };
}
// Secondary sanction risk: is any CIPS participant from a high-risk jurisdiction?
const highRiskJurisdictions = ['IR', 'KP', 'RU', 'BY', 'SY', 'CU', 'VE']; // OFAC priority
const jurisdictionRisk = tx.cipsParticipantChain.some(
p => highRiskJurisdictions.includes(p.countryCode)
);
return {
checkId: 'CIPS_SANCTIONS',
score: jurisdictionRisk ? 55 : 0,
hardBlock: false,
reason: jurisdictionRisk ? 'HIGH_RISK_JURISDICTION_IN_CHAIN' : null
};
}
Data Sources
- CIPS participant list: cips.com.cn
- OFAC SDN list (download daily): treasury.gov
- OFAC SDN API (real-time, rate-limited): ofac.treasury.gov
- EU consolidated sanctions: eeas.europa.eu
- UN Security Council consolidated list: un.org
- OpenSanctions (aggregated): opensanctions.org
- Recommended: Use OpenSanctions Yente as your primary sanctions screening engine - it aggregates OFAC, EU, UN, HMT, and 30+ additional lists into one API with sub-100ms response time when self-hosted.
Check 44: NPP (Australia) PayID Spoofing Detection
What it does: Australia's New Payments Platform (NPP) uses PayID (email, phone, ABN, or org ID) as a human-readable alias for BSB/account numbers. Fraud vector: attackers register a PayID that closely resembles a legitimate merchant or individual (lookalike spoofing), or intercept a PayID resolution to redirect funds. This check validates the PayID resolution chain and scores for lookalike patterns.
Implementation
// npp-payid.service.ts
// NPP PayID validation requires NPPA participant access
// Lookalike detection: Levenshtein distance on resolved name vs expected name
import { levenshtein } from 'fastest-levenshtein';
async function checkNPPPayID(tx: NPPTransaction): Promise<CheckResult> {
let score = 0;
if (!tx.payId) return { checkId: 'NPP_PAYID', score: 0, hardBlock: false }; // not a PayID tx
// Resolve PayID and get registration metadata
const payIdRecord = await NPPAClient.resolvePayID(tx.payId);
if (!payIdRecord.found) return { checkId: 'NPP_PAYID', score: 85, hardBlock: true, reason: 'PAYID_NOT_FOUND' };
// Age check
const agedays = daysBetween(payIdRecord.registrationDate, new Date());
if (agedays < 7) score += 60;
else if (agedays < 30) score += 25;
// Lookalike check: resolved name vs expected beneficiary name
if (tx.expectedBeneficiaryName) {
const distance = levenshtein(
payIdRecord.displayName.toLowerCase(),
tx.expectedBeneficiaryName.toLowerCase()
);
const similarity = 1 - (distance / Math.max(
payIdRecord.displayName.length, tx.expectedBeneficiaryName.length
));
if (similarity < 0.7) score += 45; // names differ significantly
else if (similarity < 0.9) score += 20;
}
return { checkId: 'NPP_PAYID', score: Math.min(score, 100), hardBlock: score >= 85 };
}
APIs and References
- NPPA PayID public register: payid.com.au
- NPPA participant access: nppa.com.au
- NPPA API specs: Available to NPP participants - contact NPPA directly
- AusPayNet: auspaynet.com.au
Category 3 (Expanded): Regulatory Compliance Flags
Adding 4 checks - new total: 10 checks in this category.
Check 45: EU MiCA Stablecoin Issuer Validation
What it does: Under the EU Markets in Crypto-Assets Regulation (MiCA), stablecoin issuers (e-money tokens and asset-referenced tokens) must be authorized by an EU National Competent Authority (NCA). Transactions involving non-MiCA-compliant stablecoins routed through EU entities are a regulatory violation. This check validates that any stablecoin in the transaction chain is issued by a MiCA-authorized entity.
Implementation
// mica-stablecoin.service.ts
// ESMA maintains the MiCA register
// EBA maintains the EMT (e-money token) register
async function checkMiCACompliance(tx: Transaction): Promise<CheckResult> {
if (!tx.stablecoinContractAddress) return { checkId: 'MICA_STABLECOIN', score: 0, hardBlock: false };
// Query ESMA MiCA register
const micaStatus = await ESMAMiCARegistry.lookup(tx.stablecoinContractAddress);
if (!micaStatus.found) {
// Not in ESMA registry - check if transaction involves EU entities
const euEntityInvolved = await checkEUEntityInvolvement(tx);
return {
checkId: 'MICA_STABLECOIN',
score: euEntityInvolved ? 75 : 30,
hardBlock: false,
reason: 'STABLECOIN_NOT_MICA_AUTHORIZED'
};
}
if (micaStatus.isProhibited) {
return { checkId: 'MICA_STABLECOIN', score: 100, hardBlock: true, reason: 'MICA_PROHIBITED_STABLECOIN' };
}
return { checkId: 'MICA_STABLECOIN', score: 0, hardBlock: false };
}
Data Sources
- ESMA MiCA register: esma.europa.eu
- EBA register of payment/e-money institutions: eba.europa.eu
- MiCA text: eur-lex.europa.eu
- Current status (2026): MiCA stablecoin provisions (Title III/IV) effective June 2024; full application December 2024
Check 46: EU DORA Operational Resilience Attestation
What it does: The EU Digital Operational Resilience Act (DORA) requires EU financial entities and their ICT third-party service providers to meet operational resilience standards. JIL operating as ICT infrastructure for EU-regulated entities is subject to DORA. This check validates that: (1) the receiving institution is a DORA-registered EU financial entity, (2) JIL's current operational status meets DORA SLA requirements for the transaction corridor, and (3) the transaction corridor does not involve a DORA-non-compliant ICT provider.
Implementation
// dora-compliance.service.ts
// DORA applies from January 17, 2025
// ESAs (EBA, ESMA, EIOPA) maintain the ICT third-party provider register
async function checkDORACompliance(tx: Transaction): Promise<CheckResult> {
// Check if counterparty is an EU-regulated financial entity subject to DORA
const isEUFinancialEntity = await checkEUFinancialEntityStatus(tx.beneficiaryLEI);
if (!isEUFinancialEntity) return { checkId: 'DORA_COMPLIANCE', score: 0, hardBlock: false };
// Validate JIL's own DORA status (self-check)
const jilDoraStatus = await getJILDoraOperationalStatus();
if (!jilDoraStatus.compliant) {
// Internal alert - JIL operational issue, not a transaction fraud signal
await triggerInternalAlert('DORA_SELF_COMPLIANCE_DEGRADED');
return { checkId: 'DORA_COMPLIANCE', score: 0, hardBlock: false,
note: 'INTERNAL_DORA_ALERT_RAISED' };
}
// Check counterparty's critical ICT providers for known DORA issues
const ictProviders = await getEntityICTProviders(tx.beneficiaryLEI);
const nonCompliantProviders = ictProviders.filter(p => !p.doraCompliant);
return {
checkId: 'DORA_COMPLIANCE',
score: nonCompliantProviders.length > 0 ? 35 : 0,
hardBlock: false,
complianceNote: `DORA check: ${nonCompliantProviders.length} non-compliant ICT providers`
};
}
Data Sources
- DORA text: eur-lex.europa.eu
- EBA DORA implementation: eba.europa.eu
- ESA ICT third-party provider register (in development for 2025): Monitor EBA/ESMA/EIOPA sites
- DORA RTS/ITS standards: eba.europa.eu
Check 47: UK FCA Authorization Verification
What it does: The UK Financial Conduct Authority (FCA) maintains a public register of all authorized and registered firms. Any UK-touching payment should involve only FCA-authorized counterparties. This check queries the FCA Financial Services Register in real time to verify that the counterparty institution (for UK transactions) is authorized and not subject to a current FCA warning, restriction, or cancellation.
Implementation
// fca-authorization.service.ts
// FCA Register API is publicly available with no authentication required
// Rate limit: 60 requests/minute on free tier
const FCA_REGISTER_API = 'https://register.fca.org.uk/services/V0.1/Firm';
const FCA_WARNING_LIST_API = 'https://register.fca.org.uk/services/V0.1/Warning';
async function checkFCAAuthorization(tx: Transaction): Promise<CheckResult> {
if (!isUKTransaction(tx)) return { checkId: 'FCA_AUTH', score: 0, hardBlock: false };
const firmRef = tx.beneficiaryFCAReference || await lookupFCAByName(tx.beneficiaryName);
if (!firmRef) return { checkId: 'FCA_AUTH', score: 40, hardBlock: false, reason: 'FCA_REF_NOT_FOUND' };
// Query FCA register
const [firmStatus, warningStatus] = await Promise.all([
fetch(`${FCA_REGISTER_API}/${firmRef}`).then(r => r.json()),
fetch(`${FCA_WARNING_LIST_API}?q=${encodeURIComponent(tx.beneficiaryName)}`).then(r => r.json())
]);
if (warningStatus.Data?.length > 0) {
return { checkId: 'FCA_AUTH', score: 100, hardBlock: true, reason: 'FCA_WARNING_LIST_MATCH' };
}
if (firmStatus.Data?.[0]?.Status === 'Cancelled' ||
firmStatus.Data?.[0]?.Status === 'No Longer Authorised') {
return { checkId: 'FCA_AUTH', score: 100, hardBlock: true, reason: 'FCA_AUTHORIZATION_CANCELLED' };
}
return { checkId: 'FCA_AUTH', score: firmStatus.Data?.length === 0 ? 50 : 0, hardBlock: false };
}
APIs (all public, no auth required)
- FCA Financial Services Register: register.fca.org.uk
- FCA Register API docs: register.fca.org.uk/developer
- FCA Warning List: fca.org.uk
- FCA API base:
https://register.fca.org.uk/services/V0.1/
Check 48: International Travel Rule Threshold Compliance (FATF / Non-US)
What it does: The FATF Travel Rule requires Virtual Asset Service Providers (VASPs) to share originator and beneficiary information for transfers above threshold. The US FinCEN threshold is USD 3,000 (already in GENIUS Act check). This check covers non-US FATF thresholds: EU/MiCA threshold EUR 1,000 (no minimum for crypto under MiCA); Singapore MAS threshold SGD 1,500; Switzerland FINMA threshold CHF 1,000; UAE VARA threshold AED 3,500; Japan FSA threshold JPY 100,000.
Implementation
// international-travel-rule.service.ts
// Travel Rule protocol options: TRP, TRISA, OpenVASP, Sygna Bridge
// JIL should support at minimum TRISA and Sygna Bridge for broad coverage
const TRAVEL_RULE_THRESHOLDS: Record<string, { currency: string; amount: number; framework: string }> = {
EU: { currency: 'EUR', amount: 1000, framework: 'MiCA_TFR' },
SG: { currency: 'SGD', amount: 1500, framework: 'MAS_PSN02' },
CH: { currency: 'CHF', amount: 1000, framework: 'FINMA_AMLA' },
AE: { currency: 'AED', amount: 3500, framework: 'VARA_2023' },
JP: { currency: 'JPY', amount: 100000, framework: 'FSA_PSA' },
GB: { currency: 'GBP', amount: 1000, framework: 'FCA_MLRS' },
US: { currency: 'USD', amount: 3000, framework: 'FINCEN_BSA' }
};
async function checkInternationalTravelRule(tx: Transaction): Promise<CheckResult> {
const jurisdiction = getApplicableJurisdiction(tx);
const threshold = TRAVEL_RULE_THRESHOLDS[jurisdiction];
if (!threshold) return { checkId: 'INTL_TRAVEL_RULE', score: 0, hardBlock: false };
const amountInLocalCurrency = await convertToLocalCurrency(tx.amount, tx.currency, threshold.currency);
if (amountInLocalCurrency < threshold.amount) return { checkId: 'INTL_TRAVEL_RULE', score: 0, hardBlock: false };
// Above threshold - check if Travel Rule data is present
const hasTravelRuleData = tx.travelRulePayload && isTravelRulePayloadValid(tx.travelRulePayload);
if (!hasTravelRuleData) {
return {
checkId: 'INTL_TRAVEL_RULE',
score: 70,
hardBlock: false,
reason: `TRAVEL_RULE_DATA_MISSING: ${threshold.framework} threshold ${threshold.amount} ${threshold.currency} exceeded`
};
}
return { checkId: 'INTL_TRAVEL_RULE', score: 0, hardBlock: false };
}
APIs and References
- TRISA: trisa.io / developer.trisa.io
- Sygna Bridge API: sygna.io
- TRP (Travel Rule Protocol): travelruleprotocol.org
- FATF Travel Rule guidance: fatf-gafi.org
- MiCA Transfer of Funds Regulation: eur-lex.europa.eu
- MAS PSN02: mas.gov.sg
- FINMA circular 2016/7: finma.ch
Category 5 (Expanded): Settlement Instruction Integrity
Adding 2 checks - new total: 6 checks in this category.
Check 49: IBAN Integrity & Beneficiary Binding Check
What it does: IBAN fraud is the dominant instruction-manipulation vector across SEPA and global USD correspondent banking. This check: (1) validates IBAN checksum algorithmically; (2) validates that the resolved account holder name matches the declared beneficiary name (IBAN name check - now mandatory for SEPA under PSD2 CoP-equivalent schemes); (3) detects BIC-to-IBAN country mismatch (a layering indicator); (4) flags IBANs associated with known money mule accounts via shared fraud intelligence networks.
Implementation
// iban-integrity.service.ts
// IBAN validation: algorithmic (no external call needed for checksum)
// Name check: SEPA CoP equivalent varies by country
// Mule database: Seon, Emailage, or shared fraud consortium databases
function validateIBANChecksum(iban: string): boolean {
// ISO 13616 IBAN validation
const cleaned = iban.replace(/\s/g, '').toUpperCase();
const rearranged = cleaned.slice(4) + cleaned.slice(0, 4);
const numeric = rearranged.split('').map(c =>
isNaN(Number(c)) ? (c.charCodeAt(0) - 55).toString() : c
).join('');
let remainder = 0;
for (const chunk of numeric.match(/.{1,9}/g) || []) {
remainder = parseInt(remainder.toString() + chunk) % 97;
}
return remainder === 1;
}
async function checkIBANIntegrity(tx: Transaction): Promise<CheckResult> {
if (!tx.beneficiaryIBAN) return { checkId: 'IBAN_INTEGRITY', score: 0, hardBlock: false };
// 1. Checksum validation (local, sub-1ms)
if (!validateIBANChecksum(tx.beneficiaryIBAN)) {
return { checkId: 'IBAN_INTEGRITY', score: 100, hardBlock: true, reason: 'IBAN_CHECKSUM_FAIL' };
}
// 2. BIC country vs IBAN country consistency
const ibanCountry = tx.beneficiaryIBAN.slice(0, 2);
const bicCountry = tx.beneficiaryBIC?.slice(4, 6);
if (bicCountry && bicCountry !== ibanCountry) {
return { checkId: 'IBAN_INTEGRITY', score: 75, hardBlock: false, reason: 'BIC_IBAN_COUNTRY_MISMATCH' };
}
// 3. Name check (SEPA CoP / EPC CoP scheme)
if (tx.beneficiaryName) {
const nameCheckResult = await SEPACoPClient.verifyName({
iban: tx.beneficiaryIBAN,
name: tx.beneficiaryName
});
if (nameCheckResult.matchScore < 0.7)
return { checkId: 'IBAN_INTEGRITY', score: 65, hardBlock: false, reason: 'NAME_MATCH_FAIL' };
}
// 4. Fraud intelligence database check
const fraudFlag = await checkIBANFraudDatabase(tx.beneficiaryIBAN);
if (fraudFlag.isFlagged) {
return { checkId: 'IBAN_INTEGRITY', score: 85, hardBlock: false,
reason: `FRAUD_DB: ${fraudFlag.source}` };
}
return { checkId: 'IBAN_INTEGRITY', score: 0, hardBlock: false };
}
APIs and References
- EPC SEPA CoP scheme: europeanpaymentscouncil.eu
- IBAN structure by country (local lookup table): iban.com/structure
- IBAN fraud consortium databases: Seon, BioCatch, ThreatMetrix/LexisNexis
- EBA IBAN verification APIs: Contact local ACH operator per jurisdiction
Check 50: Correspondent Chain Integrity & Hop Count Anomaly
What it does: In cross-border wire transactions (SWIFT MT103/gpi, CHIPS, Fedwire international), fraudulent layering and sanctions evasion both manifest as unusual correspondent chain depth - more intermediary hops than the payment corridor historically requires. This check: (1) counts the correspondent hops declared in the payment instruction; (2) compares to the p90 hop count for that source-destination corridor from JIL's historical attestation database; (3) flags any correspondent bank in the chain that is on a FATF grey/black list or has known AML deficiencies.
Implementation
// correspondent-chain.service.ts
// FATF grey/black list: updated quarterly, maintain local copy
// Corridor baseline: derived from JIL's own attestation history
const FATF_BLACK_LIST = new Set(['KP', 'IR', 'MM']); // Updated quarterly
const FATF_GREY_LIST = new Set(['SY', 'PK', 'YE', 'SS', 'HT', 'VU', 'JO', 'TZ', 'MN']); // 2026 list
async function checkCorrespondentChain(tx: SWIFTTransaction): Promise<CheckResult> {
const hopChain = extractCorrespondentChain(tx); // from MT103 fields 52a-57a
// 1. Check each correspondent against FATF lists
for (const hop of hopChain) {
const countryCode = getBICCountry(hop.bic);
if (FATF_BLACK_LIST.has(countryCode)) {
return { checkId: 'CORRESPONDENT_CHAIN', score: 100, hardBlock: true,
reason: `FATF_BLACK_LIST: ${hop.bic} ${countryCode}` };
}
}
// 2. Hop count vs corridor baseline
const corridorKey = `${tx.originCountry}-${tx.destinationCountry}`;
const baseline = await getCorridorBaseline(corridorKey);
const hopCount = hopChain.length;
let score = 0;
if (baseline && hopCount > baseline.p90HopCount + 2) score += 50;
if (baseline && hopCount > baseline.p99HopCount) score += 30;
// 3. FATF grey list presence in chain (elevated AML risk, not hard block)
const greyListHops = hopChain.filter(h => FATF_GREY_LIST.has(getBICCountry(h.bic)));
score += Math.min(greyListHops.length * 15, 30);
return { checkId: 'CORRESPONDENT_CHAIN', score: Math.min(score, 100), hardBlock: false };
}
Data Sources
- FATF lists (updated quarterly): fatf-gafi.org
- SWIFT BIC directory (for country code lookup): Available via SWIFT SWIFTRef subscription
- Corridor baseline: Built internally from JIL attestation history - seed with industry data from SWIFT gpi transparency reports
New Category 8: Cross-Jurisdiction Typology Correlation
5 new checks in a new dedicated category - Weight: 5%
This is a new category with no equivalent in the existing 7. It handles pattern-matching against international regulatory typology libraries and cross-border behavioral signals that don't fit neatly into existing categories.
Check 51: FATF Typology Pattern Match
What it does: FATF publishes detailed money laundering and terrorist financing typology reports. This check maintains a library of FATF-defined typology patterns (trade-based money laundering, real estate layering, crypto mixing, correspondent banking abuse) and scores each transaction against them using lightweight rule-based pattern matching.
Implementation approach: Maintain an internal typology rules library (JSON/YAML format) updated quarterly from FATF publications. Each rule defines: trigger conditions, transaction attributes to evaluate, and risk score contribution. No external API call needed - pure local rule engine.
Primary data source: fatf-gafi.org
Check 52: Egmont Group FIU Intelligence Signal
What it does: The Egmont Group is the international network of 166 Financial Intelligence Units (FIUs). FIUs receive STRs/SARs from financial institutions and share intelligence internationally. Several FIUs expose alert feeds or lookups for registered participants. This check queries available FIU feeds for flags on transaction participants.
Implementation approach: FIU access requires formal registration as a reporting institution. Priority integrations: FinCEN (US), FINTRAC (Canada), AUSTRAC (Australia), FIDO (France), BaFin/FIU Germany. Use the Egmont Secure Web (ESW) for cross-border lookups once JIL is registered.
Primary data source: egmontgroup.org / Egmont FIU directory
Check 53: BIS CPMI Payment System Risk Indicator
What it does: The Bank for International Settlements Committee on Payments and Market Infrastructures (CPMI) publishes real-time and periodic risk indicators for payment systems globally. This check flags transactions involving payment system participants that have recently appeared in BIS CPMI risk monitoring data or whose home jurisdiction's payment system has elevated operational risk.
Implementation approach: Monitor BIS CPMI publications and Red Book statistical updates. Build a lightweight jurisdiction-level risk scoring table updated monthly.
Primary data source: bis.org/cpmi
Check 54: Cross-Border Behavioral Velocity (Multi-Jurisdiction)
What it does: Extends the existing velocity check (Check 21) with a cross-jurisdiction dimension. Detects smurfing patterns that deliberately stay under thresholds in each individual jurisdiction but collectively exceed the aggregate. For example: three transfers of EUR 900, SGD 1,400, and CHF 900 - each under their respective Travel Rule thresholds but coordinated across jurisdictions.
Implementation approach: Extend the existing velocity microservice to maintain a cross-jurisdiction aggregate counter per entity. Aggregate window: 24 hours. Threshold: any combination exceeding USD 5,000 equivalent triggers REVIEW.
Check 55: Sanctioned Jurisdiction Routing via Neutral Hub
What it does: A common sanctions evasion technique: route funds through a neutral hub jurisdiction (UAE, Turkey, or Hong Kong historically) to obscure origin or destination in a sanctioned country. This check detects when a transaction involves a neutral hub country and either the originator or beneficial owner has a registered address, IP geolocation, or prior transaction history in a sanctioned jurisdiction.
Implementation approach: Layer the existing OFAC/sanctions check (Check 15/17) with geolocation and behavioral history analysis. Flag transactions where: neutral hub in chain AND (originator IP in sanctioned country OR prior 30-day transaction history with sanctioned jurisdiction entity).
Data sources: MaxMind GeoIP2, combined with OFAC sanctioned jurisdiction list.
Complete Check Registry: All 55 Checks
| # | Check Name | Category | Weight | External API / Data Source | Latency Budget |
|---|---|---|---|---|---|
| 1 | UBO Verification | 1 - Identity | 20% | GLEIF LEI, OpenCorporates | 400ms |
| 2 | Synthetic Identity Detection | 1 - Identity | 20% | Socure, Sardine, internal ML | 300ms |
| 3 | Account-to-Name Validation | 1 - Identity | 20% | Early Warning Zelle/Paze, bank APIs | 350ms |
| 4 | Sanctions Screening (OFAC/EU/UN/HMT) | 1 - Identity | 20% | OpenSanctions Yente (self-hosted) | 50ms cached |
| 5 | Deepfake Detection | 1 - Identity | 20% | Internal CV model or iProov | 500ms |
| 6 | Corporate Synthetic Fraud | 1 - Identity | 20% | Dun & Bradstreet, GLEIF | 400ms |
| 7 | BEC Detection | 2 - Rail Fraud | 20% | Internal domain analysis | 200ms |
| 8 | Invoice Fraud | 2 - Rail Fraud | 20% | Internal document analysis | 300ms |
| 9 | Account Takeover | 2 - Rail Fraud | 20% | Device fingerprint, behavioral | 250ms |
| 10 | Processor Impersonation | 2 - Rail Fraud | 20% | Internal registry | 100ms |
| 11 | ACH Unauthorized Return Risk | 2 - Rail Fraud | 20% | Nacha RPPS, Early Warning | 300ms |
| 12 | APP Scam Detection (US) | 2 - Rail Fraud | 20% | Internal behavioral model | 250ms |
| 13 | Check Fraud (MICR) | 2 - Rail Fraud | 20% | Internal MICR validation | 100ms |
| 14 | Wire Transfer Anomaly | 2 - Rail Fraud | 20% | Internal statistical model | 200ms |
| 15 | Real-time Sanctions Screening | 3 - Compliance | 15% | OpenSanctions Yente | 50ms cached |
| 16 | AML Typology Detection | 3 - Compliance | 15% | Internal typology engine | 200ms |
| 17 | OFAC Jurisdiction Screening | 3 - Compliance | 15% | OFAC SDN (local cache) | 30ms |
| 18 | GENIUS Act Compliance | 3 - Compliance | 15% | Internal rules engine | 100ms |
| 19 | BSA/SAR Trigger Detection | 3 - Compliance | 15% | Internal threshold engine | 100ms |
| 20 | CTR Filing Detection | 3 - Compliance | 15% | Internal threshold engine | 100ms |
| 21 | Velocity Anomaly | 4 - Behavior | 15% | Internal Redis counters | 50ms |
| 22 | Mule Account Scoring | 4 - Behavior | 15% | Internal behavioral ML | 200ms |
| 23 | High-Volume Low-Value Detection | 4 - Behavior | 15% | Internal Redis counters | 50ms |
| 24 | Smurfing/Structuring | 4 - Behavior | 15% | Internal threshold engine | 80ms |
| 25 | Geographic Anomaly | 4 - Behavior | 15% | MaxMind GeoIP2 | 30ms |
| 26 | First-Party Fraud | 4 - Behavior | 15% | Internal behavioral model | 200ms |
| 27 | Routing/Account Change (72h hold) | 5 - Instruction | 15% | Internal registry | 100ms |
| 28 | Beneficiary Age Scoring | 5 - Instruction | 15% | BID registry | 100ms |
| 29 | Instruction Provenance Attestation | 5 - Instruction | 15% | Internal hash comparison | 20ms |
| 30 | Entity Credential Registry Validation | 5 - Instruction | 15% | GLEIF, NPI, internal | 300ms |
| 31 | Duplicate Claims Detection | 6 - Healthcare | 5% | Internal ledger | 100ms |
| 32 | Provider NPI Enrollment Verification | 6 - Healthcare | 5% | CMS NPPES API | 200ms |
| 33 | Upcoding Detection | 6 - Healthcare | 5% | Internal ML model | 200ms |
| 34 | Remittance Mismatch Analysis | 6 - Healthcare | 5% | Internal comparison | 100ms |
| 35 | Overpayment Recovery Tracking | 6 - Healthcare | 5% | Internal ledger | 100ms |
| 36 | Fraud Ring Graph Analysis | 7 - Macro | 10% | Internal graph DB | 300ms |
| 37 | Typology Library Pattern Match | 7 - Macro | 10% | Internal rules engine | 150ms |
| 38 | SEPA Instant APP Scam Detection | 2 - Rail Fraud | 20% | Berlin Group PSD2 API, EPC | 400ms |
| 39 | UK FPS PSR APP Fraud (CoP) | 2 - Rail Fraud | 20% | Pay.UK CoP API | 350ms |
| 40 | PIX Social Engineering Detection | 2 - Rail Fraud | 20% | BCB DICT API | 400ms |
| 41 | UPI Fake Collect / QR Spoof | 2 - Rail Fraud | 20% | NPCI PSP API | 350ms |
| 42 | SWIFT gpi Chain Substitution | 2 - Rail Fraud | 20% | SWIFT gpi Tracker API | 500ms |
| 43 | CIPS Sanctioned-Entity Routing | 2 - Rail Fraud | 20% | CIPS participant list + OpenSanctions | 100ms |
| 44 | NPP PayID Spoofing Detection | 2 - Rail Fraud | 20% | NPPA PayID API | 350ms |
| 45 | EU MiCA Stablecoin Issuer Validation | 3 - Compliance | 15% | ESMA MiCA register | 300ms |
| 46 | EU DORA Operational Resilience | 3 - Compliance | 15% | EBA DORA register | 200ms |
| 47 | UK FCA Authorization Verification | 3 - Compliance | 15% | FCA Register API (public) | 200ms |
| 48 | International Travel Rule (FATF) | 3 - Compliance | 15% | TRISA API, Sygna Bridge | 400ms |
| 49 | IBAN Integrity & Binding | 5 - Instruction | 15% | EPC CoP API, local IBAN lib | 150ms |
| 50 | Correspondent Chain Hop Anomaly | 5 - Instruction | 15% | Internal corridor DB, FATF list | 200ms |
| 51 | FATF Typology Pattern Match | 8 - Intl Typology | 5% | Internal FATF rules library | 100ms |
| 52 | Egmont FIU Intelligence Signal | 8 - Intl Typology | 5% | Egmont ESW (registered access) | 400ms |
| 53 | BIS CPMI Payment System Risk | 8 - Intl Typology | 5% | BIS CPMI data (monthly update) | 50ms cached |
| 54 | Cross-Border Velocity (Multi-Jurisdiction) | 8 - Intl Typology | 5% | Internal Redis multi-key | 80ms |
| 55 | Sanctioned Jurisdiction Hub Routing | 8 - Intl Typology | 5% | MaxMind GeoIP2, OFAC | 100ms |
Highlighted rows = new international checks (18 total)
Priority Implementation Order
Phase 1 - High Impact, Lower Complexity (Ship within 30 days of mainnet)
- Check 49: IBAN Integrity (algorithmic + EPC CoP) - highest EU coverage value, low complexity
- Check 47: UK FCA Authorization - public API, no auth required, immediate value for UK corridor
- Check 43: CIPS Sanctions - extension of existing OpenSanctions integration
- Check 50: Correspondent Chain Hop Anomaly - pure internal data + FATF list, no new API dependency
- Check 48: International Travel Rule - TRISA integration, critical for crypto international
- Check 54: Cross-Border Velocity - extension of existing Redis velocity infrastructure
Phase 2 - Moderate Complexity, Major Corridors (60-90 days post-mainnet)
- Check 38: SEPA Instant APP - requires Berlin Group PSD2 access, EU market critical
- Check 39: UK FPS PSR (CoP) - requires Pay.UK registration, UK market critical
- Check 51: FATF Typology Pattern Match - internal build, no external dependency
- Check 55: Hub Routing - MaxMind + OFAC, extends existing infrastructure
- Check 45: MiCA Stablecoin - ESMA register access, EU regulatory positioning
Phase 3 - Higher Complexity, New Market Access (90-180 days)
- Check 40: PIX - requires BCB participant registration
- Check 41: UPI - requires NPCI PSP registration
- Check 42: SWIFT gpi Chain - requires SWIFT connectivity or service bureau
- Check 44: NPP PayID - requires NPPA participant access
- Check 46: DORA Compliance - monitoring/compliance posture, not hard block
- Check 52: Egmont FIU - requires FIU registration, longest lead time
- Check 53: BIS CPMI Risk - data monitoring, low urgency
Key Vendor / Integration Contacts
| Integration | URL | Access Type | Notes |
|---|---|---|---|
| OpenSanctions Yente | opensanctions.org | Open source + data license | Best option for <50ms sanctions screening |
| SWIFT Developer Portal | developer.swift.com | SWIFT connectivity required | Via service bureau if not direct member |
| Pay.UK (UK CoP) | developer.payuk.co.uk | Pay.UK membership | Required for UK FPS |
| FCA Register API | register.fca.org.uk | Public, no auth | Free, 60 req/min |
| Berlin Group PSD2 | berlin-group.org | Standard spec | Implement against bank APIs |
| BCB PIX (DICT) | bacen.github.io | BCB participant | Requires BCB registration |
| NPCI UPI | developer.npci.org.in | NPCI PSP registration | Requires NPCI onboarding |
| NPPA (NPP Australia) | nppa.com.au | NPPA participant | Requires NPPA membership |
| TRISA (Travel Rule) | developer.trisa.io | Open registration | Free for VASPs |
| Sygna Bridge | sygna.io | Commercial | Better APAC coverage than TRISA alone |
| GLEIF LEI | api.gleif.org | Public API | Free, no auth required |
| MaxMind GeoIP2 | maxmind.com | Commercial license | ~$24/month for most tiers |
| ESMA MiCA Register | esma.europa.eu | Public (when live) | Monitor for 2025/2026 availability |
| CIPS Participant List | cips.com.cn | Public | Scrape/download and cache locally |
| OFAC SDN | ofac.treasury.gov | Public API | Rate-limited; cache locally |
| Egmont ESW | egmontgroup.org | FIU registration required | Longest lead time of all integrations |