A highly scalable, event-driven payment backend inspired by modern payment platforms, built with Spring Boot microservices, Apache Kafka, Redis, MySQL, Neo4j, and a complete observability stack.
This project is a PayPal-like payment backend designed around the principles used in large-scale financial systems:
- 🔐 Secure authentication and authorization
- 💰 Payment intent and transaction processing
- 👛 Wallet/account management
- 📒 Double-entry-style ledger concepts
- ⚡ Event-driven communication using Kafka
- 🚀 Redis-powered caching and fast data access
- 🕸️ Transaction relationship modelling with Neo4j
- 🛡️ Fault tolerance and resilient service boundaries
- 📊 Metrics, dashboards, and distributed tracing
- 🐳 Containerized local development
- ☸️ Kubernetes-ready deployment
The goal is not simply to build CRUD APIs — it is to understand how a distributed payment system can be designed, communicated, observed, and operated.
| Capability | Implementation |
|---|---|
| 🧩 Microservices | Spring Boot |
| 🚪 API Entry Point | Spring Cloud Gateway |
| 🔎 Service Discovery | Eureka |
| ⚡ Event Streaming | Apache Kafka |
| ⚡ Caching | Redis |
| 💾 Relational Storage | MySQL |
| 🕸️ Graph Storage | Neo4j |
| 📈 Metrics | Prometheus |
| 📊 Visualization | Grafana |
| 🔍 Distributed Tracing | Zipkin |
| 🐳 Containers | Docker / Docker Compose |
| ☸️ Orchestration | Kubernetes |
| 🏗️ Build System | Maven |
| ☕ Runtime | Java 17 |
The platform follows a domain-oriented microservice architecture where services own their responsibilities and communicate through synchronous APIs where required and Kafka events for asynchronous workflows.
flowchart TB
Client["🌐 Client / Frontend"]
Gateway["🚪 API Gateway"]
Auth["🔐 Auth Service"]
User["👤 User Service"]
Account["💳 Account Service"]
Merchant["🏪 Merchant Service"]
PaymentIntent["💰 Payment Intent Service"]
Order["🛒 Order Service"]
Balance["💵 Balance Project Service"]
Payout["🏦 Payout Service"]
Ledger["📒 Ledger Service"]
Kafka["⚡ Apache Kafka"]
Events["📦 Event Contracts"]
Redis["⚡ Redis"]
MySQL["🗄️ MySQL"]
Neo4j["🕸️ Neo4j"]
Monitoring["📊 Prometheus + Grafana"]
Zipkin["🔍 Zipkin"]
Discovery["🔎 Eureka Discovery"]
Client --> Gateway
Gateway --> Auth
Gateway --> User
Gateway --> Account
Gateway --> Merchant
Gateway --> PaymentIntent
Gateway --> Order
Gateway --> Payout
PaymentIntent --> Kafka
Order --> Kafka
Balance --> Kafka
Payout --> Kafka
Kafka --> Ledger
Kafka --> Balance
Kafka --> Events
User --> MySQL
Account --> MySQL
Merchant --> MySQL
Order --> MySQL
PaymentIntent --> MySQL
Payout --> MySQL
Balance --> Redis
Ledger --> MySQL
Ledger --> Neo4j
Auth --> Discovery
User --> Discovery
Account --> Discovery
Merchant --> Discovery
PaymentIntent --> Discovery
Order --> Discovery
Ledger --> Discovery
Payout --> Discovery
Gateway -.-> Monitoring
Auth -.-> Monitoring
PaymentIntent -.-> Monitoring
Ledger -.-> Monitoring
Gateway -.-> Zipkin
PaymentIntent -.-> Zipkin
Ledger -.-> Zipkin
The architecture is intentionally designed around independent services, asynchronous events, clear domain boundaries, and observability.
Central entry point for external requests.
Responsibilities
- Request routing
- Cross-cutting concerns
- Authentication propagation
- Rate limiting / gateway policies
- Service discovery integration
Responsible for identity and authentication.
Responsibilities
- User authentication
- Credential validation
- Token generation
- Authorization-related flows
Owns user profile and user-domain information.
Responsibilities
- User registration data
- Profile management
- User lookup
- User lifecycle operations
Manages customer financial accounts / wallet-like account state.
Responsibilities
- Account creation
- Account status
- Balance-related account metadata
- Account ownership
Manages merchant-specific information.
Responsibilities
- Merchant onboarding
- Merchant profiles
- Merchant configuration
- Merchant lifecycle
The entry point for payment processing.
Responsibilities
- Create payment intents
- Validate payment requests
- Track payment lifecycle
- Publish payment events
Typical flow:
CREATE_PAYMENT
↓
VALIDATE
↓
PAYMENT_PROCESSING
↓
PAYMENT_SUCCEEDED / PAYMENT_FAILED
↓
PUBLISH EVENT
Owns payment-related order information.
Responsibilities
- Create orders
- Maintain order state
- Associate orders with payment intents
- Publish order events
Maintains derived balance projections using events.
Kafka Event
↓
Balance Projector
↓
Update Redis / Read Model
This approach keeps frequently accessed balance information fast while the ledger remains the authoritative financial record.
The ledger is one of the most important parts of the system.
Instead of treating a payment as simply:
balance = balance - amount
the system models financial activity as immutable transaction records.
Conceptually:
Payment
│
├── Debit Account A
│
└── Credit Account B
This makes the system much easier to audit, reconcile, and reason about.
Handles outgoing money movement.
Payout Request
↓
Validation
↓
Payout Processing
↓
Kafka Event
↓
Ledger
↓
Balance Projection
Neo4j can be used to model relationships between:
User
↓
Account
↓
Transaction
↓
Merchant
↓
Payment
This enables relationship-based analysis and provides a foundation for future capabilities such as:
- Transaction relationship exploration
- Fraud-pattern analysis
- Suspicious transaction detection
- Graph-based risk analysis
Kafka is used to decouple services and support asynchronous workflows.
Example:
Payment Intent Service
│
│ PaymentCreated
▼
Apache Kafka
│
┌─────┼───────────┐
▼ ▼ ▼
Ledger Balance Notification
Service Projector Service
PaymentCreated
PaymentProcessing
PaymentSucceeded
PaymentFailed
OrderCreated
PayoutRequested
PayoutCompleted
LedgerEntryCreated
Keeping event contracts separately also helps maintain stable communication boundaries between services.
A simplified payment lifecycle:
Client
│
▼
API Gateway
│
▼
Payment Intent Service
│
├──────────────► MySQL
│
▼
Kafka
│
├──────────────► Ledger Service
│
├──────────────► Balance Projector
│
└──────────────► Notification / Other Consumers
│
▼
Final State
Because payment processing often involves multiple independent side effects.
Instead of tightly coupling:
Payment → Ledger → Balance → Notification
the system can publish an event:
PaymentSucceeded
and allow multiple consumers to react independently.
This improves:
- Scalability
- Loose coupling
- Failure isolation
- Extensibility
- Event replay possibilities
The system intentionally uses different databases for different workloads.
Used for transactional domain data:
Users
Accounts
Merchants
Orders
Payments
Payouts
Ledger records
Used for low-latency access and projections:
Balance Read Models
Cache
Temporary State
Rate Limiting
Used for relationship-oriented transaction data:
User ──► Account
Account ──► Transaction
Transaction ──► Merchant
Transaction ──► Payment
This follows a polyglot persistence approach where the storage technology is selected according to the access pattern.
Production systems need to answer three questions:
What is happening?
↓
Prometheus
Why is it happening?
↓
Zipkin
Can I visualize it?
↓
Grafana
Collects application and infrastructure metrics.
Provides dashboards for:
- Request rates
- Error rates
- Latency
- JVM metrics
- Service health
- Kafka-related metrics
Provides distributed tracing across service boundaries.
Example:
Gateway
↓
Payment Service
↓
Kafka
↓
Ledger Service
↓
Balance Projection
Tracing makes it possible to follow a request/workflow across distributed components.
Make sure you have:
- Java 17+
- Maven 3.8+
- Docker
- Docker Compose
- Git
Optional:
- Kubernetes
- Minikube
- kubectl
git clone https://github.com/yashdotdev13/paypal-backend-clone.git
cd paypal-backend-clonedocker compose up -dCheck running containers:
docker psmvn clean installRun a specific service:
cd payment-intent-service
mvn spring-boot:runService-specific configuration and startup instructions can be added as the project evolves.
The repository also contains Kubernetes deployment resources.
k8s/
├── namespaces/
├── deployments/
├── services/
├── configmaps/
└── secrets/
Typical deployment:
kubectl apply -f k8s/Verify:
kubectl get pods
kubectl get servicesThe project is intended to evolve toward multiple levels of testing:
Unit Tests
↓
Integration Tests
↓
Service Tests
↓
Event / Kafka Tests
↓
End-to-End Tests
Important areas include:
- Payment state transitions
- Ledger consistency
- Idempotency
- Event processing
- Failure recovery
- Account/balance consistency
- Authentication and authorization
This project focuses heavily on real-world backend engineering concepts.
Payment APIs should be designed so that retrying the same request does not accidentally create duplicate financial operations.
Request
↓
Idempotency Key
↓
Check Existing Operation
↓
Process Only Once
Not every read model needs to update synchronously.
Authoritative Ledger
↓
Kafka
↓
Balance Projection
The projection may become consistent shortly after the source transaction is committed.
If one consumer temporarily fails:
Payment Service
↓
Kafka
↓
Ledger Consumer ❌
↓
Retry / Recovery
the payment workflow does not necessarily have to synchronously wait for every downstream component.
paypal-backend-clone/
│
├── account-service/
├── api-gateway/
├── auth-service/
├── balance-project-service/
├── discovery-server/
├── event-contracts/
├── init-db/
├── k8s/
├── kafka-kraft/
├── ledger-service/
├── merchant-service/
├── monitoring/
├── order-service/
├── payment-intent-service/
├── payout-service/
├── user-service/
│
├── docker-compose.yml
├── pom.xml
└── README.md
This project is considered complete and represents the finished implementation of the distributed payment backend.
- Microservice foundation
- API Gateway
- Service Discovery
- Authentication & authorization
- Account / wallet management
- User management
- Merchant management
- Payment intent lifecycle
- Order management
- Balance projection
- Ledger service
- Payout processing
- Kafka event-driven communication
- Event contracts
- Idempotency
- Retry / failure-handling patterns
- Distributed transaction / workflow patterns
- MySQL persistence
- Redis caching / read projections
- Neo4j transaction graph
- Docker & Docker Compose
- Kubernetes deployment resources
- Prometheus metrics
- Grafana dashboards
- Zipkin distributed tracing
- Production-oriented security practices
- Integration / event-driven testing
- Observability-first architecture
- Fault-tolerant service design
Status: 🟢 Complete — The repository represents the finished project rather than an ongoing roadmap.
This project follows several important backend engineering principles:
Domain Separation
+
Event-Driven Communication
+
Database Per Service
+
Idempotency
+
Observability
+
Fault Tolerance
+
Horizontal Scalability
+
Clean Architecture
The objective is to understand why these patterns exist, not simply to use technologies because they are popular.
If you're reviewing this repository as a backend / distributed-systems project, the major engineering areas are:
- Spring Boot
- REST APIs
- Authentication
- Database design
- Transaction management
- Microservices
- Event-driven architecture
- Kafka
- Eventual consistency
- Idempotency
- Failure handling
- MySQL
- Redis
- Neo4j
- Polyglot persistence
- Read projections
- Docker
- Docker Compose
- Kubernetes
- CI/CD
- Infrastructure automation
- Prometheus
- Grafana
- Zipkin
- Metrics
- Distributed tracing
Contributions, ideas, improvements, and architecture discussions are welcome.
git checkout -b feature/your-feature
git commit -m "feat: add your feature"
git push origin feature/your-featureThen open a Pull Request.
This project is an independent educational implementation inspired by payment-platform architecture.
It is not affiliated with, sponsored by, or endorsed by PayPal.
Do not use this project to process real money or sensitive financial information without appropriate security, compliance, auditing, and regulatory controls.
Building distributed systems, cloud-native applications, and production-oriented backend platforms.