← Back to Documentation
Developer Specification All Documentation →

International Expansion: Check Framework & Developer Implementation Spec

From 37 Checks to 55 Checks Across 8 Signal Categories - Full specification: what each check does, how to build it, latency strategy, and data sources.

Developer SpecificationJIL SovereignApril 2026

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%)

  1. UBO verification
  2. Synthetic identity detection
  3. Account-to-name validation
  4. Real-time sanctions screening (OFAC/EU/UN/HMT)
  5. Deepfake detection
  6. Corporate synthetic fraud

Category 2: Payment Rail-Specific Fraud (8 checks, Weight: 20%)

  1. BEC detection
  2. Invoice fraud
  3. Account takeover
  4. Processor impersonation
  5. ACH unauthorized return risk
  6. APP scam detection
  7. Check fraud (MICR validation)
  8. Wire transfer anomaly

Category 3: Regulatory Compliance Flags (6 checks, Weight: 15%)

  1. Real-time sanctions screening
  2. AML typology detection
  3. OFAC jurisdiction screening
  4. GENIUS Act compliance
  5. BSA/SAR trigger detection
  6. CTR filing detection

Category 4: Transaction Behavior & Velocity (6 checks, Weight: 15%)

  1. Velocity anomaly (1h/24h/7d windows)
  2. Mule account scoring
  3. High-volume low-value detection
  4. Smurfing/structuring ($10K threshold)
  5. Geographic anomaly
  6. First-party fraud

Category 5: Settlement Instruction Integrity (4 checks, Weight: 15%)

  1. Routing/account change detection with 72-hour hold
  2. Beneficiary age scoring
  3. Instruction provenance attestation (hash at initiation vs settlement)
  4. Entity validation via credential registry

Category 6: Healthcare & Government Rails (5 checks, Weight: 5%)

  1. Duplicate claims detection
  2. Provider NPI enrollment verification
  3. Upcoding detection
  4. Remittance mismatch analysis
  5. Overpayment recovery tracking

Category 7: Macro & Systemic Flags (4 checks, Weight: 10%)

  1. Fraud ring graph analysis (IP/device/account clustering)
  2. Typology sharing pattern library
  3. Cross-rail correlation
  4. 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.

Category 2 - Rail Fraud

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.

Verdict: REVIEW at 45+; NO if beneficiary account age under 7 days AND amount over EUR 1,000.

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
Category 2 - Rail Fraud

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.

Verdict: REVIEW at 40+; NO if PSR Category 1 typology match (impersonation of financial institution or government body).

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

Category 2 - Rail Fraud

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.

Verdict: REVIEW at 40+; NO if new device AND amount over BRL 5,000 AND after 20:00 local time (BCB defines this as elevated risk window).

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

Category 2 - Rail Fraud

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.

Verdict: REVIEW if collect request from unverified VPA; NO if VPA matches NPCI fraud database or if collect amount exceeds originator's stated purpose.

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
Category 2 - Rail Fraud

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.

Verdict: REVIEW if intermediary chain has changed since initiation; NO if final beneficiary BIC differs from instructed BIC.

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

Category 2 - Rail Fraud

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.

Verdict: NO on any sanctions hit anywhere in the entity chain; REVIEW if a CIPS participant in the chain is from a jurisdiction with elevated OFAC secondary sanctions risk.

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.
Category 2 - Rail Fraud

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.

Verdict: REVIEW if PayID was registered under 30 days ago; NO if PayID lookalike score exceeds threshold against beneficiary's expected name.

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

Category 3 (Expanded): Regulatory Compliance Flags

Adding 4 checks - new total: 10 checks in this category.

Category 3 - Compliance

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.

Verdict: REVIEW if stablecoin issuer not found in MiCA registry; NO if stablecoin is explicitly prohibited under MiCA (e.g., algorithmic stablecoins as defined in Article 68).

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
Category 3 - Compliance

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.

Verdict: REVIEW if receiving institution's DORA compliance status cannot be confirmed; not a hard block - informational for compliance reporting.

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

Category 3 - Compliance

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.

Verdict: NO if counterparty firm has had authorization cancelled or is on FCA Warning List; REVIEW if authorization status cannot be confirmed or is under investigation.

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)

Category 3 - Compliance

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.

Verdict: REVIEW if Travel Rule information is missing for a transaction above the applicable threshold; NO if transaction is above threshold and no Travel Rule data provided after 72-hour cure window.

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

Category 5 (Expanded): Settlement Instruction Integrity

Adding 2 checks - new total: 6 checks in this category.

Category 5 - Instruction Integrity

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.

Verdict: NO if IBAN checksum fails or BIC country != IBAN country; REVIEW if name match score under 70%; REVIEW if IBAN appears in fraud intelligence database.

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
Category 5 - Instruction Integrity

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.

Verdict: REVIEW if hop count exceeds corridor p90 + 2; NO if any correspondent bank is a FATF-blacklisted jurisdiction institution.

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.

Category 8 - Intl Typology

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

Category 8 - Intl Typology

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

Category 8 - Intl Typology

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

Category 8 - Intl Typology

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.

Category 8 - Intl Typology

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
1UBO Verification1 - Identity20%GLEIF LEI, OpenCorporates400ms
2Synthetic Identity Detection1 - Identity20%Socure, Sardine, internal ML300ms
3Account-to-Name Validation1 - Identity20%Early Warning Zelle/Paze, bank APIs350ms
4Sanctions Screening (OFAC/EU/UN/HMT)1 - Identity20%OpenSanctions Yente (self-hosted)50ms cached
5Deepfake Detection1 - Identity20%Internal CV model or iProov500ms
6Corporate Synthetic Fraud1 - Identity20%Dun & Bradstreet, GLEIF400ms
7BEC Detection2 - Rail Fraud20%Internal domain analysis200ms
8Invoice Fraud2 - Rail Fraud20%Internal document analysis300ms
9Account Takeover2 - Rail Fraud20%Device fingerprint, behavioral250ms
10Processor Impersonation2 - Rail Fraud20%Internal registry100ms
11ACH Unauthorized Return Risk2 - Rail Fraud20%Nacha RPPS, Early Warning300ms
12APP Scam Detection (US)2 - Rail Fraud20%Internal behavioral model250ms
13Check Fraud (MICR)2 - Rail Fraud20%Internal MICR validation100ms
14Wire Transfer Anomaly2 - Rail Fraud20%Internal statistical model200ms
15Real-time Sanctions Screening3 - Compliance15%OpenSanctions Yente50ms cached
16AML Typology Detection3 - Compliance15%Internal typology engine200ms
17OFAC Jurisdiction Screening3 - Compliance15%OFAC SDN (local cache)30ms
18GENIUS Act Compliance3 - Compliance15%Internal rules engine100ms
19BSA/SAR Trigger Detection3 - Compliance15%Internal threshold engine100ms
20CTR Filing Detection3 - Compliance15%Internal threshold engine100ms
21Velocity Anomaly4 - Behavior15%Internal Redis counters50ms
22Mule Account Scoring4 - Behavior15%Internal behavioral ML200ms
23High-Volume Low-Value Detection4 - Behavior15%Internal Redis counters50ms
24Smurfing/Structuring4 - Behavior15%Internal threshold engine80ms
25Geographic Anomaly4 - Behavior15%MaxMind GeoIP230ms
26First-Party Fraud4 - Behavior15%Internal behavioral model200ms
27Routing/Account Change (72h hold)5 - Instruction15%Internal registry100ms
28Beneficiary Age Scoring5 - Instruction15%BID registry100ms
29Instruction Provenance Attestation5 - Instruction15%Internal hash comparison20ms
30Entity Credential Registry Validation5 - Instruction15%GLEIF, NPI, internal300ms
31Duplicate Claims Detection6 - Healthcare5%Internal ledger100ms
32Provider NPI Enrollment Verification6 - Healthcare5%CMS NPPES API200ms
33Upcoding Detection6 - Healthcare5%Internal ML model200ms
34Remittance Mismatch Analysis6 - Healthcare5%Internal comparison100ms
35Overpayment Recovery Tracking6 - Healthcare5%Internal ledger100ms
36Fraud Ring Graph Analysis7 - Macro10%Internal graph DB300ms
37Typology Library Pattern Match7 - Macro10%Internal rules engine150ms
38SEPA Instant APP Scam Detection2 - Rail Fraud20%Berlin Group PSD2 API, EPC400ms
39UK FPS PSR APP Fraud (CoP)2 - Rail Fraud20%Pay.UK CoP API350ms
40PIX Social Engineering Detection2 - Rail Fraud20%BCB DICT API400ms
41UPI Fake Collect / QR Spoof2 - Rail Fraud20%NPCI PSP API350ms
42SWIFT gpi Chain Substitution2 - Rail Fraud20%SWIFT gpi Tracker API500ms
43CIPS Sanctioned-Entity Routing2 - Rail Fraud20%CIPS participant list + OpenSanctions100ms
44NPP PayID Spoofing Detection2 - Rail Fraud20%NPPA PayID API350ms
45EU MiCA Stablecoin Issuer Validation3 - Compliance15%ESMA MiCA register300ms
46EU DORA Operational Resilience3 - Compliance15%EBA DORA register200ms
47UK FCA Authorization Verification3 - Compliance15%FCA Register API (public)200ms
48International Travel Rule (FATF)3 - Compliance15%TRISA API, Sygna Bridge400ms
49IBAN Integrity & Binding5 - Instruction15%EPC CoP API, local IBAN lib150ms
50Correspondent Chain Hop Anomaly5 - Instruction15%Internal corridor DB, FATF list200ms
51FATF Typology Pattern Match8 - Intl Typology5%Internal FATF rules library100ms
52Egmont FIU Intelligence Signal8 - Intl Typology5%Egmont ESW (registered access)400ms
53BIS CPMI Payment System Risk8 - Intl Typology5%BIS CPMI data (monthly update)50ms cached
54Cross-Border Velocity (Multi-Jurisdiction)8 - Intl Typology5%Internal Redis multi-key80ms
55Sanctioned Jurisdiction Hub Routing8 - Intl Typology5%MaxMind GeoIP2, OFAC100ms

Highlighted rows = new international checks (18 total)

Priority Implementation Order

Phase 1 - High Impact, Lower Complexity (Ship within 30 days of mainnet)

  1. Check 49: IBAN Integrity (algorithmic + EPC CoP) - highest EU coverage value, low complexity
  2. Check 47: UK FCA Authorization - public API, no auth required, immediate value for UK corridor
  3. Check 43: CIPS Sanctions - extension of existing OpenSanctions integration
  4. Check 50: Correspondent Chain Hop Anomaly - pure internal data + FATF list, no new API dependency
  5. Check 48: International Travel Rule - TRISA integration, critical for crypto international
  6. Check 54: Cross-Border Velocity - extension of existing Redis velocity infrastructure

Phase 2 - Moderate Complexity, Major Corridors (60-90 days post-mainnet)

  1. Check 38: SEPA Instant APP - requires Berlin Group PSD2 access, EU market critical
  2. Check 39: UK FPS PSR (CoP) - requires Pay.UK registration, UK market critical
  3. Check 51: FATF Typology Pattern Match - internal build, no external dependency
  4. Check 55: Hub Routing - MaxMind + OFAC, extends existing infrastructure
  5. Check 45: MiCA Stablecoin - ESMA register access, EU regulatory positioning

Phase 3 - Higher Complexity, New Market Access (90-180 days)

  1. Check 40: PIX - requires BCB participant registration
  2. Check 41: UPI - requires NPCI PSP registration
  3. Check 42: SWIFT gpi Chain - requires SWIFT connectivity or service bureau
  4. Check 44: NPP PayID - requires NPPA participant access
  5. Check 46: DORA Compliance - monitoring/compliance posture, not hard block
  6. Check 52: Egmont FIU - requires FIU registration, longest lead time
  7. Check 53: BIS CPMI Risk - data monitoring, low urgency

Key Vendor / Integration Contacts

Integration URL Access Type Notes
OpenSanctions Yenteopensanctions.orgOpen source + data licenseBest option for <50ms sanctions screening
SWIFT Developer Portaldeveloper.swift.comSWIFT connectivity requiredVia service bureau if not direct member
Pay.UK (UK CoP)developer.payuk.co.ukPay.UK membershipRequired for UK FPS
FCA Register APIregister.fca.org.ukPublic, no authFree, 60 req/min
Berlin Group PSD2berlin-group.orgStandard specImplement against bank APIs
BCB PIX (DICT)bacen.github.ioBCB participantRequires BCB registration
NPCI UPIdeveloper.npci.org.inNPCI PSP registrationRequires NPCI onboarding
NPPA (NPP Australia)nppa.com.auNPPA participantRequires NPPA membership
TRISA (Travel Rule)developer.trisa.ioOpen registrationFree for VASPs
Sygna Bridgesygna.ioCommercialBetter APAC coverage than TRISA alone
GLEIF LEIapi.gleif.orgPublic APIFree, no auth required
MaxMind GeoIP2maxmind.comCommercial license~$24/month for most tiers
ESMA MiCA Registeresma.europa.euPublic (when live)Monitor for 2025/2026 availability
CIPS Participant Listcips.com.cnPublicScrape/download and cache locally
OFAC SDNofac.treasury.govPublic APIRate-limited; cache locally
Egmont ESWegmontgroup.orgFIU registration requiredLongest lead time of all integrations