A production-style banking middleware that demonstrates how modern digital channels integrate with core banking systems and payment networks using ISO 8583 and ISO 20022, designed for high-volume, 24/7 financial operations.
This repository is a showcase project that demonstrates real-world banking middleware design and engineering practices, inspired by production experience in a regulated banking environment.
All external dependencies such as core banking systems, payment switches, and networks are mocked, while preserving:
- Realistic transaction flows
- Architectural decisions
- Failure handling strategies
- Compliance-aware design
This project is not a simulator of a specific bank, but a transferable reference architecture.
For a detailed look into the logical components, runtime transaction flows, and physical deployment models, please see our complete Architecture Guide.
For a detailed guide on deploying this application to a cloud environment like AWS and handling specific networking challenges, please see:
- AWS Cloud Deployment Guide: Recommended architecture using ECS Fargate, CI/CD pipelines, and security best practices.
- ISO 8583 Networking Guide: Strategies for handling single, persistent TCP connections required by legacy banking switches.
- Language: Java 17
- Framework: Spring Boot 3.3.5
- Protocols: REST, ISO 8583, ISO 20022
- Libraries:
jpos: ISO 8583 message parsing.jackson-dataformat-xml: Robust ISO 20022 XML handling (pain.001,pacs.002).spring-cloud-starter-circuitbreaker-resilience4j: Circuit Breaker implementation for fault tolerance.micrometer-tracing-bridge-brave: Distributed tracing for observability.spring-retry: For automatic retry logic on transient failures.spring-boot-starter-aop: For implementing cross-cutting concerns like idempotency.
- Unit Testing: JUnit, Mockito, JaCoCo
- Circuit Breakers: Implemented with Resilience4j. If a downstream service fails repeatedly, the circuit opens, preventing the middleware from waiting on a failing service and providing an immediate fallback response.
- Idempotency: Prevents duplicate processing of state-changing operations (Fund Transfer) via an
X-Request-IDheader, which is crucial in timeout and retry scenarios. - Retry Mechanism: Uses
spring-retryto automatically retry operations against transient, short-lived failures, avoiding unnecessary error responses to the client.
- Fail-Fast with Circuit Breakers: The primary mechanism to manage latency is the "fail-fast" behavior of the circuit breaker. Instead of letting a request hang for a slow downstream service, the breaker opens and returns an immediate error, protecting system resources.
- Asynchronous Internal Processing: For long-running processes (like ISO 8583 transactions over a slow link), the recommended architecture in the ISO 8583 Networking Guide uses message queues. This allows the API to quickly accept a request and respond later via a webhook or polling, preventing long-held HTTP connections.
- Configurable Timeouts: While not explicitly configured in this demo, a production setup would involve setting timeouts at multiple levels:
- HTTP Client: For calls to other microservices.
- Resilience4j TimeLimiter: To wrap any long-running call in a timeout decorator.
- Database: Connection and query timeouts.
- Payload Masking: Sensitive data in logs (Account Numbers, Names) is automatically masked (e.g.,
12******90) to comply with PII/PCI-DSS standards. - Correlation & Trace IDs: Achieved via Micrometer Tracing.
- End-to-End Transaction Tracing: Logs automatically include a Trace ID and Span ID, enabling request tracing across a distributed system. This is critical for pinpointing which service in a chain is introducing latency.
- Log Format:
INFO [batavia,65b8e9f8e9f8e9f8,65b8e9f8e9f8e9f8] : Processing balance inquiry...
- Log Format:
- Java 17
- Maven
- Clone the repository:
git clone https://github.com/pauluswi/batavia.git
- Build the project:
Use Maven to compile the source code and install dependencies.
mvn clean install
- Run the application:
The service will start on the default port
mvn spring-boot:run
8080.
Processes a balance inquiry by transforming the JSON request into an ISO 8583 or ISO 20022 message.
- Endpoint:
POST /api/{protocol}/customer/balance{protocol}can be8583or20022.
- Request Body:
{ "bankAccountNumber": "123456", "customerFullName": "Andi Lukito" }
Initiates a fund transfer using either ISO 8583 or ISO 20022 (pain.001). This endpoint is idempotent and protected by a circuit breaker.
- Endpoint:
POST /api/{protocol}/transfer{protocol}can be8583or20022.
- Headers:
Content-Type: application/jsonX-Request-ID: <unique-uuid>(Required for Idempotency)
- Request Body:
{ "sourceAccountNumber": "1234567890", "destinationAccountNumber": "0987654321", "amount": 100000, "currency": "IDR", "description": "Payment for Invoice" } - Success Response (200 OK):
{ "responseCode": "00", "transactionId": "RRN123456", "message": "Transfer Successful" }
This project:
- Does not represent any specific bank or institution
- Uses mocked data and systems exclusively
- Is intended for educational and portfolio showcase purposes only
Slamet Widodo (Wied)
Senior Software Engineer / Software Architect
Banking Middleware • Payments • Integration • Architecture