Shubh2-0
PayFlow
Java

Production-grade Digital Wallet & Payment System built with Microservices Architecture. Java 17 | Spring Boot 3 | Spring Security + JWT | Hibernate | MySQL | RabbitMQ | Docker | JUnit 5. Features: pessimistic locking, idempotent transactions, deadlock prevention, event-driven notifications, daily transfer limits.

Last updated Jul 29, 2026
10
Stars
0
Forks
0
Issues
0
Stars/day
Attention Score
37
Language breakdown
Java 99.8%
Dockerfile 0.2%
โ–ธ Files click to expand
README

PayFlow Banner

๐Ÿ’ณ PayFlow

Digital Wallet & Payment System

A production-grade payment backend built with Microservices Architecture

Java Spring Boot MySQL RabbitMQ Docker

Getting Started ยท API Docs ยท Architecture ยท Design Decisions


๐ŸŽฏ What is PayFlow?

PayFlow is a digital wallet system โ€” think of it like a simplified version of Paytm, PhonePe, or Google Pay's backend.

What can users do?

  • ๐Ÿ“ Sign up & log in securely (passwords are encrypted, sessions use JWT tokens)
  • ๐Ÿ’ฐ Create a wallet and add money to it
  • ๐Ÿ’ธ Send money to other users instantly
  • ๐Ÿ“Š View transaction history and download wallet statements
  • โญ Save frequent contacts as beneficiaries for quick transfers
  • ๐Ÿ”” Get notified automatically when a transaction happens
What makes this a real engineering project (not a tutorial)?

| Challenge | How PayFlow Solves It | |-----------|----------------------| | Two people send money from same wallet at once | Pessimistic Locking โ€” database locks the wallet row, processes one at a time | | Network glitch causes same payment request twice | Idempotency Keys โ€” duplicate detected, money deducted only once | | Two transfers between same wallets cause system freeze | Deadlock Prevention โ€” wallets always locked in fixed order | | Sending email slows down the payment | Event-Driven Architecture โ€” payment completes instantly, email sent in background via RabbitMQ | | One service goes down, others break | Microservices โ€” each service runs independently with its own database |


๐Ÿ— Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                         API Clients                             โ”‚
โ”‚                   (Mobile App / Web App)                        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
            โ”‚                  โ”‚                  โ”‚
            โ–ผ                  โ–ผ                  โ–ผ
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  โ”‚  ๐Ÿ” Auth        โ”‚ โ”‚  ๐Ÿ’ฐ Wallet       โ”‚ โ”‚  ๐Ÿ”” Notification โ”‚
  โ”‚  Service        โ”‚ โ”‚  Service         โ”‚ โ”‚  Service         โ”‚
  โ”‚  (:8081)        โ”‚ โ”‚  (:8082)         โ”‚ โ”‚  (:8083)         โ”‚
  โ”‚                 โ”‚ โ”‚                  โ”‚ โ”‚                  โ”‚
  โ”‚ โ€ข Register      โ”‚ โ”‚ โ€ข Create Wallet  โ”‚ โ”‚ โ€ข Email Alerts   โ”‚
  โ”‚ โ€ข Login (JWT)   โ”‚ โ”‚ โ€ข Add Money      โ”‚ โ”‚ โ€ข Templates      โ”‚
  โ”‚ โ€ข User Profile  โ”‚ โ”‚ โ€ข Send Money     โ”‚ โ”‚ โ€ข Retry Failed   โ”‚
  โ”‚ โ€ข Role Access   โ”‚ โ”‚ โ€ข Statement      โ”‚ โ”‚ โ€ข Statistics     โ”‚
  โ”‚                 โ”‚ โ”‚ โ€ข Beneficiaries  โ”‚ โ”‚                  โ”‚
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
           โ”‚                  โ”‚  โ”‚                   โ”‚
           โ”‚                  โ”‚  โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
           โ”‚                  โ”‚  โ””โ”€โ”€โ–บโ”‚ ๐Ÿฐ        โ”‚โ”€โ”€โ”€โ”˜
           โ”‚                  โ”‚      โ”‚ RabbitMQ   โ”‚
           โ”‚                  โ”‚      โ”‚ (Messages) โ”‚
           โ”‚                  โ”‚      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  โ”‚  ๐Ÿ—„๏ธ payflow   โ”‚ โ”‚  ๐Ÿ—„๏ธ payflow  โ”‚ โ”‚  ๐Ÿ—„๏ธ payflow_    โ”‚
  โ”‚  auth (MySQL)   โ”‚ โ”‚  wallet (MySQL) โ”‚ โ”‚  notification    โ”‚
  โ”‚                 โ”‚ โ”‚                 โ”‚ โ”‚  (MySQL)         โ”‚
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
Each service has its own database โ€” no shared tables, no tight coupling. Services communicate through REST APIs (synchronous) and RabbitMQ (asynchronous events).

๐Ÿ›  Tech Stack

Java
Java 17
Spring
Spring Boot 3
MySQL
MySQL 8
Docker
Docker
RabbitMQ
RabbitMQ

| Category | Technologies | |:---------|:------------| | Language | Java 17 | | Framework | Spring Boot 3.2, Spring Security, Spring Data JPA | | Authentication | JWT (JSON Web Tokens), BCrypt password hashing | | ORM & Database | Hibernate, MySQL 8 (one database per service) | | Messaging | RabbitMQ (AMQP) for async event-driven communication | | API Docs | Swagger / OpenAPI 3 (interactive API playground) | | Testing | JUnit 5, Mockito, H2 in-memory DB (60+ test cases) | | Containerization | Docker, Docker Compose (one-command startup) | | CI/CD | GitHub Actions (automated build + test on every push) |


โœจ Features

๐Ÿ” Auth Service โ€” User Identity & Security

| Feature | Description | |---------|-------------| | User Registration | Sign up with email, username, password (validated) | | JWT Login | Login returns a signed token โ€” no session storage needed | | Password Security | BCrypt hashing โ€” passwords never stored in plain text | | Role-Based Access | ADMIN and USER roles with different permissions | | Protected Routes | Profile endpoint only accessible with valid JWT |

๐Ÿ’ฐ Wallet Service โ€” Core Payment Engine

| Feature | Description | |---------|-------------| | Wallet Management | Create, view, freeze, and unfreeze wallets | | Add Money | Top-up wallet balance (like adding money to Paytm) | | Send Money | Transfer to another wallet with real-time balance update | | Pessimistic Locking | Database-level locks prevent double-spending | | Idempotent Transactions | Duplicate requests safely return same result | | Deadlock Prevention | Wallets locked in ascending ID order | | Daily Transfer Limits | Configurable limit (default: โ‚น1,00,000/day) | | Transaction Reversal | Reverse completed transactions (compensating transaction) | | Beneficiary Management | Save, list, and remove frequent transfer recipients | | Wallet Statements | Date-filtered history with total credits/debits summary | | BigDecimal Precision | All money calculations use BigDecimal (no rounding errors) |

๐Ÿ”” Notification Service โ€” Smart Alerts

| Feature | Description | |---------|-------------| | Event-Driven | Listens to RabbitMQ โ€” gets triggered automatically on transactions | | Email Notifications | Sends transaction receipts and alerts | | Templates | Create reusable notification templates with {{variables}} | | Retry Mechanism | Failed notifications auto-retry (configurable max retries) | | Statistics Dashboard | Track sent, pending, and failed notification counts |

๐Ÿ“ก API Endpoints

๐Ÿ” Authentication (auth-service โ€” port 8081)

| Method | Endpoint | Description | |:------:|----------|-------------| | POST | /api/auth/register | Register a new user | | POST | /api/auth/login | Login and receive JWT token | | GET | /api/auth/profile | Get current user profile (requires JWT) |

๐Ÿ’ฐ Wallets (wallet-service โ€” port 8082)

| Method | Endpoint | Description | |:------:|----------|-------------| | POST | /api/wallets | Create a new wallet | | GET | /api/wallets/{walletId} | Get wallet details | | GET | /api/wallets/user/{userId} | Get wallet by user ID | | PUT | /api/wallets/{walletId}/freeze | Freeze a wallet | | PUT | /api/wallets/{walletId}/unfreeze | Unfreeze a wallet |

๐Ÿ’ธ Transactions (wallet-service โ€” port 8082)

| Method | Endpoint | Description | |:------:|----------|-------------| | POST | /api/transactions/wallets/{walletId}/add-money | Add money to wallet | | POST | /api/transactions/wallets/{walletId}/send-money | Send money to another wallet | | GET | /api/transactions/{transactionId} | Get transaction details | | GET | /api/transactions/wallets/{walletId}/history | Transaction history (paginated) | | GET | /api/transactions/wallets/{walletId}/statement | Wallet statement (date range) | | POST | /api/transactions/{transactionId}/reverse | Reverse a transaction |

โญ Beneficiaries (wallet-service โ€” port 8082)

| Method | Endpoint | Description | |:------:|----------|-------------| | POST | /api/wallets/{walletId}/beneficiaries | Add a beneficiary | | GET | /api/wallets/{walletId}/beneficiaries | List all beneficiaries | | DELETE | /api/wallets/{walletId}/beneficiaries/{id} | Remove a beneficiary |

๐Ÿ”” Notifications (notification-service โ€” port 8083)

| Method | Endpoint | Description | |:------:|----------|-------------| | GET | /api/notifications | List all notifications | | GET | /api/notifications/{id} | Get notification details | | POST | /api/notifications/{id}/retry | Retry a failed notification | | GET | /api/notifications/stats | Notification statistics | | POST | /api/notification-templates | Create notification template | | GET | /api/notification-templates | List all templates | | PUT | /api/notification-templates/{id} | Update a template | | DELETE | /api/notification-templates/{id} | Delete a template |


๐Ÿš€ Getting Started

Prerequisites

  • โ˜• Java 17+
  • ๐Ÿ“ฆ Maven 3.8+
  • ๐Ÿณ Docker & Docker Compose

Quick Start (Docker) โ€” One Command Setup

git clone https://github.com/Shubh2-0/PayFlow.git
cd PayFlow
docker-compose up --build

That's it! All services will be running:

| Service | URL | Swagger Docs | |---------|-----|:------------:| | ๐Ÿ” Auth Service | http://localhost:8081 | Open | | ๐Ÿ’ฐ Wallet Service | http://localhost:8082 | Open | | ๐Ÿ”” Notification Service | http://localhost:8083 | Open | | ๐Ÿฐ RabbitMQ Dashboard | http://localhost:15672 | โ€” |

Manual Setup (without Docker)

  • Start MySQL and create databases:
CREATE DATABASE payflow_auth;
   CREATE DATABASE payflow_wallet;
   CREATE DATABASE payflow_notification;
  • Start RabbitMQ on port 5672
  • Run each service:
cd auth-service && mvn spring-boot:run
   cd wallet-service && mvn spring-boot:run
   cd notification-service && mvn spring-boot:run

๐Ÿ“˜ Usage Examples

1. Register a user:

curl -X POST http://localhost:8081/api/auth/register \   -H "Content-Type: application/json" \   -d '{     "username": "john",     "email": "john@example.com",     "password": "secret123",     "fullName": "John Doe"   }'

2. Login and get JWT token:

curl -X POST http://localhost:8081/api/auth/login \   -H "Content-Type: application/json" \   -d '{"username": "john", "password": "secret123"}'

3. Add โ‚น5,000 to wallet:

curl -X POST http://localhost:8082/api/transactions/wallets/1/add-money \   -H "Content-Type: application/json" \   -d '{     "amount": 5000.00,     "description": "Initial top-up",     "idempotencyKey": "topup-001"   }'

4. Send โ‚น1,500 to another wallet:

curl -X POST http://localhost:8082/api/transactions/wallets/1/send-money \   -H "Content-Type: application/json" \   -d '{     "receiverWalletId": 2,     "amount": 1500.00,     "description": "Payment for services",     "idempotencyKey": "txn-001"   }'


๐Ÿ“ Project Structure

PayFlow/
โ”‚
โ”œโ”€โ”€ ๐Ÿณ docker-compose.yml          # One-command setup for all services
โ”œโ”€โ”€ ๐Ÿ—„๏ธ init-db.sql                 # Auto-creates all 3 databases
โ”œโ”€โ”€ ๐Ÿ“ฆ pom.xml                      # Parent Maven POM
โ”‚
โ”œโ”€โ”€ ๐Ÿ” auth-service/                # Authentication & User Management
โ”‚   โ””โ”€โ”€ src/main/java/
โ”‚       โ”œโ”€โ”€ controller/             # REST API endpoints
โ”‚       โ”œโ”€โ”€ dto/                    # Request/Response objects
โ”‚       โ”œโ”€โ”€ entity/                 # User, Role (JPA entities)
โ”‚       โ”œโ”€โ”€ exception/              # Error handling
โ”‚       โ”œโ”€โ”€ repository/             # Database queries
โ”‚       โ”œโ”€โ”€ security/               # JWT filter, config, token service
โ”‚       โ””โ”€โ”€ service/                # Business logic
โ”‚
โ”œโ”€โ”€ ๐Ÿ’ฐ wallet-service/              # Core Payment Engine
โ”‚   โ””โ”€โ”€ src/main/java/
โ”‚       โ”œโ”€โ”€ controller/             # Wallet, Transaction, Beneficiary APIs
โ”‚       โ”œโ”€โ”€ dto/                    # 10 DTOs for all operations
โ”‚       โ”œโ”€โ”€ entity/                 # Wallet, Transaction, Beneficiary
โ”‚       โ”œโ”€โ”€ enums/                  # WalletStatus, TransactionType/Status
โ”‚       โ”œโ”€โ”€ event/                  # RabbitMQ event publisher
โ”‚       โ”œโ”€โ”€ exception/              # 6 domain-specific exceptions
โ”‚       โ”œโ”€โ”€ repository/             # Queries with pessimistic locking
โ”‚       โ””โ”€โ”€ service/                # Transaction logic, daily limits
โ”‚
โ”œโ”€โ”€ ๐Ÿ”” notification-service/        # Event-Driven Notifications
โ”‚   โ””โ”€โ”€ src/main/java/
โ”‚       โ”œโ”€โ”€ config/                 # RabbitMQ queue/exchange setup
โ”‚       โ”œโ”€โ”€ controller/             # Notification & Template APIs
โ”‚       โ”œโ”€โ”€ dto/                    # TransactionEvent, responses
โ”‚       โ”œโ”€โ”€ entity/                 # Notification, Template
โ”‚       โ”œโ”€โ”€ listener/               # RabbitMQ event consumer
โ”‚       โ”œโ”€โ”€ repository/             # Database queries
โ”‚       โ””โ”€โ”€ service/                # Email & notification logic
โ”‚
โ””โ”€โ”€ ๐Ÿ”„ .github/workflows/
    โ””โ”€โ”€ ci.yml                      # GitHub Actions CI pipeline

๐Ÿง  Design Decisions

These are the engineering choices that make PayFlow production-grade, not just another CRUD project.

1. Why Pessimistic Locking for Balance Updates?

Problem: If two requests read wallet balance (โ‚น1000) at the same time, both deduct โ‚น500, and both write โ‚น500 โ€” the user loses โ‚น500.

Solution: SELECT ... FOR UPDATE locks the wallet row. Second request waits until first completes. No money is lost.

Why not Optimistic Locking? In payments, retrying a failed transaction is risky and expensive. Better to wait 10ms for a lock than risk incorrect balances.

2. Why Idempotency Keys?

Problem: User clicks "Pay" โ†’ network timeout โ†’ user clicks again โ†’ money deducted twice.

Solution: Every transaction has a unique idempotencyKey. If the same key comes again, we return the existing result instead of creating a new transaction. This is how Stripe, Razorpay, and every production payment API works.

3. Why Ordered Locking for Deadlock Prevention?

Problem: Transfer Aโ†’B locks wallet A, then tries to lock B. Simultaneously, transfer Bโ†’A locks wallet B, then tries to lock A. Both wait forever = deadlock.

Solution: Always lock the wallet with the smaller ID first. Both transfers lock A first, then B. No circular wait = no deadlock. Ever.

4. Why Event-Driven Notifications?

Problem: Sending email inside the payment transaction โ€” if email server is slow (3 seconds), payment is slow. If email fails, does the payment rollback?

Solution: Payment completes โ†’ event published to RabbitMQ โ†’ notification service picks it up independently. Payment is fast, email failures don't affect payments, and we can add new consumers (SMS, push notifications) without changing wallet-service.

5. Why Database Per Service?

Problem: Shared database = one service changes a table, other service breaks. Tight coupling defeats the purpose of microservices.

Solution: payflowauth, payflowwallet, payflow_notification โ€” three separate databases. Each service owns its data. No cross-database joins.


๐Ÿงช Testing

60+ test cases across 12 test classes in all three services:

| Type | What it Tests | Tools | |------|--------------|-------| | Unit Tests | Service layer logic in isolation | JUnit 5, Mockito | | Controller Tests | API endpoints, request validation, error responses | @WebMvcTest, MockMvc | | Repository Tests | Database queries and JPA mappings | @DataJpaTest, H2 |

# Run all tests
cd auth-service && mvn test
cd wallet-service && mvn test
cd notification-service && mvn test

๐Ÿ”„ CI/CD

GitHub Actions automatically runs on every push:

  • โ˜• Sets up JDK 17 (Temurin) with Maven caching
  • ๐Ÿ”จ Builds all three services (mvn clean verify)
  • ๐Ÿงช Runs complete test suite

๐Ÿ“„ License

This project is licensed under the MIT License.


Built with โค๏ธ by Shubham Bhati

โญ Star this repo if you found it useful!


๐Ÿ‘ค Author

๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท Shubh2-0/PayFlow ยท Updated daily from GitHub