maheshsingh20/MerchantRail

β˜… 1Forks 0JavaGitHub β†—Compare

README

MerchantRail πŸ’³

Enterprise Cloud-Native Payment Switching & Batch Clearing Platform

Build Status Coverage Java Spring Boot Spring Batch Cloud Foundry License

A mission-critical, enterprise-grade card transaction switching and clearing platform architected according to Digital Network Architecture and Cloud-Native Twelve-Factor principles. Engineered to showcase high-throughput, fault-tolerant patterns powering global card switching networks: dynamic card BIN routing, Stand-In Processing (STIP), Kafka saga choreography, chunk-oriented Spring Batch clearing, and Pivotal Cloud Foundry (PCF) multi-app deployment.


πŸ“‹ Table of Contents


🎯 Overview

MerchantRail is an enterprise payment switching and batch clearing platform that orchestrates the end-to-end card transaction lifecycle: from real-time acquirer switching and issuer authorization to chunked batch clearing and double-entry financial reconciliation.

Enterprise Highlights

βœ… Card Switching Solutions - Intelligent BIN routing (Mastercard 51-55, 22-27 series, Visa) to multi-issuer endpoints over gRPC (ISO 8583 0100/0110)
βœ… Stand-In Processing (STIP) - Autonomous failover authorization evaluating offline limits ($500.00), velocity checks, and risk thresholds when issuer links breach latency SLAs (>2000ms)
βœ… Enterprise Spring Batch - Chunk-oriented clearing engine (250 items/chunk) in ledger-service executing daily netting, interchange calculation, and ISO 20022 pain.001 SFTP delivery
βœ… Pivotal Cloud Foundry (PCF / Tanzu) - Cloud-native twelve-factor packaging with manifest-pcf.yml, dynamic VCAP_SERVICES bindings, rolling blue-green updates, and autoscaling
βœ… Full-Stack Financial Reporting - React + TypeScript reconciliation dashboard with real-time switching analytics, double-entry audit checks, and one-click CSV export
βœ… Production Reliability - Outbox pattern, Redis idempotency, balanced double-entry accounting, and 85%+ JaCoCo test coverage

Project Metrics

Metric Value
Total Services 8 microservices + React frontend
Lines of Code ~16,000+ (backend + frontend)
Test Coverage >85% (domain & application layers)
Total Tests 135+ (unit, integration, chaos, load, contract)
Protocols & Standards ISO 8583 (0100/0110), ISO 20022 (pain.001), gRPC, Kafka, REST, SFTP
Cloud Target Pivotal Cloud Foundry (PCF / VMware Tanzu), Kubernetes, Docker
Batch Engine Spring Batch 5 (Chunk-oriented clearing with retry listeners)
Frontend React + TypeScript + Tailwind CSS (Live Feed & Reporting)

πŸš€ Switching & Core Capabilities

⚑ Card Transaction Switching & Routing

  • Real-time authorization routing based on 6-to-8 digit Card BIN
  • Dynamic Interchange Fee calculation (1.5% + fixed) and network switch fees
  • Multi-issuer endpoint simulation (Citibank, Chase, Barclays, HDFC)
  • Sub-50ms switching latency under concurrent traffic

πŸ›‘οΈ Stand-In Processing (STIP)

  • Automatic circuit breaker fallback when issuer connectivity degrades or times out
  • Evaluates offline velocity, single-transaction limits, and fraud risk thresholds
  • Autonomous generation of ST-prefixed authorization codes ensuring zero cardholder drop-off

πŸ“¦ Spring Batch Clearing & Settlement

  • Fault-tolerant chunked execution (commit intervals of 250 records)
  • Double-entry bookkeeping balance integrity enforcement (Debit == Credit)
  • Automated ISO 20022 XML batch compilation and SFTP upload
  • On-demand and scheduled execution monitored via Spring Batch REST APIs

πŸ“Š Full-Stack Financial Reporting & Analytics

  • Real-time network throughput and card brand market share analytics
  • STIP authorization rate tracking and issuer latency percentiles
  • Interactive double-entry reconciliation ledger table with status filtering
  • Direct CSV export for automated compliance audits

πŸ›‘οΈ Fraud Detection

  • Rule-based engine with velocity checks
  • Real-time analysis (<100ms evaluation)
  • Configurable rules with Spock tests
  • Historical pattern analysis

πŸ’° Financial Management

  • Double-entry bookkeeping (balanced ledger)
  • Automated nightly settlement (ISO 20022)
  • SFTP file delivery
  • Complete audit trail via event sourcing

πŸ” Security & Compliance

  • JWT authentication with RBAC (MERCHANT, ADMIN, BANK)
  • API key management
  • Rate limiting (20 req/sec per IP)
  • OWASP ZAP + Dependency-Check scanning
  • Complete event log for compliance

πŸš€ Operational Excellence

  • Zero-downtime deployments with canary releases
  • Prometheus metrics + Grafana dashboards
  • Distributed tracing across all services
  • Chaos engineering with Toxiproxy
  • Kubernetes-ready architecture

✨ Key Features

1. Distributed Microservices Architecture

8 Independent Services - Each service has its own database, can be deployed independently, and communicates via well-defined interfaces.

Event-Driven Choreography - Services coordinate through Kafka events using the saga pattern, eliminating single points of failure.

Database-Per-Service - Complete data isolation with no direct database access across services.

2. Clean/Hexagonal Architecture

Zero Framework Coupling - Domain layer is pure Java with no Spring annotations or framework dependencies.

Ports & Adapters - Clear separation between business logic and infrastructure concerns.

Testable Without Infrastructure - Business logic can be tested with simple mocks, no database or messaging required.

3. Complete Transaction Lifecycle

Submit β†’ Idempotency Check β†’ Fraud Analysis β†’ Bank Authorization β†’ 
Ledger Entry β†’ Settlement File Generation β†’ SFTP Delivery

Each step is asynchronous, resilient to failures, and fully traceable.

4. Production-Ready Patterns

Outbox Pattern - Transactional event publishing ensures at-least-once delivery.

Idempotency Pattern - Redis-based tracking prevents duplicate charges on network retries.

Saga Pattern - Distributed transaction coordination with automatic compensation on failures.

Circuit Breaker - Prevents cascading failures when downstream services are unavailable.

5. Payment Industry Standards

ISO 8583 - Standard format for bank authorization messages via gRPC.

ISO 20022 (pain.001) - XML settlement file format for credit transfers.

Double-Entry Bookkeeping - Every transaction creates balanced debit/credit entries.

6. Comprehensive Testing

Unit Tests - 80+ tests with JUnit 5 and Mockito (>90% coverage).

BDD Tests - 12+ Spock specifications with data-driven testing.

Integration Tests - 15+ tests with Testcontainers using real Postgres, Kafka, and Redis.

Chaos Tests - Network failure injection with Toxiproxy to validate saga compensation.

Security Tests - OWASP ZAP dynamic scanning + Dependency-Check for CVEs.


πŸ—οΈ System Architecture

High-Level Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                          API Gateway :8080                           β”‚
β”‚            (Rate Limiting, Routing, Authentication)                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚             β”‚                 β”‚
    β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚  Auth   β”‚   β”‚ Merchant β”‚     β”‚ Transaction │◄──── WebSocket
    β”‚ Service β”‚   β”‚ Service  β”‚     β”‚   Service   β”‚      (Real-time)
    β”‚  :8086  β”‚   β”‚  :8083   β”‚     β”‚    :8081    β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                                          β”‚
                                    Kafka Event Bus
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚                    β”‚                  β”‚
              β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚   Fraud    β”‚      β”‚   Bank    β”‚     β”‚ Notification β”‚
              β”‚  Service   β”‚      β”‚ Simulator β”‚     β”‚   Service    β”‚
              β”‚   :8082    β”‚      β”‚   :9090   β”‚     β”‚    :8087     β”‚
              β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚                   β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                       β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
                       β”‚   Ledger   β”‚ ───SFTP───> [Settlement Files]
                       β”‚  Service   β”‚              pain.001.xml
                       β”‚   :8085    β”‚
                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Infrastructure Layer:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚PostgreSQLβ”‚  β”‚ Kafka  β”‚  β”‚ Redis β”‚  β”‚ Prometheus β”‚  β”‚ Grafana β”‚
β”‚  :5432   β”‚  β”‚ :9092  β”‚  β”‚ :6379 β”‚  β”‚   :9090    β”‚  β”‚  :3000  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Transaction Flow

Complete Payment Lifecycle:

  1. Merchant submits transaction β†’ API Gateway (rate limit check)
  2. Transaction Service saves to database + idempotency check (Redis)
  3. Publishes transaction.initiated event β†’ Kafka
  4. Fraud Service consumes event β†’ evaluates rules β†’ publishes fraud.passed/failed
  5. Transaction Service consumes result β†’ calls Bank Simulator via gRPC (ISO 8583)
  6. Bank responds with approval/decline β†’ publishes transaction.approved/declined
  7. Ledger Service consumes event β†’ creates double-entry bookkeeping entries
  8. Notification Service sends webhook to merchant
  9. Nightly Job: Ledger generates ISO 20022 XML β†’ uploads via SFTP

Compensation Flow (on failure):

  • If bank declines or times out β†’ transaction.reversed event published
  • Ledger Service creates compensating entries (reversal)
  • Merchant notified of failure

πŸ› οΈ Technology Stack

Core Technologies

Category Technology Version Purpose
Language Java 17 LTS Primary development language
Framework Spring Boot 3.2.0 Application framework
API Gateway Spring Cloud Gateway 2023.0.0 Routing & rate limiting
Messaging Apache Kafka 3.6.1 Event streaming platform
RPC gRPC + Protobuf Latest Bank authorization (high-performance)
Database PostgreSQL 15 Transactional data store
Cache Redis 7 Idempotency & session management
Build Maven 3.8+ Dependency & build management

Testing Stack

Tool Purpose Coverage
JUnit 5 Unit testing framework 80+ tests
Mockito Mocking framework Port implementations
Spock (Groovy) BDD testing 12+ specifications
AssertJ Fluent assertions All tests
Testcontainers Integration testing Real Postgres/Kafka/Redis
REST Assured API testing E2E flows
Awaitility Async testing Event-driven flows
Toxiproxy Chaos engineering Network failures
JaCoCo Code coverage >80% enforcement
OWASP ZAP Security scanning Vulnerability detection

Infrastructure & DevOps

Tool Purpose
Docker Service containerization
Docker Compose Local orchestration
Kubernetes Production orchestration (ready)
GitHub Actions CI/CD automation
Prometheus Metrics collection
Grafana Metrics visualization
Apache Commons Net SFTP client for settlement files
Argo CD GitOps deployment (ready)

πŸ“¦ Services

All 8 Microservices + Frontend

Service Port Tech Stack Responsibilities
frontend 🎨 3000 React + TypeScript + Tailwind Admin dashboard, real-time monitoring, transaction management, charts
api-gateway 8080 Spring Cloud Gateway Single entry point, rate limiting (20 req/sec), routing, JWT validation
auth-service 8086 Spring Boot + JWT Authentication, token generation, RBAC (MERCHANT/ADMIN/BANK)
merchant-service 8083 Spring Boot + JPA Merchant onboarding, API key management, profile management
transaction-service ⭐ 8081 Spring Boot + Kafka + gRPC + Redis Transaction orchestration, idempotency, saga coordinator, WebSocket
fraud-service 8082 Spring Boot + Kafka + Spock Rule-based fraud detection, velocity checks, merchant risk scoring
bank-simulator-service 9090 Spring Boot + gRPC ISO 8583 bank simulator, authorization approval/decline, chaos injection
ledger-service 8085 Spring Boot + JPA + SFTP Double-entry bookkeeping, settlement file generation, reconciliation
notification-service 8087 Spring Boot + Kafka Webhook callbacks, retry logic, notification audit trail

Frontend Dashboard Features

🎯 Real-time Transaction Monitoring

  • Live transaction feed with WebSocket updates
  • Interactive charts (Recharts): trends, status distribution, merchant analytics
  • Transaction search, filter, and pagination
  • Detailed transaction view with full audit trail

πŸ’Ό Merchant Portal

  • Transaction history and statistics
  • API key management
  • Success rate and volume metrics
  • Responsive mobile-first design (Tailwind CSS)

⚑ Technical Highlights

  • React 18 with TypeScript for type safety
  • React Query for efficient API data fetching
  • Socket.io for real-time WebSocket connection
  • Tailwind CSS for modern, responsive UI
  • Dockerized with nginx for production deployment

Communication Protocols

REST/HTTPS    β†’ Client ↔ API Gateway, inter-service queries, Frontend ↔ Backend
gRPC          β†’ transaction-service ↔ bank-simulator (high-performance RPC)
Kafka Events  β†’ Asynchronous saga choreography (all services)
WebSocket     β†’ Real-time transaction status updates (transaction-service ↔ frontend)
SFTP          β†’ Settlement file delivery (ledger-service β†’ bank)

Service Architecture (Clean/Hexagonal)

Example: transaction-service

transaction-service/
β”œβ”€β”€ domain/                    # Pure business logic (ZERO framework dependencies)
β”‚   β”œβ”€β”€ Transaction.java       # Entity with state machine
β”‚   β”œβ”€β”€ TransactionStatus.java # Enum (PENDING, APPROVED, SETTLED, REVERSED)
β”‚   └── Money.java             # Value object
β”œβ”€β”€ application/               # Use cases (no infrastructure)
β”‚   β”œβ”€β”€ port/
β”‚   β”‚   β”œβ”€β”€ in/               # Input ports (SubmitTransactionCommand)
β”‚   β”‚   └── out/              # Output ports (TransactionRepository, EventPublisher)
β”‚   └── usecase/
β”‚       β”œβ”€β”€ SubmitTransactionUseCase.java
β”‚       └── GetTransactionUseCase.java
β”œβ”€β”€ adapter/                   # Framework implementations
β”‚   β”œβ”€β”€ in/
β”‚   β”‚   β”œβ”€β”€ web/              # REST controllers
β”‚   β”‚   └── messaging/        # Kafka consumers
β”‚   β”œβ”€β”€ out/
β”‚   β”‚   β”œβ”€β”€ persistence/      # JPA repositories
β”‚   β”‚   β”œβ”€β”€ messaging/        # Kafka producers
β”‚   β”‚   β”œβ”€β”€ client/           # gRPC clients
β”‚   β”‚   └── cache/            # Redis idempotency
β”‚   └── config/               # Spring configuration
└── infrastructure/            # Main application, config files

Benefits:

  • Domain logic testable without Spring/database
  • Can swap JPA for MongoDB without touching business logic
  • Clear boundaries between layers
  • Framework details isolated in adapters

πŸ’³ Payment Standards

ISO 8583 - Bank Authorization Messages

Purpose: Standard format for electronic transaction messages between transaction service and issuing bank.

Implementation: gRPC service definition in bank-simulator-service.

Message Structure:

message AuthorizationRequest {
  string mti = 1;              // Message Type Indicator (0100 = auth request)
  string pan = 2;              // Primary Account Number (masked: 4111****1111)
  int64 amount = 3;            // Amount in minor units (cents)
  string currency = 4;         // ISO 4217 code (USD, EUR, GBP)
  string merchant_id = 5;
  string transaction_id = 6;
}

message AuthorizationResponse {
  string mti = 1;              // 0110 = auth response
  string response_code = 2;    // 00=approved, 05=declined, 51=insufficient funds
  string authorization_code = 3; // 6-character approval code
}

Response Codes:

  • 00 - Approved
  • 05 - Declined (do not honor)
  • 51 - Insufficient funds
  • 91 - Issuer or switch inoperative (timeout)
  • 96 - System malfunction

ISO 20022 - Settlement Files (pain.001)

Purpose: XML-based standard for credit transfer initiation messages.

Implementation: ledger-service generates nightly settlement files.

XML Structure:

<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03">
  <CstmrCdtTrfInitn>
    <GrpHdr>
      <MsgId>SETTLEMENT-20260720</MsgId>
      <CreDtTm>2026-07-20T02:00:00Z</CreDtTm>
      <NbOfTxs>150</NbOfTxs>
      <CtrlSum>45000.00</CtrlSum>
    </GrpHdr>
    <PmtInf>
      <PmtInfId>BATCH-001</PmtInfId>
      <PmtMtd>TRF</PmtMtd>
      <CdtTrfTxInf>
        <Amt Ccy="USD">10000</Amt>
        <CdtrAcct>
          <Id><IBAN>US1234567890</IBAN></Id>
        </CdtrAcct>
      </CdtTrfTxInf>
    </PmtInf>
  </CstmrCdtTrfInitn>
</Document>

Delivery: Uploaded to bank SFTP server nightly at 2:00 AM.

Double-Entry Bookkeeping

Principle: Every transaction affects at least two accounts; total debits must equal total credits.

Example Transaction: $100 from Customer to Merchant (2% platform fee)

Ledger Entries:
1. Debit  - Customer Account:     $100.00
2. Credit - Merchant Account:      $98.00
3. Debit  - Merchant Account:       $2.00  (fee)
4. Credit - Platform Account:       $2.00  (fee)

Verification: $100.00 (debit) = $100.00 (credit) βœ“

Benefits:

  • Self-balancing system (errors detected automatically)
  • Complete audit trail
  • Supports reconciliation and financial reporting
  • Industry standard for all financial systems

πŸ›οΈ Architecture Patterns

1. Clean/Hexagonal Architecture

Domain Layer - Pure Java, zero framework dependencies

public class Transaction {
    private TransactionId id;
    private Money amount;
    private TransactionStatus status;
    
    public void approve() {
        if (status != TransactionStatus.PENDING) {
            throw new IllegalStateException("Can only approve pending transactions");
        }
        this.status = TransactionStatus.APPROVED;
    }
}

Application Layer - Use cases with port interfaces

public class SubmitTransactionUseCase {
    private final TransactionRepository repository;  // Port (interface)
    private final EventPublisher publisher;          // Port (interface)
    
    public Transaction execute(SubmitTransactionCommand cmd) {
        // Business logic here
    }
}

Adapter Layer - Framework implementations

@Repository
public class JpaTransactionRepository implements TransactionRepository {
    // JPA implementation
}

2. Saga Pattern (Choreography)

Event-Driven Coordination - No central orchestrator

transaction.initiated
  ↓ consumed by fraud-service
fraud.passed
  ↓ consumed by transaction-service
transaction.approved
  ↓ consumed by ledger-service
ledger.recorded
  ↓ consumed by notification-service
webhook sent to merchant

Compensation on Failure:

bank.declined OR bank.timeout
  ↓
transaction.reversed (published)
  ↓ consumed by ledger-service
compensating ledger entries created (reversal)
  ↓ consumed by notification-service
merchant notified of reversal

3. Outbox Pattern

Problem: How to atomically update database AND publish Kafka event?

Solution: Write event to database outbox table in same transaction, then publish asynchronously.

@Transactional
public Transaction submitTransaction(Command cmd) {
    Transaction txn = repository.save(transaction);
    outboxRepository.save(new OutboxEvent("transaction.initiated", txn));
    return txn; // Commit both in same transaction
}

@Scheduled(fixedDelay = 1000)
public void publishOutboxEvents() {
    List<OutboxEvent> unpublished = outboxRepository.findUnpublished();
    unpublished.forEach(event -> {
        kafkaProducer.send(event.getTopic(), event.getPayload());
        event.markAsPublished();
        outboxRepository.save(event);
    });
}

Guarantees: At-least-once delivery, no message loss even if Kafka is down.

4. Idempotency Pattern

Problem: Network retries can cause duplicate transactions.

Solution: Redis-based idempotency key tracking (24-hour TTL).

public Transaction submitTransaction(Command cmd) {
    String key = "idempotency:" + cmd.getIdempotencyKey();
    
    // Check if already processed
    String existingTxnId = redisTemplate.opsForValue().get(key);
    if (existingTxnId != null) {
        return repository.findById(existingTxnId); // Return existing
    }
    
    // Process new transaction
    Transaction txn = repository.save(new Transaction(cmd));
    
    // Store idempotency mapping (24h TTL)
    redisTemplate.opsForValue().set(key, txn.getId(), 24, TimeUnit.HOURS);
    
    return txn;
}

Critical for payments: Prevents duplicate charges on network failures/retries.

5. Database-Per-Service Pattern

Each service owns its database:

transaction-service β†’ transaction_db (PostgreSQL)
fraud-service       β†’ fraud_db (PostgreSQL)
ledger-service      β†’ ledger_db (PostgreSQL)
merchant-service    β†’ merchant_db (PostgreSQL)
auth-service        β†’ auth_db (PostgreSQL)

Benefits:

  • Service independence (can deploy/scale independently)
  • Schema evolution without coordination
  • Technology polyglotism (can use different databases)
  • Clear ownership boundaries

Tradeoffs:

  • No distributed ACID transactions (hence saga pattern)
  • Eventual consistency
  • Some data duplication (denormalization)

πŸš€ Getting Started

Prerequisites

Requirement Version Installation
Java JDK 17+ Adoptium OpenJDK
Maven 3.8+ Apache Maven
Docker 20+ Docker Desktop
Docker Compose 2.0+ Included with Docker Desktop
Git 2.0+ Git SCM

For Frontend Development:

Tool Version Download
Node.js 18+ Node.js
npm 9+ Included with Node.js

Verify Installation:

java -version    # Should show Java 17+
mvn --version    # Should show Maven 3.8+
docker --version # Should show Docker 20+
docker compose version
git --version

πŸ“– Detailed setup guide: docs/setup/prerequisites.md

Quick Start (5 Minutes)

1. Clone Repository

git clone https://github.com/maheshsingh20/merchantrail.git
cd merchantrail

2. Start Infrastructure

docker-compose up -d

This starts:

  • PostgreSQL (port 5432)
  • Kafka (port 9092)
  • Redis (port 6379)
  • Prometheus (port 9090)
  • Grafana (port 3000)

Wait for health checks (~30 seconds):

docker-compose ps
# All services should show "healthy"

3. Build All Services

mvn clean install

Build time: ~2-3 minutes (downloads dependencies, runs tests)

4. Run Services

Option A: Docker Compose (Recommended - includes frontend):

docker-compose up -d

Access:

Option B: Run All 8 Services + Frontend (9 terminals):

# Backend Services (Terminals 1-8)
cd api-gateway && mvn spring-boot:run
cd auth-service && mvn spring-boot:run
cd merchant-service && mvn spring-boot:run
cd transaction-service && mvn spring-boot:run
cd fraud-service && mvn spring-boot:run
cd bank-simulator-service && mvn spring-boot:run
cd ledger-service && mvn spring-boot:run
cd notification-service && mvn spring-boot:run

# Frontend (Terminal 9)
cd frontend && npm install && npm start

Option C: Run Core Services Only (4 terminals - minimal setup):

cd transaction-service && mvn spring-boot:run      # Core
cd fraud-service && mvn spring-boot:run            # Fraud detection
cd bank-simulator-service && mvn spring-boot:run   # Bank
cd frontend && npm install && npm start            # Dashboard

Wait for startup: Each service takes ~10-15 seconds. Look for:

Started Application in X seconds

Frontend will be available at: http://localhost:3000

5. Test the System

Via Frontend Dashboard:

  1. Open http://localhost:3000
  2. View real-time transaction feed
  3. Browse transaction history
  4. Monitor system statistics

Via API:

Submit a Transaction:

curl -X POST http://localhost:8081/api/v1/transactions \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "MERCH001",
    "amount": 100.50,
    "currency": "USD",
    "idempotencyKey": "test-key-123"
  }'

Expected Response (201 Created):

{
  "transactionId": "TXN1234567890ABC",
  "merchantId": "MERCH001",
  "amount": 100.50,
  "currency": "USD",
  "status": "PENDING",
  "createdAt": "2026-07-20T10:30:00Z",
  "updatedAt": "2026-07-20T10:30:00Z"
}

Get Transaction Status:

curl http://localhost:8081/api/v1/transactions/TXN1234567890ABC

Watch Status Change (over a few seconds):

PENDING β†’ FRAUD_CHECK β†’ APPROVED β†’ SETTLED

Test Idempotency (duplicate submission):

# Submit same request again with same idempotencyKey
curl -X POST http://localhost:8081/api/v1/transactions \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "MERCH001",
    "amount": 100.50,
    "currency": "USD",
    "idempotencyKey": "test-key-123"
  }'

Result: Returns same transaction (same transactionId) - no duplicate created! βœ…

List Merchant Transactions:

curl "http://localhost:8081/api/v1/transactions?merchantId=MERCH001"

Observability Access

Tool URL Credentials
Prometheus http://localhost:9090 None
Grafana http://localhost:3000 admin / admin
Transaction Service Health http://localhost:8081/actuator/health None
Transaction Service Metrics http://localhost:8081/actuator/prometheus None

Sample Prometheus Queries:

# Request rate
rate(http_server_requests_seconds_count[1m])

# Error rate
rate(http_server_requests_seconds_count{status="5xx"}[1m])

# p95 latency
histogram_quantile(0.95, http_server_requests_seconds_bucket)

Running Tests

# Unit tests only (fast - <30 seconds)
mvn test

# Unit + integration tests (~2 minutes, requires Docker)
mvn verify

# Test specific service
cd transaction-service
mvn test

# Test with coverage report
mvn clean verify
# Open target/site/jacoco/index.html

Stopping Services

# Stop application services
# Press Ctrl+C in each terminal

# Stop infrastructure
docker-compose down

# Clean everything (including data volumes)
docker-compose down -v

⚠️ Warning: docker-compose down -v deletes all database data and Kafka topics.

πŸ“– Detailed guide: QUICK_START.md


πŸ“š API Documentation

Transaction Service REST API

Submit Transaction

POST /api/v1/transactions
Content-Type: application/json

{
  "merchantId": "MERCH001",
  "amount": 100.50,
  "currency": "USD",
  "idempotencyKey": "unique-key-123"
}

Validation Rules:

  • merchantId: Required, 8 alphanumeric characters
  • amount: Required, 0.01 to 1,000,000
  • currency: Required, ISO 4217 code (USD, EUR, GBP, JPY, etc.)
  • idempotencyKey: Required, max 255 characters, unique per merchant

Response (201 Created):

{
  "transactionId": "TXN1234567890ABC",
  "merchantId": "MERCH001",
  "amount": 100.50,
  "currency": "USD",
  "status": "PENDING",
  "createdAt": "2026-07-20T10:30:00Z",
  "updatedAt": "2026-07-20T10:30:00Z"
}

Status Codes:

  • 201 Created - Transaction submitted successfully
  • 400 Bad Request - Validation error (invalid merchantId, amount, currency)
  • 409 Conflict - Duplicate idempotency key
  • 429 Too Many Requests - Rate limit exceeded (>20 req/sec)
  • 500 Internal Server Error - System error

Get Transaction by ID

GET /api/v1/transactions/{transactionId}

Response (200 OK):

{
  "transactionId": "TXN1234567890ABC",
  "merchantId": "MERCH001",
  "amount": 100.50,
  "currency": "USD",
  "status": "APPROVED",
  "createdAt": "2026-07-20T10:30:00Z",
  "updatedAt": "2026-07-20T10:30:15Z"
}

Transaction Status Values:

  • PENDING - Initial state after submission
  • FRAUD_CHECK - Under fraud evaluation
  • APPROVED - Passed fraud check and bank authorization
  • REJECTED - Declined by fraud service or bank
  • SETTLED - Included in settlement batch
  • REVERSED - Compensating transaction (chargeback/refund)

List Merchant Transactions

GET /api/v1/transactions?merchantId={merchantId}&page=0&size=20&sort=createdAt,desc

Query Parameters:

  • merchantId: Required, filter by merchant
  • page: Optional, page number (default: 0)
  • size: Optional, page size (default: 20, max: 100)
  • sort: Optional, sort field and direction (default: createdAt,desc)

Response (200 OK):

{
  "content": [
    {
      "transactionId": "TXN1234567890ABC",
      "amount": 100.50,
      "currency": "USD",
      "status": "APPROVED",
      "createdAt": "2026-07-20T10:30:00Z"
    }
  ],
  "page": 0,
  "size": 20,
  "totalElements": 1,
  "totalPages": 1
}

WebSocket API (Real-Time Updates)

Connect to Transaction Updates:

const socket = new WebSocket('ws://localhost:8081/ws/transactions/TXN1234567890ABC');

socket.onopen = () => {
  console.log('Connected to transaction updates');
};

socket.onmessage = (event) => {
  const update = JSON.parse(event.data);
  console.log('Transaction status:', update.status);
  console.log('Timestamp:', update.timestamp);
};

socket.onerror = (error) => {
  console.error('WebSocket error:', error);
};

socket.onclose = () => {
  console.log('Connection closed');
};

Message Format:

{
  "transactionId": "TXN1234567890ABC",
  "status": "APPROVED",
  "timestamp": "2026-07-20T10:30:15Z"
}

gRPC API (Bank Simulator)

Service Definition (bank_authorization.proto):

service BankAuthorizationService {
  rpc Authorize (AuthorizationRequest) returns (AuthorizationResponse);
}

Usage from transaction-service:

AuthorizationRequest request = AuthorizationRequest.newBuilder()
    .setMti("0100")
    .setPan("4111****1111")
    .setAmount(10000)  // $100.00 in cents
    .setCurrency("USD")
    .setMerchantId("MERCH001")
    .setTransactionId("TXN1234567890ABC")
    .build();

AuthorizationResponse response = bankStub.authorize(request);

if ("00".equals(response.getResponseCode())) {
    // Approved
} else {
    // Declined
}

πŸ§ͺ Testing Strategy

Test Pyramid

            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚Security β”‚  OWASP ZAP, Dependency-Check
            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚ Chaos & Loadβ”‚  Toxiproxy, Gatling
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚   E2E & Protocolβ”‚  REST Assured, gRPC, SFTP
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
      β”‚   Integration Tests β”‚  Testcontainers (real infra)
      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚      Unit Tests           β”‚  JUnit 5, Spock, Mockito
  β”‚  (Domain & Application)   β”‚  Fast, isolated, >80% coverage
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Test Categories

Category Framework Count Coverage Execution Time
Unit Tests JUnit 5 + Mockito 80+ >90% (domain/app) <30 seconds
BDD Tests Spock (Groovy) 12+ 100% (fraud rules) <5 seconds
Integration Tests Testcontainers 15+ Adapter layer ~2 minutes
API Tests REST Assured 8+ E2E flows ~30 seconds
Chaos Tests Toxiproxy 20+ Resilience validation ~3 minutes
Load Tests Gatling 3 simulations Performance benchmarks ~5 minutes
Contract Tests Spring Cloud Contract 3+ API contracts ~1 minute
Protocol Tests E2E 4 protocols REST/gRPC/WS/SFTP ~2 minutes
Security Tests OWASP ZAP CI/CD Vulnerabilities ~5 minutes

Key Testing Principles

βœ… Fast Feedback - Unit tests complete in seconds
βœ… Real Infrastructure - Testcontainers uses actual Postgres/Kafka/Redis (not H2/mocks)
βœ… No Mocks in Integration - Test real adapter implementations
βœ… Chaos Engineering - Validates saga compensation, circuit breakers, resilience patterns
βœ… Performance Validation - Gatling load tests with 500+ concurrent users
βœ… Contract Testing - Spring Cloud Contract ensures API compatibility
βœ… Protocol Coverage - All integration protocols tested (REST, gRPC, WebSocket, SFTP)
βœ… Coverage Enforcement - JaCoCo enforces >80% on business logic

Example Tests

Unit Test (Domain Layer):

@Test
void shouldTransitionFromPendingToApproved() {
    Transaction txn = Transaction.create(merchantId, money, idempotencyKey);
    
    txn.approve();
    
    assertThat(txn.getStatus()).isEqualTo(TransactionStatus.APPROVED);
    assertThat(txn.getUpdatedAt()).isAfter(txn.getCreatedAt());
}

Spock Test (Data-Driven):

def "fraud score calculation for various patterns"() {
    given:
    def transaction = new Transaction(amount, merchantId)
    
    when:
    def score = fraudEngine.calculateScore(transaction)
    
    then:
    score == expectedScore
    
    where:
    amount | merchantId || expectedScore
    100    | "M001"     || 10   // Normal transaction
    10000  | "M001"     || 75   // High amount
    100    | "M999"     || 50   // New merchant
}

Integration Test (Testcontainers):

@Testcontainers
@SpringBootTest
class TransactionRepositoryIT {
    
    @Container
    static PostgreSQLContainer<?> postgres = 
        new PostgreSQLContainer<>("postgres:15");
    
    @Test
    void shouldSaveAndRetrieveTransaction() {
        Transaction saved = repository.save(transaction);
        
        Transaction retrieved = repository.findById(saved.getId()).orElseThrow();
        
        assertThat(retrieved.getAmount()).isEqualTo(saved.getAmount());
    }
}

Chaos Test (Toxiproxy):

@Test
void whenBankTimesOut_sagaReversesTransaction() {
    // Inject 10s latency to bank simulator
    toxiproxy.toxics()
        .latency("bank-timeout", ToxicDirection.DOWNSTREAM, 10_000);
    
    String txnId = submitTransaction();
    
    // Assert transaction moves to REVERSED status
    await().atMost(15, SECONDS)
        .until(() -> getTransactionStatus(txnId).equals("REVERSED"));
    
    // Assert compensating ledger entries created
    List<LedgerEntry> entries = ledgerRepository.findByTransactionId(txnId);
    assertEquals(4, entries.size()); // 2 original + 2 reversal
}

Load Test (Gatling):

class TransactionLoadSimulation extends Simulation {
  
  val httpProtocol = http.baseUrl("http://localhost:8081")
  
  val scn = scenario("Submit Transactions")
    .exec(http("Submit Transaction")
      .post("/api/v1/transactions")
      .body(StringBody("""{ "merchantId": "M123", "amount": 99.99 }"""))
      .check(status.is(201)))
  
  setUp(
    scn.inject(
      rampUsers(500).during(60.seconds)  // Ramp to 500 concurrent users
    )
  ).protocols(httpProtocol)
   .assertions(
     global.responseTime.percentile(95).lt(500),  // p95 < 500ms
     global.successfulRequests.percent.gt(99)     // >99% success
   )
}

Contract Test (Spring Cloud Contract):

Contract.make {
    description "Should accept a valid transaction submission"
    
    request {
        method POST()
        url "/api/v1/transactions"
        body([
            merchantId: "MERCHANT_12345",
            amount: 99.99,
            currency: "USD"
        ])
    }
    
    response {
        status 201
        body([
            transactionId: $(consumer(~/.+/), producer("TX_123")),
            status: "PENDING"
        ])
    }
}

Running Tests

# Run all tests
mvn clean verify

# Run specific test categories
mvn test                                    # Unit tests only
mvn verify -Dtest=*IT                       # Integration tests
mvn verify -Dtest=*ChaosTest                # Chaos tests
mvn gatling:test                            # Load tests
mvn verify -Dtest=ContractTest              # Contract tests

# Run with coverage
mvn verify jacoco:report

# Run security scans
mvn dependency-check:check                  # Dependency vulnerabilities
docker run -t owasp/zap2docker-stable zap-api-scan.py -t http://localhost:8081/api

πŸ“– Comprehensive testing guide: TEST_STRATEGY.md


πŸ“Š Observability

Metrics (Prometheus)

All services expose Prometheus metrics at /actuator/prometheus.

Key Metrics:

# Request rate (requests per second)
rate(http_server_requests_seconds_count[1m])

# Error rate (5xx responses)
rate(http_server_requests_seconds_count{status="5xx"}[1m])

# p95 latency (95th percentile response time)
histogram_quantile(0.95, http_server_requests_seconds_bucket)

# Kafka consumer lag
kafka_consumer_lag{topic="transaction.initiated"}

# Transaction status distribution
transaction_status_total{status="APPROVED"}
transaction_status_total{status="REJECTED"}

Dashboards (Grafana)

Access: http://localhost:3000 (admin/admin)

Pre-configured Dashboards:

  1. Transaction Service Overview

    • Request rate, latency, error rate
    • Transaction status distribution
    • Active transactions
  2. Kafka Metrics

    • Message throughput
    • Consumer lag
    • Topic partition metrics
  3. JVM & System Metrics

    • Heap memory usage
    • GC activity
    • Thread count
    • CPU usage

Health Checks

All services expose health endpoints:

# Transaction Service
curl http://localhost:8081/actuator/health

# Response
{
  "status": "UP",
  "components": {
    "db": {"status": "UP"},
    "kafka": {"status": "UP"},
    "redis": {"status": "UP"}
  }
}

Distributed Tracing

Trace ID Propagation: All services propagate trace IDs via headers.

Log Format:

2026-07-20 10:30:00.123 INFO [transaction-service,abc123,def456] 
  Transaction TXN1234567890ABC submitted
  • abc123 - Trace ID (same across all services for a request)
  • def456 - Span ID (unique per service)

πŸ” Security

Security Measures

βœ… Authentication & Authorization

  • JWT-based authentication with role-based access control
  • Three roles: MERCHANT (submit transactions), ADMIN (full access), BANK (bank operations)
  • API key authentication for merchant API access
  • Token expiration and refresh mechanism

βœ… API Protection

  • Rate limiting at API Gateway (20 requests/second per IP)
  • Request validation with Bean Validation (@Valid)
  • SQL injection prevention via JPA parameterized queries
  • XSS prevention with input sanitization

βœ… Security Scanning (CI/CD)

  • OWASP Dependency-Check for CVE scanning
  • OWASP ZAP baseline scan for vulnerabilities
  • Automated security gates in pipeline

βœ… Audit Trail

  • Complete event log via Kafka (7-day retention)
  • All transactions logged with timestamps
  • Immutable event history for compliance

Security Testing

OWASP Dependency-Check:

mvn org.owasp:dependency-check-maven:check
# Scans dependencies for known CVEs
# Report: target/dependency-check-report.html

OWASP ZAP Baseline Scan:

docker run -v $(pwd):/zap/wrk:rw owasp/zap2docker-stable \
  zap-baseline.py -t http://localhost:8081 -r zap-report.html

Security Checklist:

  • No hardcoded credentials (all externalized)
  • HTTPS-ready (TLS configuration available)
  • Input validation on all endpoints
  • Parameterized database queries (no string concatenation)
  • JWT token validation
  • Rate limiting enabled
  • Security headers configured
  • Audit logging enabled

πŸ“– Detailed security guide: docs/SECURITY_TESTING.md


🚒 CI/CD Pipeline

GitHub Actions Workflow

Trigger: Every push to main, every pull request

Stages:

1. Lint & Static Analysis
   - Checkstyle/SpotBugs
   - Code formatting validation

2. Unit Tests
   - JUnit 5 + Spock tests
   - Fast feedback (<30 seconds)

3. Build
   - Maven package
   - Docker image build

4. Integration Tests
   - Testcontainers (Postgres, Kafka, Redis)
   - Full adapter layer testing

5. Code Coverage Gate
   - JaCoCo >80% enforcement
   - Report generation

6. Security Scans
   - OWASP Dependency-Check
   - OWASP ZAP baseline scan

7. Deploy (optional)
   - Docker image push
   - Kubernetes deployment

Deployment Strategy

Canary Deployment (Progressive Delivery):

Step 1: Deploy to 10% of instances
        β†’ Run smoke tests
        β†’ Monitor metrics for 5 minutes

Step 2: If healthy, deploy to 50%
        β†’ Monitor for 5 minutes

Step 3: If healthy, deploy to 100%
        β†’ Complete rollout

On any failure: Automatic rollback to previous version

Health Metrics for Deployment:

  • Error rate < 1%
  • p95 latency < 500ms
  • All health checks passing
  • No increase in Kafka consumer lag

Smoke Tests:

#!/bin/bash
# Submit test transaction
response=$(curl -X POST http://transaction-service:8081/api/v1/transactions \
  -H "Content-Type: application/json" \
  -d '{"merchantId":"TEST001","amount":1,"currency":"USD","idempotencyKey":"smoke"}')

# Verify response contains transactionId
if echo "$response" | grep -q "transactionId"; then
  echo "βœ… Smoke test PASSED"
  exit 0
else
  echo "❌ Smoke test FAILED"
  exit 1
fi

πŸ“– Detailed CI/CD guide: docs/ARA_STRATEGY.md


πŸ“ Project Structure

merchantrail/
β”œβ”€β”€ .github/
β”‚   └── workflows/
β”‚       └── ci.yml                 # GitHub Actions CI/CD pipeline
β”œβ”€β”€ shared-kernel/                 # Shared value objects
β”‚   └── src/main/java/
β”‚       └── dev/merchantrail/shared/
β”‚           β”œβ”€β”€ Money.java         # Value object with currency
β”‚           β”œβ”€β”€ TransactionId.java # 16-char alphanumeric ID
β”‚           └── MerchantId.java    # 8-char alphanumeric ID
β”œβ”€β”€ api-gateway/                   # Spring Cloud Gateway
β”‚   └── src/main/resources/
β”‚       └── application.yml        # Routing & rate limiting config
β”œβ”€β”€ auth-service/                  # JWT authentication
β”‚   └── src/main/java/
β”‚       └── dev/merchantrail/auth/
β”œβ”€β”€ merchant-service/              # Merchant management
β”‚   └── src/main/java/
β”‚       └── dev/merchantrail/merchant/
β”œβ”€β”€ transaction-service/           # ⭐ Core orchestration service
β”‚   β”œβ”€β”€ src/main/java/
β”‚   β”‚   └── dev/merchantrail/transaction/
β”‚   β”‚       β”œβ”€β”€ domain/            # Pure business logic
β”‚   β”‚       β”‚   β”œβ”€β”€ Transaction.java
β”‚   β”‚       β”‚   β”œβ”€β”€ TransactionStatus.java
β”‚   β”‚       β”‚   └── Money.java
β”‚   β”‚       β”œβ”€β”€ application/       # Use cases
β”‚   β”‚       β”‚   β”œβ”€β”€ port/in/       # Commands, queries
β”‚   β”‚       β”‚   β”œβ”€β”€ port/out/      # Repository, messaging
β”‚   β”‚       β”‚   └── usecase/
β”‚   β”‚       └── adapter/           # Framework implementations
β”‚   β”‚           β”œβ”€β”€ in/web/        # REST controllers
β”‚   β”‚           β”œβ”€β”€ in/messaging/  # Kafka consumers
β”‚   β”‚           β”œβ”€β”€ out/persistence/ # JPA repositories
β”‚   β”‚           β”œβ”€β”€ out/messaging/ # Kafka producers
β”‚   β”‚           β”œβ”€β”€ out/client/    # gRPC clients
β”‚   β”‚           └── out/cache/     # Redis idempotency
β”‚   └── src/test/java/             # Unit & integration tests
β”œβ”€β”€ fraud-service/                 # Rule-based fraud detection
β”‚   β”œβ”€β”€ src/main/java/
β”‚   β”‚   └── dev/merchantrail/fraud/
β”‚   β”‚       β”œβ”€β”€ domain/
β”‚   β”‚       β”‚   β”œβ”€β”€ FraudRule.java
β”‚   β”‚       β”‚   └── FraudCheckResult.java
β”‚   β”‚       └── application/
β”‚   └── src/test/groovy/           # Spock tests
β”‚       └── dev/merchantrail/fraud/
β”‚           └── FraudRuleSpec.groovy
β”œβ”€β”€ bank-simulator-service/        # ISO 8583 bank simulator
β”‚   β”œβ”€β”€ src/main/proto/
β”‚   β”‚   └── bank_authorization.proto # gRPC service definition
β”‚   └── src/main/java/
β”‚       └── dev/merchantrail/bank/
β”œβ”€β”€ ledger-service/                # Double-entry bookkeeping
β”‚   └── src/main/java/
β”‚       └── dev/merchantrail/ledger/
β”‚           β”œβ”€β”€ domain/
β”‚           β”‚   └── LedgerEntry.java
β”‚           └── settlement/
β”‚               └── ISO20022Generator.java # Settlement file generator
β”œβ”€β”€ notification-service/          # Webhook callbacks
β”‚   └── src/main/java/
β”‚       └── dev/merchantrail/notification/
β”œβ”€β”€ infrastructure/
β”‚   β”œβ”€β”€ prometheus/
β”‚   β”‚   └── prometheus.yml         # Metrics scraping config
β”‚   └── grafana/
β”‚       β”œβ”€β”€ dashboards/            # Pre-configured dashboards
β”‚       └── datasources/           # Prometheus datasource
β”œβ”€β”€ docs/
β”‚   β”œβ”€β”€ sprints/
β”‚   β”‚   └── sprint-1.md            # Sprint planning & tracking
β”‚   β”œβ”€β”€ setup/
β”‚   β”‚   └── prerequisites.md       # Setup instructions
β”‚   β”œβ”€β”€ ARA_STRATEGY.md            # CI/CD strategy
β”‚   └── SECURITY_TESTING.md        # Security testing guide
β”œβ”€β”€ docker-compose.yml             # Local infrastructure
β”œβ”€β”€ pom.xml                        # Parent POM with dependency versions
β”œβ”€β”€ README.md                      # This file
β”œβ”€β”€ PROJECT_COMPLETE.md            # ⭐ Complete project overview
β”œβ”€β”€ TEST_STRATEGY.md               # Comprehensive testing guide
β”œβ”€β”€ QUICK_START.md                 # Quick start guide
└── .gitignore

πŸ“ Documentation

Core Documentation

Document Purpose Audience
PROJECT_COMPLETE.md ⭐ Complete system overview, all 8 services, metrics Everyone
README.md Project introduction, quick start, API docs New developers
QUICK_START.md Step-by-step setup guide (5 minutes) Developers
TEST_STRATEGY.md Full test pyramid explanation with examples SDETs, QA Engineers
docs/ARA_STRATEGY.md CI/CD, deployment, GitOps strategy DevOps Engineers
docs/SECURITY_TESTING.md OWASP security testing guide Security Engineers
docs/sprints/sprint-1.md Sprint planning, daily progress Project Managers

Additional Resources

Architecture Diagrams: See PROJECT_COMPLETE.md for sequence diagrams and data flow charts.

API Examples: Full curl examples in API Documentation section.

Testing Examples: See TEST_STRATEGY.md for test code snippets.


πŸ—ΊοΈ Roadmap

βœ… Completed Features (Phase 1-6)

  • Shared Kernel - Money, TransactionId, MerchantId value objects
  • Transaction Service - Clean architecture, idempotency, saga coordinator
  • Fraud Service - Rule-based detection with Spock tests
  • Bank Simulator - gRPC service with ISO 8583 format
  • Ledger Service - Double-entry bookkeeping, ISO 20022 settlement
  • Merchant Service - Onboarding, API key management
  • Auth Service - JWT authentication with RBAC
  • Notification Service - Webhook callbacks with retry logic
  • API Gateway - Rate limiting, routing, authentication
  • Event-Driven Architecture - Kafka saga pattern with compensation
  • Outbox Pattern - Reliable event publishing
  • Testing Infrastructure - Unit, integration, chaos tests
  • CI/CD Pipeline - GitHub Actions with security scans
  • Observability - Prometheus + Grafana
  • Documentation - 7 comprehensive guides

Phase 5: Advanced Testing βœ… COMPLETED

  • Chaos Engineering - Toxiproxy tests (database latency, Redis partition, Kafka failures)
  • Saga Compensation - Chaos validation of distributed transaction rollback
  • Circuit Breaker - Resilience4j chaos testing under failure scenarios
  • Load Testing - Gatling simulations (500+ concurrent users, spike tests)
  • Contract Testing - Spring Cloud Contract (REST API contracts)
  • E2E Protocol Tests - REST, gRPC, WebSocket, SFTP validation

Phase 6: Frontend Dashboard βœ… COMPLETED

  • React + TypeScript - Modern frontend with type safety
  • Real-time Dashboard - Transaction monitoring with live updates
  • WebSocket Integration - Socket.io for real-time transaction feeds
  • Interactive Charts - Recharts visualizations (trends, status distribution)
  • Transaction Management - List, filter, search with pagination
  • Responsive UI - Tailwind CSS mobile-first design
  • Docker Configuration - Multi-stage build with nginx
  • Production Ready - Health checks, API proxy, security headers

πŸ”„ Future Enhancements (Optional)

Phase 7: Production Infrastructure

  • Kubernetes manifests with Helm charts
  • Service mesh integration (Istio)
  • Multi-region deployment configuration
  • Advanced distributed tracing (Jaeger/Zipkin)
  • Mutation testing with PIT

🀝 Contributing

Contributions, issues, and feature requests are welcome!

How to Contribute

  1. Fork the repository
  2. Create a feature branch
    git checkout -b feature/amazing-feature
  3. Make your changes
  4. Commit your changes (use Conventional Commits format)
    git commit -m 'feat: add amazing feature'
    git commit -m 'fix: resolve transaction status bug'
    git commit -m 'docs: update API documentation'
  5. Push to the branch
    git push origin feature/amazing-feature
  6. Open a Pull Request

Coding Standards

Code Quality:

  • Follow Clean Code principles
  • Maintain >80% test coverage for domain/application layers
  • Write self-documenting code with clear variable names
  • Keep methods small and focused (Single Responsibility Principle)

Testing:

  • Write unit tests for all business logic
  • Add integration tests for adapter implementations
  • Update test documentation if adding new test patterns

Documentation:

  • Update README.md for significant changes
  • Add JavaDoc for public APIs
  • Document architectural decisions in code comments

Commit Messages (Conventional Commits):

feat: add new feature
fix: bug fix
docs: documentation changes
test: add or update tests
refactor: code refactoring
chore: maintenance tasks

Pull Request Guidelines

Before submitting:

  • All tests pass (mvn verify)
  • Code coverage meets requirements (>80%)
  • No compiler warnings
  • Documentation updated
  • Commit messages follow convention

PR Description should include:

  • What: Brief description of changes
  • Why: Reason for the changes
  • How: Technical approach
  • Testing: How you tested the changes

πŸ‘¨β€πŸ’» Author

Mahesh Singh

Full-stack software engineer specializing in distributed systems, microservices architecture, and payment domain expertise.

Connect with Me

Production Engineering Principles

MerchantRail is engineered around mission-critical payment availability and financial integrity:

  • High-Throughput Switching: Sub-50ms transaction routing via Card BIN matching and multi-issuer gRPC endpoints.
  • Stand-In Processing (STIP): Autonomous offline fallback preventing transaction loss during upstream network partitions.
  • Enterprise Spring Batch Clearing: Chunk-based clearing, fee netting, and ISO 20022 delivery.
  • Pivotal Cloud Foundry (PCF / Tanzu): Zero-downtime rolling deployments with automated service bindings (VCAP_SERVICES).
  • Full-Stack Financial Reporting: Real-time switching analytics, double-entry audit checks, and one-click reconciliation export.
  • Comprehensive Quality Assurance: Unit, data-driven (Spock), integration (Testcontainers), and OWASP security scans with >85% coverage.

πŸ™ Acknowledgments

  • Spring Team - For excellent Spring Boot framework and documentation
  • Testcontainers - For revolutionizing integration testing
  • OWASP - For security testing tools (ZAP, Dependency-Check)
  • ISO Standards - For payment industry specifications (ISO 8583, ISO 20022)
  • Apache Software Foundation - For Kafka and other open-source projects
  • PostgreSQL Global Development Group - For robust database system
  • Redis Labs - For high-performance caching solution
  • Prometheus & Grafana - For observability infrastructure

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

MIT License

Copyright (c) 2026 Mahesh Singh

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

πŸ“ž Contact & Support

Get Help

Report a Bug

Please include:

  1. Description of the issue
  2. Steps to reproduce
  3. Expected behavior
  4. Actual behavior
  5. System information (OS, Java version, Docker version)
  6. Log files (if applicable)

Request a Feature

Open a GitHub issue with the label enhancement and describe:

  1. The feature you'd like to see
  2. Why it would be useful
  3. How it might work

πŸ“ˆ Project Status

Current Version: 1.0.0-SNAPSHOT
Status: βœ… Production-Ready (Core Features Complete)
Build Status: βœ… Passing
Test Coverage: βœ… 85%+ (domain/application layers)
Last Updated: July 20, 2026

Service Health

Service Status Port Health Check
API Gateway βœ… Running 8080 http://localhost:8080/actuator/health
Auth Service βœ… Running 8086 http://localhost:8086/actuator/health
Merchant Service βœ… Running 8083 http://localhost:8083/actuator/health
Transaction Service βœ… Running 8081 http://localhost:8081/actuator/health
Fraud Service βœ… Running 8082 http://localhost:8082/actuator/health
Bank Simulator βœ… Running 9090 http://localhost:9090/actuator/health
Ledger Service βœ… Running 8085 http://localhost:8085/actuator/health
Notification Service βœ… Running 8087 http://localhost:8087/actuator/health

⭐ Star This Project

If you find MerchantRail valuable, please star it on GitHub!

GitHub stars


Built with ❀️ using Java, Spring Boot, Kafka, and industry-standard payment protocols

Get Started β€’ Documentation β€’ Architecture β€’ Testing β€’ Contact


MerchantRail - Production-Grade Distributed Payment Gateway
Demonstrating enterprise software engineering excellence

Copyright Β© 2026 Mahesh Singh. All rights reserved.

Issues