Task
A small bookshop wanted to sell online. It must never sell more copies than it has, even when two people check out at the same moment. Old orders must keep their prices after catalog and exchange rate changes, and buyers from different countries must see their own language and currency.
Solution
All business rules live in a Django REST API, and the Vue app only calls it. An order line keeps the title and price at the time of purchase in the chosen currency. An order is paid only after a signed Stripe webhook, and every refund is a separate record with an idempotency key, so money is never refunded twice.
What was done
- Built a catalog with full-text search that finds a book even with a typo
- Ruled out overselling: checkout locks the book rows in one transaction
- Priced shipping by weight and zone and tax by country, state or postal code
- Connected card payments through Stripe and a demo provider with test cards
- Built order cancelling with refunds, partial ones included
- Showed prices in dollars, euros and roubles, with currencies added in the admin
- Translated the interface and the catalog into Russian, English, French and German
- Moved exchange rate updates and refund retries to a separate scheduler
Result
The shop takes orders from a phone in four languages and three currencies, never oversells and refunds cancelled orders by itself. The code is open on GitHub, and the shop starts with a single docker compose up.
Technologies
PythonDjango REST FrameworkVue 3TypeScriptPostgreSQLStripeDocker