Skip to content

Repository files navigation

Forks Stargazers Issues LinkedIn


πŸ’ΈπŸ’ΈπŸ’Έ

Payment System

Production-grade P2P payment infrastructure with distributed fraud detection and event-driven architecture
Explore the code Β»

Read the Build Journal Β· Report Bug Β· Request Feature


Table of Contents
  1. About The Project
  2. Architecture
  3. Services
  4. Key Design Decisions
  5. Microservices Patterns
  6. Security
  7. Built With
  8. Getting Started
  9. API Reference
  10. Roadmap
  11. Contact
  12. Acknowledgments

About The Project

A distributed payment processing system built with Spring Boot microservices β€” modeled after the infrastructure layer that powers platforms like Razorpay or PayPal. Handles peer-to-peer money movement with fraud detection, event-driven architecture, and production-grade reliability patterns.

Built to answer one question: what actually happens when you tap "Pay"?

Key capabilities:

  • Never processes the same payment twice β€” Redis idempotency
  • Prevents double spending β€” Pessimistic DB locking
  • Zero message loss on crash β€” Outbox Pattern
  • Automatic fraud reversal β€” Saga Pattern
  • Real-time fraud detection β€” Rule-based engine with admin review queue

(back to top)


Architecture

                                        Client
                                           β”‚
                                    β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                    β”‚ API Gatewayβ”‚  JWT Auth Β· Rate Limiting
                                    β”‚  Port 8080 β”‚  Role-based Routing
                                    β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                                          β”‚
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚               β”‚               β”‚
                    β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
                    β”‚    Auth    β”‚  β”‚  Payment   β”‚  β”‚   Fraud    β”‚
                    β”‚  Service   β”‚  β”‚  Service   β”‚  β”‚  Service   β”‚
                    β”‚  Port 8081 β”‚  β”‚  Port 8082 β”‚  β”‚  Port 8083 β”‚
                    β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚               β”‚               β”‚
                       Auth DB       Payment DB       Fraud DB
                      (Postgres)     (Postgres)      (Postgres)
                                          β”‚
                                     Redis Cache
                                   (Idempotency +
                                    Rate Limiting)
                
                                ────── Kafka Event Bus ──────
                
                  Auth Service     β†’ user-registered-topic   β†’ Payment Service
                  Payment Service  β†’ payment-topic           β†’ Fraud Service
                  Payment Service  β†’ payment-topic           β†’ Notification Service
                  Fraud Service    β†’ fraud-alert-topic       β†’ Payment Service
                  Fraud Service    β†’ fraud-review-topic      β†’ Payment Service
                
                                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                    β”‚ Notification β”‚
                                    β”‚   Service    β”‚
                                    β”‚  Port 8084   β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                              β”‚   Grafana LGTM Stack    β”‚
                              β”‚  Traces Β· Logs Β· Metricsβ”‚
                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                
                         ╔════════════════════════════════════╗
                         β•‘      Docker Internal Network       β•‘
                         β•‘  Only port 8080 exposed externally β•‘
                         β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

(back to top)


Services

API Gateway (8080)

  • JWT validation on every request β€” no token, no entry
  • Role-based access control β€” /fraud/** restricted to ADMIN
  • Rate limiting per IP via Redis β€” 5 req/min on login, 10 req/min on payments
  • Strips untrusted X-User-Id headers β€” injects verified identity downstream

Auth Service (8081)

  • User registration and login
  • JWT issuance with userId as subject and role as claim
  • BCrypt password hashing
  • Publishes user-registered event on registration

Payment Service (8082)

  • Double-entry ledger β€” every transaction creates DEBIT and CREDIT entries
  • Idempotency via Redis β€” duplicate requests return same response without reprocessing
  • Pessimistic DB locking β€” prevents double spending on concurrent requests
  • Outbox Pattern β€” guaranteed Kafka delivery even on service crash
  • Account ownership validation β€” users can only move money from their own accounts
  • Account number abstraction β€” UUIDs stay internal, users interact via account numbers
  • Consumes user-registered β†’ auto-creates account on registration
  • Consumes fraud-alert β†’ reverses transaction and freezes account (Saga)
  • Consumes fraud-review β†’ unfreezes account on admin approval

Notification Service (8084)

  • Consumes payment events from Kafka
  • Async payment confirmations β€” never blocks payment processing
  • Extensible to email/SMS providers

Fraud Detection Service (8083)

  • Rule-based fraud engine β€” evaluates every transaction
  • Rules: high value (β‰₯ β‚Ή10,000), round numbers, self-transfer, rapid successive payments
  • Saves alerts to dedicated fraud DB with risk levels (LOW, MEDIUM, HIGH)
  • Admin review queue β€” approve (unfreeze) or reject (keep frozen) via outbox pattern
  • Publishes fraud alerts to trigger Saga compensation in Payment Service

(back to top)


Key Design Decisions

Outbox Pattern β€” Direct Kafka publishing risks message loss if service crashes mid-transaction. Events are written to an outbox table in the same DB transaction. A scheduler reads and publishes. Atomicity guaranteed.

Idempotency with Redis β€” Every payment request carries a client-generated Idempotency-Key header. Redis stores the key with TTL. Duplicate requests return the original response without reprocessing β€” prevents double charges on network retries.

Pessimistic Locking β€” Concurrent payments to the same account can cause double spending. @Lock(PESSIMISTIC_WRITE) on account fetches ensures one transaction processes at a time per account.

Saga Pattern β€” Fraud detection is async. Payment processes first, fraud analysis follows. When fraud is confirmed, a compensation event reverses the transaction and freezes the account. No records deleted β€” full audit trail preserved.

Kafka over RabbitMQ β€” Multiple services consume every payment event independently. Kafka's message retention means no events are lost if a service goes down β€” consumer catches up on restart.

Database per Service β€” Each service owns its data. No cross-service JPA relationships. Services communicate via events. Payment DB, Fraud DB, and Auth DB are completely independent.

Account Number Abstraction β€” Users share account numbers (e.g. ABC123DEF456). Internal UUIDs never surface in the API. Account number to UUID resolution happens server-side.

JWT at Gateway Only β€” Auth Service issues JWT. Gateway validates it using a shared secret β€” no Auth Service call needed per request. Downstream services trust the X-User-Id header injected by Gateway.

(back to top)


Microservices Patterns

Pattern Implementation
API Gateway Spring Cloud Gateway β€” single entry point
Database per Service Auth DB, Payment DB, Fraud DB
Event-Driven Architecture Kafka backbone across all services
Outbox Pattern Payment Service + Fraud Service
Idempotent Consumer Redis idempotency keys
Saga Pattern Fraud reversal compensation flow
Pessimistic Locking Account fetches during payment processing

(back to top)


Security

  • JWT validation at Gateway β€” no unauthenticated request reaches any service
  • Header stripping β€” client-supplied X-User-Id removed, Gateway injects verified identity
  • Account ownership validation β€” users can only deposit/transfer from their own accounts
  • Role-based access β€” ADMIN role required for fraud endpoints
  • Rate limiting per IP β€” brute force and spam protection on auth and payment routes
  • BCrypt password hashing
  • Internal network isolation β€” only port 8080 exposed externally via Docker
  • No UUIDs in API surface β€” account numbers only
  • IDOR prevention β€” account ownership checked on every write operation

(back to top)


Built With

Java Spring Kafka Redis Postgres Docker Grafana

(back to top)


Getting Started

Prerequisites

  • Docker and Docker Compose
  • Java 21
  • Maven

Installation

  1. Clone the repository

    git clone https://github.com/abubakkar-siddhiq/payment-system.git
    cd payment-system
  2. Start infrastructure

    docker-compose up -d

    Starts: PostgreSQL (x3), Redis, Kafka (KRaft), Grafana LGTM

  3. Build each service

    cd payment-service && mvn clean package -DskipTests && cd ..
    cd authservice && mvn clean package -DskipTests && cd ..
    cd frauddetectionsystem && mvn clean package -DskipTests && cd ..
    cd notificationservice && mvn clean package -DskipTests && cd ..
    cd gateway && mvn clean package -DskipTests && cd ..
  4. Start services in order

    1. Auth Service          β†’ port 8081
    2. Payment Service       β†’ port 8082
    3. Fraud Service         β†’ port 8083
    4. Notification Service  β†’ port 8084
    5. API Gateway           β†’ port 8080
    
  5. Create admin user

    UPDATE users SET role = 'ADMIN' WHERE email = 'admin@yourdomain.com';

(back to top)


API Reference

Auth

POST /api/v1/auth/register    β†’ Register, returns JWT + userId
POST /api/v1/auth/login       β†’ Login, returns JWT + userId

Accounts

GET  /api/v1/accounts/me                        β†’ My account info
GET  /api/v1/accounts/{accountNumber}/balance   β†’ My balance
POST /api/v1/accounts/{accountNumber}/deposit   β†’ Deposit funds
GET  /api/v1/accounts                           β†’ List all (ADMIN only)

Payments

POST /api/v1/payments    β†’ Process payment between accounts

Required headers:

Authorization: Bearer <jwt>
Idempotency-Key: <uuid>

Body:

{
  "senderAccountNumber": "ABC123DEF456",
  "receiverAccountNumber": "XYZ789GHI012",
  "amount": 500.00
}

Fraud (ADMIN only)

GET /api/v1/fraud/alerts              β†’ List all fraud alerts
GET /api/v1/fraud/alerts/{id}         β†’ Get specific alert
PUT /api/v1/fraud/alerts/{id}/approve β†’ Legitimate β€” unfreeze account
PUT /api/v1/fraud/alerts/{id}/reject  β†’ Confirmed fraud β€” keep frozen

Example Flow

1. Register         POST /api/v1/auth/register
                    β†’ Account auto-created via Kafka event

2. Login            POST /api/v1/auth/login
                    β†’ Receive JWT + account number

3. Deposit          POST /api/v1/accounts/{number}/deposit
                    β†’ Fund your account

4. Pay              POST /api/v1/payments
                    β†’ Money moves, ledger updated, Kafka event fired

5. Notification     β†’ Notification Service logs confirmation

6. Fraud Check      β†’ Fraud Service analyzes transaction
                    β†’ If HIGH risk: account frozen, payment reversed

7. Admin Review     β†’ PUT /api/v1/fraud/alerts/{id}/approve
                    β†’ Account unfrozen

(back to top)


Roadmap

  • Payment Service with idempotency and pessimistic locking
  • Outbox Pattern for guaranteed Kafka delivery
  • Fraud Detection with rule-based engine
  • Saga Pattern for fraud reversal
  • API Gateway with JWT and rate limiting
  • Distributed tracing with Grafana LGTM
  • Docker network isolation
  • Service discovery via Eureka/Consul
  • ML-based fraud scoring
  • Kubernetes orchestration
  • CI/CD pipeline
  • Load testing with k6

(back to top)


Contact

Abubakkar Siddhiq - LinkedIn

Project Link: https://github.com/abubakkar-siddhiq/payment-system

Build Journal: medium blog

(back to top)


Acknowledgments

(back to top)


About

Distributed payment system built with microservices and event-driven architecture, leveraging Kafka for asynchronous processing and a rule-based fraud detection engine.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages