Skip to content

abdkadirozer/digitalwallet

Repository files navigation

Digital Wallet API

A comprehensive backend API for digital payment operations built with Spring Boot. This application provides wallet management, transaction processing (deposits/withdrawals), and transaction approval workflows for digital payment companies.

Features

  • Wallet Management: Create wallets with different currencies (TRY, USD, EUR)
  • Dual Balance System: Separate balance and usable balance tracking
  • Transaction Processing: Automated deposit and withdrawal handling
  • Smart Status Management: Automatic PENDING status for transactions >1000
  • Transaction Approval Workflow: Employee approval system for pending transactions
  • Turkish ID (TCKN) Validation: Full TCKN validation with checksum algorithm
  • Comprehensive Error Handling: Global exception handling with detailed error responses
  • Sample Data: Pre-loaded sample customers and wallets for testing

Technology Stack

  • Java 21 with Spring Boot 3.5.6
  • Spring Data JPA with Hibernate
  • H2 Database (in-memory for development)
  • Redis for caching and session management
  • Spring Security with JWT authentication
  • Spring Boot Actuator for monitoring and health checks
  • Spring Boot Validation for request validation
  • OpenAPI/Swagger for API documentation
  • Docker & Docker Compose for containerization
  • Lombok for boilerplate code reduction
  • Gradle for build management

Prerequisites

For Local Development (Method 2)

  • Java 21 or higher
  • No additional setup required (H2 database is embedded)

For Docker Deployment (Method 1)

  • Docker version 20.0 or higher
  • Docker Compose version 2.0 or higher
  • No Java installation required (runs in containers)

Getting Started

There are two ways to run the Digital Wallet application:

Method 1: Docker Compose (Recommended for Production)

This method includes Redis caching and runs in containers for better isolation and production-like environment.

# Clone the repository
git clone <repository-url>
cd digitalwallet

# Start all services (app + Redis)
docker-compose up --build

# Or run in background
docker-compose up -d

# View logs
docker-compose logs -f

# Stop services
docker-compose down

Access Points:

Method 2: Local Development

This method runs the application locally for development purposes.

# Clone the repository
git clone <repository-url>
cd digitalwallet

# Build the project
./gradlew clean build

# Run the application
./gradlew bootRun

The application will start on http://localhost:8080

For Redis caching (optional):

# Start Redis with Docker (recommended)
docker run -d -p 6379:6379 redis:7.2-alpine

# Then run the application with Redis enabled
./gradlew bootRun

Access H2 Database Console

While the application is running, visit: http://localhost:8080/h2-console

Database Configuration:

  • JDBC URL: jdbc:h2:mem:testdb
  • Username: sa
  • Password: (leave empty)

API Documentation

Base URL

http://localhost:8080/api

Wallet Endpoints

Create Wallet

POST /api/wallets
Content-Type: application/json

{
  "customerId": 1,
  "walletName": "My TRY Wallet",
  "currency": "TRY",
  "activeForShopping": true,
  "activeForWithdraw": true
}

Get Customer Wallets

GET /api/wallets/customer/{customerId}
GET /api/wallets/customer/{customerId}?currency=TRY
GET /api/wallets/customer/{customerId}?minBalance=100

Get Specific Wallet

GET /api/wallets/{walletId}/customer/{customerId}

Update Wallet Settings

PUT /api/wallets/{walletId}/customer/{customerId}/settings?activeForShopping=false&activeForWithdraw=true

Transaction Endpoints

Make Deposit

POST /api/transactions/deposit
Content-Type: application/json

{
  "walletId": 1,
  "amount": 500.00,
  "source": "TR320010009999901234567890",
  "sourceType": "IBAN"
}

Make Withdrawal

POST /api/transactions/withdraw
Content-Type: application/json
X-Customer-Id: 1

{
  "walletId": 1,
  "amount": 200.00,
  "destination": "TR320010009999901234567890",
  "destinationType": "IBAN"
}

List Wallet Transactions

GET /api/transactions/wallet/{walletId}/customer/{customerId}
GET /api/transactions/wallet/{walletId}/customer/{customerId}?page=0&size=10

Get Pending Transactions

GET /api/transactions/pending

Approve/Deny Transaction

PUT /api/transactions/{transactionId}/approve
Content-Type: application/json

{
  "status": "APPROVED"
}

Get Transaction Details

GET /api/transactions/{transactionId}

Docker Deployment Guide

Docker Architecture

The Docker setup includes:

  1. Application Container: Spring Boot app running on Java 21
  2. Redis Container: For caching and session management
  3. Persistent Volume: Redis data persistence
  4. Health Checks: Automated health monitoring
  5. Network: Custom bridge network for service communication

Docker Commands Reference

# Build and start all services
docker-compose up --build

# Start services in background
docker-compose up -d

# View all logs
docker-compose logs -f

# View specific service logs
docker-compose logs -f app
docker-compose logs -f redis

# Stop all services
docker-compose down

# Stop and remove volumes
docker-compose down -v

# Rebuild specific service
docker-compose build app
docker-compose up -d app

# Scale services (if needed)
docker-compose up --scale app=2

# Check service status
docker-compose ps

# Execute commands in container
docker-compose exec app sh
docker-compose exec redis redis-cli

Docker Environment Configuration

The Docker setup automatically configures:

  • Redis Integration: SPRING_DATA_REDIS_HOST=redis
  • Cache Type: SPRING_CACHE_TYPE=redis
  • Database: H2 in-memory (configurable for production)
  • Health Checks: Both app and Redis monitored
  • Rate Limiting: Enabled with Redis backend
  • Logging: Centralized container logging

Production Docker Setup

For production deployment, create docker-compose.prod.yml:

services:
  app:
    build: .
    environment:
      SPRING_PROFILES_ACTIVE: prod
      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/digitalwallet
      SPRING_DATA_REDIS_HOST: redis
      LOGGING_LEVEL_ROOT: WARN
    depends_on:
      - db
      - redis

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: digitalwallet
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:7.2-alpine
    command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

Monitoring with Docker

# Check container health
docker-compose ps
docker-compose exec app curl http://localhost:8080/actuator/health

# Monitor resource usage
docker-compose top
docker stats

# View Redis statistics
docker-compose exec redis redis-cli info

# Check application metrics
curl http://localhost:8080/actuator/metrics/jvm.memory.used
curl http://localhost:8080/actuator/metrics/http.server.requests

Troubleshooting Docker Issues

# Clean up Docker resources
docker-compose down -v
docker system prune -a

# Rebuild without cache
docker-compose build --no-cache

# Check container logs for errors
docker-compose logs app | grep ERROR

# Verify network connectivity
docker-compose exec app ping redis

# Test Redis connection
docker-compose exec redis redis-cli ping

Business Rules

Transaction Status Logic

  • Amounts ≤ 1000: Automatically APPROVED
  • Amounts > 1000: Set to PENDING (requires manual approval)

Balance Management

  • Balance: Total wallet funds (includes pending deposits)
  • Usable Balance: Available funds for transactions

Deposit Balance Updates

  • Approved Deposits: Update both balance and usableBalance
  • Pending Deposits: Update only balance

Withdrawal Balance Updates

  • Approved Withdrawals: Update both balance and usableBalance
  • Pending Withdrawals: Update only usableBalance

Wallet Permissions

  • activeForShopping: Controls shopping transaction permissions
  • activeForWithdraw: Required for withdrawal operations (checked before processing)

TCKN Validation

  • Turkish ID numbers are validated using the official checksum algorithm
  • Sample valid TCKNs: 12345678901, 98765432109, 11111111110

Sample Data

The application initializes with sample data:

Customers:

  • Ahmet Yılmaz (TCKN: 12345678901) - 2 wallets
  • Ayşe Demir (TCKN: 98765432109) - 1 wallet
  • Mehmet Kaya (TCKN: 11111111110) - 1 wallet

Wallets:

  • Various currencies (TRY, USD, EUR)
  • Different permission settings for testing scenarios

Testing Examples

1. Create a Small Deposit (Auto-Approved)

curl -X POST http://localhost:8080/api/transactions/deposit \
  -H "Content-Type: application/json" \
  -d '{
    "walletId": 1,
    "amount": 500.00,
    "source": "TR320010009999901234567890",
    "sourceType": "IBAN"
  }'

2. Create a Large Deposit (Pending)

curl -X POST http://localhost:8080/api/transactions/deposit \
  -H "Content-Type: application/json" \
  -d '{
    "walletId": 1,
    "amount": 1500.00,
    "source": "TR320010009999901234567890",
    "sourceType": "IBAN"
  }'

3. Approve Pending Transaction

curl -X PUT http://localhost:8080/api/transactions/{transactionId}/approve \
  -H "Content-Type: application/json" \
  -d '{
    "status": "APPROVED"
  }'

Development Notes

Project Structure

src/main/java/org/example/digitalwallet/
├── entity/          # JPA entities
├── repository/      # Data access layer
├── service/         # Business logic layer
├── controller/      # REST API endpoints
├── dto/            # Request/Response objects
├── config/         # Configuration classes
└── enums/          # Enums for currencies, statuses, etc.

Key Configuration Files

  • application.properties: Database and logging configuration
  • CLAUDE.md: Development guidance for Claude Code
  • todolist.md: Implementation task breakdown

Database Schema

The application uses Hibernate to automatically create the following tables:

  • customers: Customer information with TCKN
  • wallets: Wallet details with dual balance tracking
  • transactions: Transaction history with status and type

Build Commands

# Clean build
./gradlew clean build

# Run tests
./gradlew test

# Run application
./gradlew bootRun

# Build JAR
./gradlew bootJar

Production Considerations

Security:

  • Current configuration permits all API access (development mode)
  • Implement role-based authentication for production
  • Add JWT or OAuth2 authentication
  • Enable customer/employee role separation
  • Use Docker secrets for sensitive configuration
  • Enable HTTPS with SSL certificates
  • Implement API rate limiting per user/IP

Database:

  • Replace H2 with PostgreSQL or MySQL for production
  • Configure connection pooling with HikariCP
  • Add database migrations with Flyway/Liquibase
  • Implement database backup strategy
  • Use persistent volumes for data in Docker

Monitoring & Observability:

  • Spring Boot Actuator endpoints available at /actuator
  • Add application metrics and health checks
  • Configure logging levels for production
  • Implement centralized logging (ELK stack or similar)
  • Add APM tools (New Relic, DataDog, etc.)
  • Monitor Docker container resources

Performance & Scalability:

  • Redis caching enabled in Docker setup
  • Implement database indexing strategy
  • Add pagination for large result sets
  • Use Docker container orchestration (Kubernetes)
  • Implement horizontal scaling with load balancers
  • Add connection pooling for Redis

Infrastructure & Deployment:

  • Use Docker multi-stage builds for smaller images
  • Implement CI/CD pipelines with Docker
  • Use container registries (Docker Hub, ECR, etc.)
  • Deploy with Kubernetes or Docker Swarm
  • Implement blue-green deployments
  • Add environment-specific configuration

Error Handling

The API returns consistent error responses:

{
  "error": "Bad Request",
  "message": "Validation Failed",
  "status": 400,
  "path": "/api/wallets",
  "timestamp": "2025-01-15T10:30:00",
  "validationErrors": [
    "walletName: Wallet name is required",
    "currency: Currency is required"
  ]
}

Quick Reference

Two Ways to Run the Application:

🐳 Docker (Recommended)

git clone <repository-url> && cd digitalwallet
docker-compose up --build
# Access: http://localhost:8080

☕ Local Development

git clone <repository-url> && cd digitalwallet
./gradlew clean build
./gradlew bootRun
# Access: http://localhost:8080

Key URLs:

Docker Files:

  • Dockerfile - Application container definition
  • docker-compose.yml - Multi-service orchestration
  • .dockerignore - Build context optimization
  • docker-setup.md - Detailed Docker documentation

Support

For development questions, refer to:

  • README.md: This comprehensive guide
  • docker-setup.md: Detailed Docker deployment guide
  • CLAUDE.md: Development commands and architecture notes
  • Application logs: Available in console output with detailed error information

License

This is a case study implementation for digital wallet backend services designed for production-ready deployment.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published