A robust, atomic, and idempotent payment processing backend built with Django and Django REST Framework, focusing on financial correctness, concurrency safety, and auditability.
- Features
- Tech Stack
- Prerequisites
- Installation & Local Setup
- Docker Deployment
- API Documentation
- Architecture & Design
- Running Tests
- Project Structure
- Future Roadmap
- Account Management: Create and manage multi-currency accounts.
- Immutable Transactions: Ledger-style credit and debit operations that cannot be modified or deleted.
- Atomic Transfers: Safe money movement between accounts with full rollback on failure.
- Financial Correctness:
- Strict overdraft prevention (balance never drops below zero).
- Decimal arithmetic for precision (no floating-point errors).
- Concurrency Safety: Row-level locking (
select_for_update) to prevent race conditions. - Idempotency: Built-in protection against duplicate requests using unique idempotency keys.
- Audit Logging: Comprehensive event emission for all financial activities.
- Language: Python 3.11+
- Framework: Django 4.x & Django REST Framework
- Database: SQLite (Default) / PostgreSQL (Ready)
- Documentation: OpenAPI 3.0 / Swagger UI
- Containerization: Docker & Docker Compose
- Utilities:
python-dotenv,dj-database-url
- Python: Version 3.11 or higher
- pip: Python package installer
- Docker (Optional, for containerized run)
- Git (for version control)
Follow these steps to set up the project locally for development.
git clone <repository-url>
cd Payment-ServiceIsolate dependencies by creating a virtual environment.
Windows:
python -m venv .venv
.\venv\Scripts\activateLinux/macOS:
python3 -m venv venv
source venv/bin/activatepip install -r requirements.txtCreate a .env file in the project root to configure the application.
# Create .env file
touch .envAdd the following configuration to .env:
DEBUG=True
SECRET_KEY=your-secure-secret-key-development-only
DATABASE_URL=sqlite:///db.sqlite3
ALLOWED_HOSTS=localhost,127.0.0.1Initialize the database schema.
python manage.py migrateTo access the Django Admin panel, you need a superuser account.
python manage.py createsuperuserFollow the prompts to set a username, email, and password.
python manage.py runserverThe service will be available at http://localhost:8000/.
Run the complete application stack using Docker.
docker-compose up --buildThis command builds the image and starts the service on port 8000.
docker-compose downThe specificaiton is available in standard OpenAPI 3.0 format.
| Type | URL / Path | Description |
|---|---|---|
| Swagger UI | http://localhost:8000/api/docs/ | Interactive API explorer |
| OpenAPI Schema | http://localhost:8000/api/schema/ | Dynamic JSON schema |
| Static File | openapi.yaml |
Static YAML specification file included in repo |
- You can write the openapi.yaml file manually as it will be more organized and more readable having swagger schemas on a seperate organized folder.
- You can use
python manage.py spectacular --file schema.yamlto generate the OpenAPI schema from the code automatically, which will generate a seperate schema fileschema.yamlmatching the code and representing openapi.yaml.
The project includes a comprehensive test suite covering standard flows, edge cases, and error conditions.
# Run all tests
python manage.py test accounts
# Run tests with verbosity
python manage.py test accounts -v 2
# Run tests with Coverage Report
coverage run --source='.' manage.py test
coverage reportCoverage includes:
- Account creation & retrieval
- Credit & Debit atomicity
- Overdraft prevention logic
- Idempotency (duplicate key handling)
- Transfer atomicity & rollback integrity
Payment-Service/
├── accounts/
│ ├── migrations/ # DB schema changes
│ ├── tests/ # Comprehensive tests
│ │ ├── __init__.py
│ │ ├── test_api.py # Integration tests for APIs
│ │ └── test_services.py # Unit tests for services
│ ├── exceptions.py # Custom exceptions
│ ├── models.py # Database models
│ ├── serializers.py # Data serialization & validation
│ ├── services.py # Core business logic (Atomic transactions)
│ ├── signals.py # Event signals
│ ├── urls.py # URL routing
│ └── views.py # API Controllers
├── payment_service/ # Project configuration
│ ├── settings.py # Django settings
│ ├── urls.py # Main routing
│ └── wsgi.py # WSGI entry point
├── swagger_schemas/ # Split API specifications
├── .env # Environment variables
├── boltfile.py # Bolt task runner configuration
├── Dockerfile # Docker build instructions
├── docker-compose.yml # Container orchestration
├── manage.py # CLI entry point
├── openapi.yaml # Swagger API Spec
├── requirements.txt # Production dependencies
├── requirements-dev.txt # Development dependencies
└── README.md # Project documentation
- Add Frontend for the service
Potential Technical enhancements for the next iteration:
- Add Authorization/Authentication: Secure the APIs with jwt-token-based authentication.
- PostgreSQL Migration: Switch to PostgreSQL for production to leverage better concurrent performance and JSONB support.
- Async Event Processing: Move event logging to a background worker (Celery/Redis) to reduce request latency.
- Rate Limiting: Add throttling to prevent API abuse.
- Multi-Currency Support: Integrate an exchange rate service for cross-currency transfers.
- Pagination: Add cursor-based pagination for large transaction history lists.
- Load tests: Add load tests using Locust.
Potential Business enhancements for the next iteration:
- Support Scheduled Transactions: Payroll, subscriptions, rent Cron-driven execution.
- Support Feature Flags: Enable/disable transfers, credits, debits dynamically.
- Support Multi-Currency & Money Realism: Integrate an exchange rate service for cross-currency transfers and Enforce valid ISO currencies.
- Soft Account Lock: Temporarily freeze an account without deleting it.
- Receive Monthly Report: Receive a monthly report on email as PDF/EXCEL files with all the transactions.
- Balance Snapshots: Periodic snapshots to speed up reads, Rebuild balance from ledger if corruption is suspected.
- Handle currency difference EGP VS USD when doing transfer