Skip to content

About

A RESTful API for managing financial accounts, transactions, and ledger records with secure authentication and reliable transaction processing.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

FinancialLedgerAPI

A RESTful financial ledger API built with Django REST Framework and PostgreSQL for managing user accounts, financial transactions, and double-entry ledger records.

The project focuses on secure authentication, reliable money transfers, transaction integrity, idempotency, concurrency handling, and production deployment.

Features

  • User registration and authentication
  • JWT-based authentication
  • Access and refresh tokens
  • Refresh token rotation and blacklisting
  • User account management
  • Financial account balances
  • Money transfers between accounts
  • Double-entry ledger records
  • Transaction status tracking
  • Idempotent transfers using idempotency keys
  • Database transaction atomicity
  • Row-level locking for concurrent transfers
  • Currency validation
  • Account status validation
  • Transaction history
  • Transaction filtering
  • Pagination
  • API throttling
  • OpenAPI schema and Swagger documentation
  • Automated tests
  • Docker containerization
  • PostgreSQL database
  • Production deployment with Render and Neon

Tech Stack

Technology Purpose
Python Backend programming language
Django Web framework
Django REST Framework REST API development
PostgreSQL Relational database
SimpleJWT JWT authentication
drf-spectacular OpenAPI/Swagger documentation
Docker Containerization
Gunicorn Production WSGI server
Nginx Reverse proxy for local container setup
Render Production application hosting
Neon Production PostgreSQL database
uv Python dependency and environment management
Git/GitHub Version control

Architecture

Client
   │
   ▼
REST API
   │
   ▼
Django REST Framework
   │
   ├── Authentication / Permissions
   │
   ├── Serializers
   │
   ├── Views / ViewSets
   │
   ▼
Service Layer
   │
   ├── Transfer validation
   ├── Idempotency
   ├── Atomic transactions
   └── Concurrency control
   │
   ▼
PostgreSQL
   │
   ├── Accounts
   ├── Transactions
   └── Ledger Entries

Production

Internet
   │
   ▼
Render
   │
   ▼
Django + Gunicorn
   │
   ▼
Neon PostgreSQL

Authentication

The API uses JWT authentication.

Users obtain access and refresh tokens through the authentication endpoints.

Access tokens are short-lived, while refresh tokens can be used to obtain new access tokens.

Refresh token rotation and blacklisting are enabled to prevent reuse of rotated refresh tokens.

Protected endpoints require:

Authorization: Bearer <access_token>

API Endpoints

Authentication

POST /api/auth/register/
POST /api/auth/login/
POST /api/auth/token/refresh/

Accounts

GET /api/accounts/
GET /api/accounts/{id}/

Transactions

GET  /api/transactions/
GET  /api/transactions/{id}/
POST /api/transactions/transfer/

Documentation

GET /api/schema/
GET /api/docs/

Money Transfer

Transfers are handled inside a database transaction.

The transfer process validates:

  1. The sender and receiver are different accounts.
  2. Both accounts exist.
  3. Both accounts are active.
  4. Both accounts use the same currency.
  5. The idempotency key has not been used for a different transaction.
  6. The sender has sufficient funds.

The accounts are locked using database row-level locking before the balance is checked.

This prevents concurrent transfers from spending the same balance.

Conceptually:

Request
   │
   ▼
Validate transfer
   │
   ▼
Lock accounts
   │
   ▼
Check idempotency
   │
   ▼
Check balance
   │
   ▼
Create transaction
   │
   ▼
Create debit ledger entry
   │
   ▼
Create credit ledger entry
   │
   ▼
Mark transaction COMPLETED

If any operation fails, the database transaction is rolled back.

Idempotency

Transfers require an idempotency_key.

This prevents accidental duplicate processing when the same request is submitted more than once.

For example:

{
  "from_account_id": 1,
  "to_account_id": 2,
  "amount": "100.00",
  "idempotency_key": "transfer-001"
}

If the same request is submitted again with the same key, the existing transaction can be returned instead of creating another transfer.

If the same key is reused with different transaction details, the request is rejected.

Ledger

The system records transfers using ledger entries.

A successful transfer creates:

Sender Account
    │
    └── DEBIT 100.00

Receiver Account
    │
    └── CREDIT 100.00

The ledger provides a transaction history from which account balances can be calculated.

Transaction Integrity

The transfer service uses Django's database transaction management:

with transaction.atomic():
    ...

This ensures that related database operations succeed or fail together.

For example, if the debit entry succeeds but the credit entry fails, the entire transfer is rolled back.

Concurrency Control

The transfer service uses:

select_for_update()

to lock the accounts involved in a transfer.

Accounts are locked in a consistent order to reduce the risk of deadlocks.

This is important when multiple requests attempt to transfer money from the same account at the same time.

Validation

The API validates:

  • Positive transaction amounts
  • Sender and receiver accounts
  • Account status
  • Currency compatibility
  • Sufficient balance
  • Idempotency keys
  • User authorization

Example insufficient-balance response:

{
  "detail": "Insufficient balance. Current balance is 0.00. Requested amount is 100.00."
}

Pagination and Filtering

Transaction history supports pagination and filtering.

Example:

GET /api/transactions/

Response:

{
  "count": 10,
  "next": "...",
  "previous": null,
  "results": []
}

API Throttling

The API uses DRF throttling to limit request rates.

Configured limits include:

Anonymous users: 20 requests/minute
Authenticated users: 60 requests/minute

This provides basic protection against excessive API requests.

Testing

The project includes automated tests covering areas such as:

  • Successful transfers
  • Insufficient funds
  • Same-account transfers
  • Invalid accounts
  • Inactive accounts
  • Currency mismatch
  • Transaction rollback
  • Idempotency
  • Concurrent transfers
  • Authorization
  • Transaction filtering
  • Transaction status filtering
  • Pagination

The test suite has previously passed with:

Ran 33 tests

OK

Environment Variables

Sensitive configuration is stored in environment variables rather than committed to Git.

Example:

SECRET_KEY=your-secret-key
DEBUG=False
DATABASE_URL=your-postgresql-connection-string
SECURE_SSL_REDIRECT=True

The .env file is excluded from version control.

Running Locally

Clone the repository:

git clone https://github.com/mucheru-delvan/FinancialLedgerAPI.git
cd FinancialLedgerAPI

Create and activate the virtual environment:

uv sync
source .venv/bin/activate

Run migrations:

uv run python manage.py migrate

Start the development server:

uv run python manage.py runserver

The API will be available at:

http://127.0.0.1:8000/

Swagger documentation:

http://127.0.0.1:8000/api/docs/

Docker

The project includes Docker support for running the application in containers.

Build the image:

docker build -t financial-ledger-api .

Run the container:

docker run --rm \
  -p 8000:8000 \
  -e PORT=8000 \
  --env-file .env \
  financial-ledger-api

The project also includes Docker Compose for running Django, PostgreSQL, and Nginx together.

docker compose up --build

Production Deployment

The API is deployed using:

  • Render for the Django application
  • Neon for PostgreSQL

Production architecture:

Client
  │
  ▼
Render
  │
  ▼
Docker
  │
  ▼
Gunicorn
  │
  ▼
Django REST Framework
  │
  ▼
Neon PostgreSQL

Swagger:

https://financialledgerapi.onrender.com/api/docs/

Security

Security measures implemented include:

  • JWT authentication
  • Short-lived access tokens
  • Refresh token rotation
  • Refresh token blacklisting
  • Password hashing through Django
  • Authenticated API permissions
  • Environment-based secrets
  • HTTPS in production
  • API throttling
  • Database transactions
  • Row-level locking
  • Idempotent transaction processing
  • Input validation

Project Goals

This project was built to demonstrate practical backend engineering concepts relevant to financial systems, including:

  • REST API design
  • Authentication and authorization
  • Relational database design
  • Transaction processing
  • ACID transactions
  • Concurrency control
  • Idempotency
  • Testing
  • Containerization
  • Production deployment

About

A RESTful API for managing financial accounts, transactions, and ledger records with secure authentication and reliable transaction processing.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages