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.
- 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
- 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
- Java 21 or higher
- No additional setup required (H2 database is embedded)
- Docker version 20.0 or higher
- Docker Compose version 2.0 or higher
- No Java installation required (runs in containers)
There are two ways to run the Digital Wallet application:
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 downAccess Points:
- Application: http://localhost:8080
- H2 Console: http://localhost:8080/h2-console
- Redis: localhost:6379
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 bootRunThe 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 bootRunWhile the application is running, visit: http://localhost:8080/h2-console
Database Configuration:
- JDBC URL:
jdbc:h2:mem:testdb - Username:
sa - Password: (leave empty)
http://localhost:8080/api
POST /api/wallets
Content-Type: application/json
{
"customerId": 1,
"walletName": "My TRY Wallet",
"currency": "TRY",
"activeForShopping": true,
"activeForWithdraw": true
}GET /api/wallets/customer/{customerId}
GET /api/wallets/customer/{customerId}?currency=TRY
GET /api/wallets/customer/{customerId}?minBalance=100GET /api/wallets/{walletId}/customer/{customerId}PUT /api/wallets/{walletId}/customer/{customerId}/settings?activeForShopping=false&activeForWithdraw=truePOST /api/transactions/deposit
Content-Type: application/json
{
"walletId": 1,
"amount": 500.00,
"source": "TR320010009999901234567890",
"sourceType": "IBAN"
}POST /api/transactions/withdraw
Content-Type: application/json
X-Customer-Id: 1
{
"walletId": 1,
"amount": 200.00,
"destination": "TR320010009999901234567890",
"destinationType": "IBAN"
}GET /api/transactions/wallet/{walletId}/customer/{customerId}
GET /api/transactions/wallet/{walletId}/customer/{customerId}?page=0&size=10GET /api/transactions/pendingPUT /api/transactions/{transactionId}/approve
Content-Type: application/json
{
"status": "APPROVED"
}GET /api/transactions/{transactionId}The Docker setup includes:
- Application Container: Spring Boot app running on Java 21
- Redis Container: For caching and session management
- Persistent Volume: Redis data persistence
- Health Checks: Automated health monitoring
- Network: Custom bridge network for service communication
# 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-cliThe 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
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:# 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# 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- Amounts ≤ 1000: Automatically
APPROVED - Amounts > 1000: Set to
PENDING(requires manual approval)
- Balance: Total wallet funds (includes pending deposits)
- Usable Balance: Available funds for transactions
- Approved Deposits: Update both
balanceandusableBalance - Pending Deposits: Update only
balance
- Approved Withdrawals: Update both
balanceandusableBalance - Pending Withdrawals: Update only
usableBalance
- activeForShopping: Controls shopping transaction permissions
- activeForWithdraw: Required for withdrawal operations (checked before processing)
- Turkish ID numbers are validated using the official checksum algorithm
- Sample valid TCKNs:
12345678901,98765432109,11111111110
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
curl -X POST http://localhost:8080/api/transactions/deposit \
-H "Content-Type: application/json" \
-d '{
"walletId": 1,
"amount": 500.00,
"source": "TR320010009999901234567890",
"sourceType": "IBAN"
}'curl -X POST http://localhost:8080/api/transactions/deposit \
-H "Content-Type: application/json" \
-d '{
"walletId": 1,
"amount": 1500.00,
"source": "TR320010009999901234567890",
"sourceType": "IBAN"
}'curl -X PUT http://localhost:8080/api/transactions/{transactionId}/approve \
-H "Content-Type: application/json" \
-d '{
"status": "APPROVED"
}'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.
application.properties: Database and logging configurationCLAUDE.md: Development guidance for Claude Codetodolist.md: Implementation task breakdown
The application uses Hibernate to automatically create the following tables:
customers: Customer information with TCKNwallets: Wallet details with dual balance trackingtransactions: Transaction history with status and type
# Clean build
./gradlew clean build
# Run tests
./gradlew test
# Run application
./gradlew bootRun
# Build JAR
./gradlew bootJarSecurity:
- 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
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"
]
}git clone <repository-url> && cd digitalwallet
docker-compose up --build
# Access: http://localhost:8080git clone <repository-url> && cd digitalwallet
./gradlew clean build
./gradlew bootRun
# Access: http://localhost:8080- API: http://localhost:8080/api
- Swagger: http://localhost:8080/swagger-ui
- H2 Console: http://localhost:8080/h2-console
- Health Check: http://localhost:8080/actuator/health
Dockerfile- Application container definitiondocker-compose.yml- Multi-service orchestration.dockerignore- Build context optimizationdocker-setup.md- Detailed Docker documentation
For development questions, refer to:
README.md: This comprehensive guidedocker-setup.md: Detailed Docker deployment guideCLAUDE.md: Development commands and architecture notes- Application logs: Available in console output with detailed error information
This is a case study implementation for digital wallet backend services designed for production-ready deployment.