Skip to content

taralshah09/wallet-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🏦 Digital Wallet & Fixed Deposit Management API

Java Spring Boot MySQL License

A production-grade RESTful API for digital wallet and fixed deposit management with enterprise-level security, concurrency handling, and transactional integrity.

🌟 Key Features

βœ… Authentication & Authorization

  • JWT-based Authentication with secure token generation
  • Password Encryption using BCrypt
  • Role-based Access Control (USER/ADMIN)
  • Session management with token expiration

πŸ’° Wallet Management

  • Deposit Money - Add funds to your wallet
  • Withdraw Money - Withdraw with balance validation
  • Money Transfer - P2P transfers with double-spending prevention
  • Transaction History - Complete audit trail with pagination
  • Optimistic Locking - Prevents race conditions

πŸͺ™ Fixed Deposit Module

  • Create FD - Lock funds for fixed tenure with interest
  • Auto Interest Calculation - Simple interest formula
  • Break FD - Premature withdrawal with penalty (2%)
  • Maturity Tracking - Track FD status and maturity dates
  • Pro-rata Interest - Calculate interest for partial tenure

πŸ›‘οΈ Enterprise Features

  • ACID Transactions - @Transactional for data consistency
  • Pessimistic Locking - Prevents concurrent modifications
  • Global Exception Handling - Consistent error responses
  • Input Validation - Jakarta Validation annotations
  • DTO Pattern - Clean separation of concerns
  • Layered Architecture - Controller β†’ Service β†’ Repository

πŸ“Š Database Schema

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    users    β”‚1────1 β”‚   wallets    β”‚1────M β”‚  transactions   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€       β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€       β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ id (PK)     β”‚       β”‚ id (PK)      β”‚       β”‚ id (PK)         β”‚
β”‚ email       β”‚       β”‚ user_id (FK) β”‚       β”‚ wallet_id (FK)  β”‚
β”‚ password    β”‚       β”‚ balance      β”‚       β”‚ type            β”‚
β”‚ full_name   β”‚       β”‚ version      β”‚       β”‚ amount          β”‚
β”‚ phone       β”‚       β”‚ created_at   β”‚       β”‚ balance_before  β”‚
β”‚ role        β”‚       β”‚ updated_at   β”‚       β”‚ balance_after   β”‚
β”‚ is_active   β”‚       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚ description     β”‚
β”‚ created_at  β”‚                               β”‚ reference_id    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                               β”‚ related_user_id β”‚
      β”‚                                       β”‚ created_at      β”‚
      β”‚                                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚
      β”‚1
      β”‚
      β”‚M
      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ fixed_deposits   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ id (PK)          β”‚
β”‚ user_id (FK)     β”‚
β”‚ principal_amount β”‚
β”‚ interest_rate    β”‚
β”‚ tenure_months    β”‚
β”‚ maturity_amount  β”‚
β”‚ maturity_date    β”‚
β”‚ status           β”‚
β”‚ penalty_amount   β”‚
β”‚ amount_received  β”‚
β”‚ closed_at        β”‚
β”‚ created_at       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Relationships:

  • User 1:1 Wallet (One user has exactly one wallet)
  • Wallet 1:M Transactions (One wallet has many transactions)
  • User 1:M FixedDeposits (One user can have multiple FDs)

πŸš€ Quick Start

Prerequisites

  • Java 17 or higher
  • Maven 3.6+
  • MySQL 8.0+

1. Clone Repository

git clone <repository-url>
cd wallet-api

2. Configure Database

Edit src/main/resources/application.properties:

spring.datasource.url=jdbc:mysql://localhost:3306/wallet_db?createDatabaseIfNotExist=true
spring.datasource.username=your_username
spring.datasource.password=your_password

3. Build & Run

# Build the project
mvn clean install

# Run the application
mvn spring-boot:run

Application runs on: http://localhost:8080


πŸ“š API Endpoints

πŸ” Authentication

1. Signup

POST /api/auth/signup
Content-Type: application/json

{
  "email": "john@example.com",
  "password": "password123",
  "fullName": "John Doe",
  "phoneNumber": "9876543210"
}

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "type": "Bearer",
  "userId": 1,
  "email": "john@example.com",
  "fullName": "John Doe",
  "role": "USER"
}

2. Login

POST /api/auth/login
Content-Type: application/json

{
  "email": "john@example.com",
  "password": "password123"
}

πŸ’³ Wallet Operations

All wallet endpoints require JWT token:

Authorization: Bearer <your-jwt-token>

1. Get Wallet Balance

GET /api/wallet/{userId}

Response:

{
  "walletId": 1,
  "userId": 1,
  "userEmail": "john@example.com",
  "balance": 5000.00,
  "updatedAt": "2024-02-12T10:30:00"
}

2. Deposit Money

POST /api/wallet/{userId}/deposit
Content-Type: application/json

{
  "amount": 1000.00,
  "description": "Salary credit"
}

3. Withdraw Money

POST /api/wallet/{userId}/withdraw
Content-Type: application/json

{
  "amount": 500.00,
  "description": "ATM withdrawal"
}

4. Transfer Money

POST /api/wallet/{userId}/transfer
Content-Type: application/json

{
  "recipientEmail": "jane@example.com",
  "amount": 200.00,
  "description": "Payment for dinner"
}

Response:

{
  "id": 10,
  "type": "TRANSFER_SENT",
  "amount": 200.00,
  "balanceBefore": 5000.00,
  "balanceAfter": 4800.00,
  "description": "Transfer to jane@example.com",
  "referenceId": "TXN-A1B2C3D4",
  "relatedUserEmail": "jane@example.com",
  "createdAt": "2024-02-12T11:00:00"
}

5. Transaction History

GET /api/wallet/{userId}/transactions?page=0&size=10

Response:

{
  "content": [
    {
      "id": 10,
      "type": "TRANSFER_SENT",
      "amount": 200.00,
      "balanceBefore": 5000.00,
      "balanceAfter": 4800.00,
      "description": "Transfer to jane@example.com",
      "referenceId": "TXN-A1B2C3D4",
      "createdAt": "2024-02-12T11:00:00"
    }
  ],
  "totalElements": 25,
  "totalPages": 3,
  "size": 10,
  "number": 0
}

πŸͺ™ Fixed Deposit Operations

1. Create Fixed Deposit

POST /api/fixed-deposits/{userId}
Content-Type: application/json

{
  "amount": 10000.00,
  "tenureInMonths": 12,
  "interestRate": 7.5
}

Response:

{
  "fdId": 1,
  "userId": 1,
  "userEmail": "john@example.com",
  "principalAmount": 10000.00,
  "interestRate": 7.5,
  "tenureInMonths": 12,
  "maturityAmount": 10750.00,
  "maturityDate": "2025-02-12T10:30:00",
  "status": "ACTIVE",
  "createdAt": "2024-02-12T10:30:00"
}

Interest Calculation:

  • Formula: Interest = (Principal Γ— Rate Γ— Tenure) / 1200
  • Example: (10000 Γ— 7.5 Γ— 12) / 1200 = β‚Ή750
  • Maturity Amount = Principal + Interest = β‚Ή10,750

2. Break Fixed Deposit (Premature Withdrawal)

POST /api/fixed-deposits/{userId}/{fdId}/break

Response:

{
  "fdId": 1,
  "principalAmount": 10000.00,
  "interestEarned": 375.00,
  "penaltyAmount": 200.00,
  "amountReturned": 10175.00,
  "message": "FD broken successfully. Amount credited to wallet after penalty deduction."
}

Penalty Logic:

  • Penalty Rate: 2% of principal amount
  • Pro-rata Interest: Calculated based on months elapsed
  • Amount Returned = Principal + Interest Earned - Penalty

3. Get All Fixed Deposits

GET /api/fixed-deposits/{userId}

4. Get Specific FD Details

GET /api/fixed-deposits/{userId}/{fdId}

πŸ”’ Security Features

1. JWT Authentication

  • Token-based stateless authentication
  • Token expiration: 24 hours (configurable)
  • Secure password storage with BCrypt

2. Concurrency Control

Pessimistic Locking:

@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT w FROM Wallet w WHERE w.user.id = :userId")
Optional<Wallet> findByUserIdWithLock(Long userId);

Optimistic Locking:

@Version
private Long version; // In Wallet entity

3. Transaction Management

@Transactional // Ensures ACID properties
public TransactionDto transfer(Long senderId, WalletDto.TransferRequest request) {
    // All operations succeed or rollback together
}

🎯 Technical Highlights for Resume

1. Concurrency Handling

βœ… Implemented pessimistic locking to prevent race conditions
βœ… Optimistic locking with @Version for wallet balance
βœ… Deadlock prevention with ordered locking

2. Transaction Safety

βœ… ACID compliance with Spring @Transactional
βœ… Atomic money transfers - both debit and credit happen together
βœ… Rollback on failures

3. Clean Architecture

Controller (API Layer)
    ↓
Service (Business Logic)
    ↓
Repository (Data Access)
    ↓
Database (MySQL)

4. Best Practices

βœ… DTO pattern for clean separation
βœ… Global exception handling
βœ… Input validation with Jakarta Validation
βœ… Proper HTTP status codes
βœ… Pagination for large datasets


πŸ§ͺ Testing the API

Using cURL

1. Signup:

curl -X POST http://localhost:8080/api/auth/signup \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "password": "test123",
    "fullName": "Test User",
    "phoneNumber": "9876543210"
  }'

2. Login & Get Token:

curl -X POST http://localhost:8080/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "password": "test123"
  }'

3. Deposit Money:

curl -X POST http://localhost:8080/api/wallet/1/deposit \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5000.00,
    "description": "Initial deposit"
  }'

4. Create FD:

curl -X POST http://localhost:8080/api/fixed-deposits/1 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 2000.00,
    "tenureInMonths": 6,
    "interestRate": 6.5
  }'

πŸ“ˆ Performance Considerations

  1. Database Indexing:

    • Index on email in users table
    • Index on user_id in wallets and fixed_deposits
    • Composite index on wallet_id and created_at in transactions
  2. Query Optimization:

    • Used pagination for transaction history
    • Lazy loading for relationships
    • Selective fetch strategies
  3. Connection Pooling:

    • HikariCP for efficient database connections

πŸ› Error Handling

The API provides consistent error responses:

{
  "timestamp": "2024-02-12T10:30:00",
  "status": 400,
  "error": "Insufficient Balance",
  "message": "Insufficient balance. Available: 1000.00",
  "path": "/api/wallet/1/withdraw"
}

Common Error Codes:

  • 400 - Bad Request (validation errors, insufficient balance)
  • 401 - Unauthorized (invalid/missing token)
  • 404 - Not Found (resource doesn't exist)
  • 409 - Conflict (duplicate email/phone)
  • 500 - Internal Server Error

πŸ”§ Configuration

application.properties

# Server Configuration
server.port=8080

# Database
spring.datasource.url=jdbc:mysql://localhost:3306/wallet_db
spring.datasource.username=root
spring.datasource.password=root

# JPA
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

# JWT
jwt.secret=your-secret-key-here
jwt.expiration=86400000

πŸ“ Project Structure

wallet-api/
β”œβ”€β”€ src/main/java/com/fintech/wallet/
β”‚   β”œβ”€β”€ controller/          # REST Controllers
β”‚   β”‚   β”œβ”€β”€ AuthController.java
β”‚   β”‚   β”œβ”€β”€ WalletController.java
β”‚   β”‚   └── FixedDepositController.java
β”‚   β”œβ”€β”€ service/             # Business Logic
β”‚   β”‚   β”œβ”€β”€ AuthService.java
β”‚   β”‚   β”œβ”€β”€ WalletService.java
β”‚   β”‚   └── FixedDepositService.java
β”‚   β”œβ”€β”€ repository/          # Data Access
β”‚   β”‚   β”œβ”€β”€ UserRepository.java
β”‚   β”‚   β”œβ”€β”€ WalletRepository.java
β”‚   β”‚   β”œβ”€β”€ TransactionRepository.java
β”‚   β”‚   └── FixedDepositRepository.java
β”‚   β”œβ”€β”€ entity/              # JPA Entities
β”‚   β”‚   β”œβ”€β”€ User.java
β”‚   β”‚   β”œβ”€β”€ Wallet.java
β”‚   β”‚   β”œβ”€β”€ Transaction.java
β”‚   β”‚   └── FixedDeposit.java
β”‚   β”œβ”€β”€ dto/                 # Data Transfer Objects
β”‚   β”‚   β”œβ”€β”€ AuthDto.java
β”‚   β”‚   β”œβ”€β”€ WalletDto.java
β”‚   β”‚   β”œβ”€β”€ FixedDepositDto.java
β”‚   β”‚   └── TransactionDto.java
β”‚   β”œβ”€β”€ security/            # Security Configuration
β”‚   β”‚   β”œβ”€β”€ SecurityConfig.java
β”‚   β”‚   β”œβ”€β”€ JwtUtil.java
β”‚   β”‚   β”œβ”€β”€ JwtAuthenticationFilter.java
β”‚   β”‚   └── CustomUserDetailsService.java
β”‚   β”œβ”€β”€ exception/           # Exception Handling
β”‚   β”‚   β”œβ”€β”€ GlobalExceptionHandler.java
β”‚   β”‚   β”œβ”€β”€ ResourceNotFoundException.java
β”‚   β”‚   β”œβ”€β”€ InsufficientBalanceException.java
β”‚   β”‚   β”œβ”€β”€ DuplicateResourceException.java
β”‚   β”‚   └── InvalidOperationException.java
β”‚   └── WalletApplication.java
└── src/main/resources/
    └── application.properties

πŸ“§ Support

For questions or issues:

  • Create an issue in the repository
  • Contact: hitmeup.taral@example.com

πŸ“„ License

This project is licensed under the MIT License.


Built with ❀️ by Taral Shah

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages