Simple payment system REST API.
Allows user:
- create account with wallet
- get account with wallet
- replenish wallet amount
- transfer amount from one wallet to another
Currently supports only USD currency.
All the operations performs without commision.
- python-3.8
- FastAPI
- PostgreSQL
- databases for async work with database
- Alembic for migrations
- Docker with Docker Compose
Run the project: docker-compose up --build -d
You can change default environment variables in .env
file.
Run tests:
- set
TESTING=1
in.env
- build project:
docker-compose down -v && docker-compose up --build -d
- run tests:
docker-compsoe exec backend pytest app/tests/unittests -s -vv
- Used FastAPI as a backend framework because it is simple and performant.
- Used PostgreSQL as a database backend because it's open source, performant and this task required consistency between
tables (so ACID transactions). Also, PostgreSQL is mature and proven tool for such billing tasks. However,one of the
disadvantages of using Postgres is that in some performance measures it is slower than mysql. But I used Postgres before so I
chose this one.
To store incoming data I created several tables:account(id, name, created_at, updated_at)
- store general information about user. Connected with wallet in one-to-one relationship.wallet(id, account_id, amount, currency, created_at, updated_at)
- store information about current account moneycurrency(code)
- static table with only one currency -USD
transaction(id, type, created_at)
- append only table; store information about wallet transactions. 2 types of transaction supported -replenish
andtransfer
. Row created when replenish wallet or transfer money performs.posting(id, transaction_id, amount, currency)
- append only table; information about transaction amount and wallets. It is possible to restore wallet amount depending ontransaction
and this tables. Used to log wallet operations.
There are several improvements in architecture of this system:
- Add rate limiter to prevent users overuse this API.
- Add Redis or memcached to cache db results of reading operations (however I think this system will mostly be used for write operations, so it is not really necessary).
- Add idempotency tokens support to create account, replenish wallet and transfer money methods to handle correctly identical sequential operations from one user.