Spring Boot wallet engine built around safe account creation and money-transfer
rules. PostgreSQL is the source of truth; all monetary values use long minor
units (for example, 2500 represents 25.00 THB).
POST /api/accountscreates an active THB/USD/etc. account.POST /api/transfersperforms an atomic, idempotent transfer.GET /api/transfers/{transferId}returns a persisted transfer result.- Transfers use PostgreSQL row-level locks and create debit/credit ledger entries in the same transaction.
- Kafka, Debezium, and Redis read models are deferred until the core transfer flow is complete.
- Java 21
- Docker
Start PostgreSQL and Redis:
docker compose up -dStart the application:
./mvnw spring-boot:runCheck health:
curl http://localhost:8080/actuator/healthCreate an account:
curl -X POST http://localhost:8080/api/accounts \
-H 'Content-Type: application/json' \
-d '{"ownerId":"user-001","currency":"THB","initialBalance":100000}'Create two accounts, then transfer money between their response id values:
curl -X POST http://localhost:8080/api/transfers \
-H 'Content-Type: application/json' \
-d '{
"idempotencyKey":"transfer-001",
"fromAccountId":"<source-account-uuid>",
"toAccountId":"<destination-account-uuid>",
"amount":2500,
"currency":"THB"
}'A completed transfer returns 201 Created. Insufficient balance returns 422
and records a failed transfer without changing either balance. Reusing the same
idempotencyKey with the same request returns the saved result.
Fetch a transfer:
curl http://localhost:8080/api/transfers/<transfer-uuid>Run the complete suite (Docker is required for Testcontainers):
./mvnw testRun only fast transfer business-rule tests:
./mvnw test -Dtest=TransferUseCaseTestHTTP request → Controller → Use Case → Persistence Adapter → PostgreSQL
The transfer use case locks both accounts in deterministic UUID order before changing balances, then persists the transfer and its debit/credit ledger entries in one database transaction.
- Apache Maven
- Spring Boot Maven Plugin
- Create an OCI image
- Spring Boot Testcontainers support
- Testcontainers Kafka
- Testcontainers PostgreSQL
- Spring Web
- Validation
- Spring Data JPA
- Flyway Migration
- Spring Boot Actuator
- Spring Data Reactive Redis
- Spring for Apache Kafka
- Building a RESTful Web Service
- Serving Web Content with Spring MVC
- Building REST services with Spring
- Validating form input
- Accessing data with JPA
- Building a RESTful Web Service with Actuator
- Messaging with Redis
Core integration tests use postgres:17. The optional Testcontainers setup also
defines Kafka and Redis containers; pin their image tags before using them in
production-like tests.