Skip to content

Raghuvorkady/cross-border-remittance-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

135 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Cross-Border Remittance API

This project aims to simulates a real-world cross-border money transfer system. Built to demonstrate advanced Spring Boot patterns, distributed systems architecture, and fintech system design.

πŸ“– Table of Contents

πŸš€ Overview

This project showcases a distributed system capable of handling idempotent transactions, compliance validation, and asynchronous settlement in a cross-border context.

πŸŽ₯ Demo Video

Watch the Demo

πŸ—οΈ Architecture & Service Interaction

The system follows a microservices architecture where each service owns its specific domain and data:

System Overview

flowchart LR

    %% ==========================================
    %% Nodes
    %% ==========================================
    FE["Frontend App"]
    TS["Transfer Service"]
    QS["Quote Service"]
    TR["Transfer Repository"]
    REDIS[("Redis Cache<br/>(Quotes)")]
    US["User Service"]
    CS["Compliance Service"]
    KAFKA[("Kafka<br/>Event Bus")]
    SS["Settlement Service"]
    EXT_FX["External FX API"]

    %% ======================
    %% QUOTE FLOW
    %% ======================
    FE -- "(1) Request Quote" --> QS
    QS -- "(1.1) Get FX Rate" --> EXT_FX
    QS -- "(1.2) Cache Quote" --> REDIS

    %% ======================
    %% TRANSFER REQUEST
    %% ======================
    FE -- "(2) Create Transfer Request" --> TS

    TS -- "(2.1) Verify Idempotency Key" --> TR
    TS -- "(2.2) Record Transfer<br/>(INITIATED)" --> TR
    TS -- "(2.3) Validate Quote<br/>Cross-check Cache)" --> REDIS
    TS -- "(2.4) Validate User<br/>(Sync HTTP)" --> US
    TS -- "(2.5) Verify Compliance<br/>(Sync HTTP)" --> CS
    TS -- "(2.6) Update Transaction with Quote Details" --> TR
    TS -- "(2.7) Advance State = SETTLEMENT_IN_PROGRESS" --> TR

    %% ======================
    %% EVENT-DRIVEN SETTLEMENT
    %% ======================
    TS -- "(2.8) Publish TRANSFER_CREATED" --> KAFKA
    KAFKA -- "(2.9) Consume TRANSFER_CREATED" --> SS
    SS -- "(2.10) Publish TRANSFER_SETTLED / TRANSFER_FAILED" --> KAFKA

    KAFKA -- "(2.11) Consume Settlement Result" --> TS
    TS -- "(2.12) Update Status = COMPLETED / FAILED" --> TR

    %% ==========================================
    %% Styling / Class Definitions
    %% ==========================================
    classDef controller fill:#e1f5fe,stroke:#01579b,stroke-width:1px;
    classDef messaging fill:#fff3e0,stroke:#e65100,stroke-width:1px;
    classDef repository fill:#f3e5f5,stroke:#4a148c,stroke-width:1px;
    classDef external fill:#e8f5e9,stroke:#1b5e20,stroke-width:1px;
    classDef infra fill:#eceff1,stroke:#263238,stroke-width:1px;

    %% ==========================================
    %% Apply Styles
    %% ==========================================
    class FE controller;
    class TR repository;
    class EXT_FX external;
    class REDIS infra;
    class KAFKA messaging;
Loading
  1. User Service: The identity provider. Manages registration, profiles, and provides user validation for transactions.
  2. Transfer Service: The core orchestrator. Handles POST requests for new transfers, enforces ACID-compliant Idempotency (PostgreSQL), and publishes events to Kafka.
  3. Compliance Service: A validation gate. Performs automated AML/KYC checks before approving settlement.
  4. Settlement Service: The financial ledger. Listens for approved transfers via Kafka, simulates clearing, and publishes settlement results.
  5. Notification Service: The user-facing alert system. Listens for terminal events and dispatches alerts (Email/SMS simulation).
  6. Quote Caching: The system utilizes Redis to cache FX quotes, ensuring high-performance validation and managing quote expiration.

Microservice Internal Structure

flowchart TB

    User((User)) --> FE["Frontend App"]

    %% ======================
    %% Infrastructure
    %% ======================
    subgraph INFRA["**Core Infrastructure**"]
        REDIS[("Redis Cache<br/>(Quotes)")]
        KAFKA[("Kafka<br/>Event Bus")]
    end

    EX_API["External FX API"]

    %% ======================
    %% User Service
    %% ======================
    subgraph USER_SRV["**User Service**"]
        direction TB
        UC["UserController<br/>AuthController"]
        US["UserService"]
        UR["UserRepository"]
        UDB[("PostgreSQL<br/>user_db")]

        UC --> US --> UR --> UDB
    end

    %% ======================
    %% Transfer Service (Orchestrator)
    %% ======================
    subgraph TRANSFER_SRV["**Transfer Service**"]
        direction TB

        subgraph TS_CLIENT["Downstream Clients"]
            TSC_CC["Compliance Client"]
            TSC_UC["User Client"]
            TSC_FX["FX Rate Client"]
        end

        subgraph TS_MESSAGING["Message Handling"]
            T_SUB["CONSUMER<br/>SettlementResultListener"]
            T_PUB["PUBLISHER<br/>TransferEventPublisher"]
        end

        TC["TransferController<br/>QuoteController"]
        TS["TransferService<br/>QuoteService"]
        TR["TransactionRepository"]
        TDB[("PostgreSQL<br/>transfer_db")]

        TC --> TS --> TR --> TDB
        
        %% Internal Orchestration
        TS --> TSC_CC
        TS --> TSC_UC
        TS --> TSC_FX
        TS --> T_PUB
        T_SUB --> TS
    end

    %% ======================
    %% Compliance Service
    %% ======================
    subgraph COMPLIANCE_SRV["**Compliance Service**"]
        CC["ComplianceController"]
        CS["ComplianceService"]
        CC --> CS 
    end

    %% ======================
    %% Async Services
    %% ======================
    subgraph SETTLEMENT_SRV["**Settlement Service**"]
        SL["SettlementListener"]
        SS["SettlementService"]
        S_PUB["SettlementEventPublisher"]
        SL --> SS --> S_PUB
    end

    subgraph NOTIFICATION_SRV["**Notification Service**"]
        NL["NotificationListener"]
    end

    %% ======================
    %% Communication Paths
    %% ======================

    FE -- "HTTPS" --> TC

    %% Sync Orchestration
    TSC_UC -- "REST (Sync)" --> UC
    TSC_CC -- "REST (Sync)" --> CC
    TS -- "Check Cache" --> REDIS
    
    %% External Integration
    TSC_FX -- "Fetch Rates" --> EX_API
    
    %% Async Choreography
    T_PUB -- "TRANSFER_CREATED" --> KAFKA
    KAFKA -- "TRANSFER_CREATED" --> SL
    KAFKA -- "TRANSFER_CREATED / TRANSFER_SETTLED / TRANSFER_FAILED" --> NL
    
    S_PUB -- "TRANSFER_SETTLED / TRANSFER_FAILED" --> KAFKA
    KAFKA -- "TRANSFER_SETTLED / TRANSFER_FAILED" --> T_SUB
    
    %% ==========================================
    %% Styling / Class Definitions
    %% ==========================================
    classDef controller fill:#e1f5fe,stroke:#01579b,stroke-width:0.5px;
    classDef service fill:#fff3e0,stroke:#e65100,stroke-width:0.5px;
    classDef repository fill:#f3e5f5,stroke:#4a148c,stroke-width:0.5px;
    classDef database fill:#e8f5e9,stroke:#1b5e20,stroke-width:0.5px;
    classDef infra fill:#eceff1,stroke:#263238,stroke-width:0.5px;
    classDef messaging fill:#ffffb0,stroke:#fbc02d,stroke-width:0.5px;
    classDef client fill:#fcefec,stroke:#880e4f,stroke-width:0.5px;

    %% ==========================================
    %% Apply Styles
    %% ==========================================
    class UC,TC,CC controller;
    class US,TS,CS,SS service;
    class UR,TR repository;
    class UDB,TDB,REDIS database;
    class KAFKA infra;
    class T_PUB,T_SUB,SL,S_PUB,NL messaging;
    class TS_CLIENT,TS_MESSAGING client;
Loading

Transaction Lifecycle (Sequence)

sequenceDiagram
    autonumber
    participant FE as Frontend App
    participant QS as Quote Service
    participant EXT as External FX API
    participant REDIS as Redis / Cache
    participant TS as Transfer Service
    participant TR as Transfer Repository
    participant US as User Service
    participant CS as Compliance Service
    participant KAFKA as Kafka (Event Bus)
    participant SS as Settlement Service
    participant NS as Notification Service

    Note over FE, REDIS: Phase 1: Quote Flow
    FE->>QS: Request Quote
    QS->>EXT: Fetch FX Rate
    QS->>REDIS: Cache Quote
    QS-->>FE: Quote Response (Quote ID)

    Note over FE, CS: Phase 2: Transfer Request
    FE->>TS: Create Transfer Request (Idempotency-Key)
    
    rect rgb(240, 240, 240)
        Note right of TS: Idempotency Guard
        TS->>TR: Verify Idempotency Key
        TR-->>TS: Result (Existing / None)
    end

    TS->>TR: Record Transfer (INITIATED)
    
    rect rgb(232, 245, 233)
        Note over TS, CS: Resilience Layer (Circuit Breaker & Retry)
        
        par Checks
            TS->>REDIS: Validate Quote (Cross-check Cache)
            TS->>US: Validate User
            US-->>TS: 200 OK (Active)
            TS->>CS: Verify Compliance
            CS-->>TS: 200 OK (Cleared)
        end
    end

    TS->>TR: Update Transaction with Quote Details
    TS->>TR: Advance State = SETTLEMENT_IN_PROGRESS
    TS-->>FE: 202 Accepted (Transaction ID)

    Note over TS, NS: Phase 3: Settlement & Notifications
    TS->>KAFKA: Publish TRANSFER_CREATED
    
    par Async Processing
        KAFKA->>SS: Consume TRANSFER_CREATED
        KAFKA->>NS: Consume TRANSFER_CREATED
        NS->>NS: Send "Transfer Received" Email
    end

    SS->>SS: Process Settlement (External Rails)
    SS->>KAFKA: Publish TRANSFER_SETTLED / TRANSFER_FAILED
    
    par Async Updates
        KAFKA->>TS: Consume Settlement Result
        KAFKA->>NS: Consume Settlement Result
        NS->>NS: Send "Transfer Complete/Failed" Email
    end

    TS->>TR: Update Status = COMPLETED / FAILED
Loading

πŸ”„ The Remittance Lifecycle

  1. FX Quote: User requests a currency conversion rate.
  2. Creation: User submits a transfer with an Idempotency-Key.
  3. Validation: transfer-service calls user-service (Sync HTTP) and compliance-service (Sync HTTP).
  4. Messaging: Once approved, transfer-service publishes a TRANSFER_CREATED event to Kafka.
  5. Settlement: settlement-service processes the event and publishes TRANSFER_SETTLED.
  6. Terminal State: transfer-service updates the database to COMPLETED and notification-service alerts the user.

πŸ› οΈ Tech Stack

Backend (Microservices)

  • Java 21 & Spring Boot 3.5.x
  • Spring Data JPA & Flyway (Schema management)
  • Resilience4j (Fault tolerance: Circuit Breaker, Retry, Timeout)
  • SpringDoc OpenAPI (Swagger UI for API documentation)

Frontend (User Interface)

  • React 19 (TypeScript)
  • Vite (Build tool & Dev server)

Infrastructure & Messaging

  • PostgreSQL (ACID-compliant relational database)
  • Redis (High-performance caching for FX quotes)
  • Apache Kafka (Asynchronous event-driven communication)
  • Docker & Docker Compose (Container orchestration)

Testing & Quality

  • Testcontainers (Infrastructure-accurate integration testing)
  • JUnit 5 & Mockito
  • Awaitility (Asynchronous test verification)
  • JaCoCo (Code coverage reporting)

🚦 Getting Started

Please refer to the CONTRIBUTING.md file for detailed instructions on prerequisites, configuration, and environment setup.

πŸ§ͺ Testing & Quality

We use Vertical-Slice Integration Testing with Testcontainers to verify the entire stack (REST -> DB -> Redis -> Kafka).

Run Global Test Suite

This script runs tests for all 5 services and generates a high-fidelity report with coverage and latency metrics:

./run-all-tests.sh

Code Coverage (JaCoCo)

To view detailed Line and Branch coverage:

  1. Run ./run-all-tests.sh
  2. Open [service-name]/target/site/jacoco/index.html in your browser.

πŸ“ˆ Project Roadmap (Status Tracker)

  • Phase 1: Initial Spring Boot scaffolds with health checks
  • Phase 2: User Service with registration/auth
  • Phase 3: Transfer Service with basic CRUD
  • Phase 4: Inter-service communication (Sync Feign/REST)
  • Phase 5: Resilience (Circuit Breaker, Retry, Timeouts)
  • Phase 6: Compliance Service integration & Daily Limit rules
  • Phase 7: Event-Driven Messaging (Kafka wiring)
  • Phase 8: Async Settlement, FX Quotes & Redis Caching
  • Phase 9: Database-level Idempotency
  • Phase 10: Observability (Spring Boot Actuator & Metrics)
  • Phase 11: API Documentation (Swagger/OpenAPI UI)
  • Phase 12: Refactoring & Cleanup
  • Phase 13: Unit & Integration Testing with Coverage
  • Phase 14: Simple Frontend Demo UI (React & Vite)
  • Phase 16: Architecture Diagram Creation
  • Phase 17: Migration from H2 to PostgreSQL
  • Phase 18: Dockerization of microservices and frontend

πŸ’Ž Key Concepts Covered

  • Idempotency: Preventing duplicate charges in a distributed environment using unique database constraints.
  • Caching: Low-latency state management using Redis for high-frequency quote lookups.
  • Event-Driven Architecture: Choreography vs. Orchestration using Kafka.
  • Infrastructure Fidelity: Using Testcontainers to ensure tests reflect production environments.
  • Fault Tolerance: Implementing the Circuit Breaker pattern to prevent cascading failures.
  • Database Hygiene: Migration from H2 to PostgreSQL for consistent schema behavior.

About

This project aims to simulates a real-world cross-border money transfer system.

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors