A robust, production-ready REST API for a hotel booking system. Features dynamic pricing, real-time inventory management, automated expiration of unpaid bookings ("Zombie Killer"), and secure payments via Stripe. Built with Django REST Framework, Celery, Redis, and Stripe.
- Features
- API Flow Diagrams
- Quick Start (Docker)
- Manual Development Setup
- Configuration Reference
- Testing Guide
- API Documentation
- Project Structure
- Real-time Availability: Prevents double-booking using atomic database transactions.
- Dynamic Pricing Engine: Calculates prices based on:
- Date ranges (e.g., High Season)
- Days of the week (e.g., Weekend rates)
- Room types
- The "Zombie Killer" Task: A background job (Celery) that automatically expires "Pending" bookings if they remain unpaid for more than 15 minutes, releasing inventory back to the pool.
- Payment Intents: Secure handling of payments using Stripe's modern API.
- Webhooks: Listens for Stripe events to automatically confirm bookings upon successful payment.
- "God Mode" Testing: A developer-only feature to instantly confirm payments via API without a frontend (for testing purposes).
- Refund Handling: Logic for calculating refunds and penalties based on cancellation policies (48-hour rule).
- Authentication: JWT (JSON Web Token) authentication.
- Documentation: Auto-generated Swagger/OpenAPI docs via drf-spectacular.
- Dockerized: Ready for containerized deployment.
graph TD
A[Client/Frontend] -->|1. Search Rooms| B[GET /api/search]
B -->|Returns available rooms| A
A -->|2. Create Booking| C[POST /api/book]
C -->|Creates PENDING booking| D[(Database)]
D -->|Status: PENDING| A
A -->|3. Initiate Payment| E[POST /api/bookings/ID/checkout]
E -->|Creates Stripe Intent| F[Stripe API]
F -->|Returns client_secret| E
E -->|Returns credentials| A
A -->|4. Confirm Payment| F
F -->|5. Payment Succeeded| G[Stripe Webhook]
G -->|6. POST /api/webhook| H[Django Webhook Handler]
H -->|Updates booking| D
D -->|Status: CONFIRMED| H
H -->|7. Response 200| G
D -->|Booking confirmed| A
Use this method to run the entire system (Django, Postgres, Redis, Celery) instantly without installing any dependencies on your machine.
Prerequisites: Only Docker Desktop and Git.
π‘ Quick Download: Want to skip cloning the repository? You can pull the pre-built Docker image directly from Docker Hub:
docker pull mohammed237/booking-engine:v1View image on Docker Hub for updates, documentation, and version history.
# Clone the repository
git https://github.com/Mohammed2372/Booking-Engine-API.git
cd Booking-Engine-API
# Copy the example env file to create your local config
cp .env.example .env
# (On Windows use: copy .env.example .env)
# Open the .env file and fill in your specific keys:
# - SECRET_KEY
# - STRIPE Keys (Public, Secret, Webhook)Run this single command to download the image, set up the database, and start the servers.
docker compose -f docker-compose.prod.yml up- API: http://localhost:8000/api/ # main entrypoint
- Swagger Docs: http://localhost:8000/api/docs/ # interactive API docs
To access the admin panel, create a superuser inside the running container:
docker compose -f docker-compose.prod.yml exec web python manage.py createsuperuserUse this method only if you are a developer contributing to the code and want to run services individually for debugging.
- Python 3.10+
- PostgreSQL
- Redis (for Celery)
- Stripe CLI
# Create virtual environment
python -m venv .venv
source .venv/bin/activate
# On Windows: .venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Create .env from example
cp .env.example .envYou must install these manually if running outside Docker:
- Install PostgreSQL for your OS.
- Create a database named
booking_db. - Update
.envto setSQL_HOST=localhost.
- Install Redis (
brew install redisor download for Windows). - Ensure it is running on port 6379.
- Update
.envto setCELERY_BROKER=redis://localhost:6379/0.
- Install Stripe CLI to forward webhooks to localhost.
- Run
stripe login.
python manage.py migrate
python manage.py createsuperuser- Django Server:
python manage.py runserver - Celery Worker:
celery -A core worker -l info - Celery Beat:
celery -A core beat -l info - Stripe Listener:
stripe listen --forward-to localhost:8000/api/webhook/
Located in core/celery.py:
# Task routing
CELERY_TASK_ROUTES = {
'bookings.tasks.expire_pending_bookings': {'queue': 'default'},
}
# Task time limits (prevent hanging tasks)
CELERY_TASK_TIME_LIMIT = 30 * 60 # 30 minutes hard limit
CELERY_TASK_SOFT_TIME_LIMIT = 25 * 60 # 25 minutes soft limit
# Celery Beat schedule (in core/settings.py)
CELERY_BEAT_SCHEDULE = {
'expire-pending-bookings': {
'task': 'bookings.tasks.expire_pending_bookings',
'schedule': crontab(minute='*/1'), # Every minute
},
}Keys location: core/settings.py
STRIPE_SECRET_KEY = os.getenv("STRIPE_SECRET_KEY")
STRIPE_PUBLIC_KEY = os.getenv("STRIPE_PUBLIC_KEY")
STRIPE_WEBHOOK_KEY = os.getenv("STRIPE_WEBHOOK_KEY")Webhook endpoint: POST /api/webhook/
To test that bookings expire after 15 minutes:
- Create a Booking: POST to
/api/book/. Status will bePENDING. - Wait: Wait 16 minutes OR manually modify the
created_attimestamp in DB. - Check Status: The Celery Beat task runs every minute. It should update status to
EXPIRED. - Verify Inventory: You should be able to book the same room again immediately.
We implemented a special testing flag to bypass the frontend card entry.
Endpoint: POST /api/bookings/{id}/checkout/
Request Body:
{
"auto_confirm": true
}Result: The server contacts Stripe, forces a test charge using a Visa mock, and instantly updates the booking to CONFIRMED.
To test the real integration where Stripe notifies Django:
-
Start Stripe Listener:
stripe listen --forward-to localhost:8000/api/webhook/
-
Create a Booking normally (get the
client_secret). -
Confirm via CLI (Simulates user paying on frontend):
stripe payment_intents confirm pi_3Sk... --payment-method=pm_card_visa
-
Verify: Check your terminal. The webhook should hit
/api/webhook/and you should see "β Booking confirmed via Webhook."
# Run specific bookings app tests
python manage.py test bookings
Once the server is running, visit:
- Swagger UI: http://localhost:8000/api/docs/ # for full interactive docs
- ReDoc: http://localhost:8000/api/schema/redoc/ # for alternative docs view
- Admin Panel: http://localhost:8000/admin/ # for managing models and admin dashboards
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/search/ |
Search available rooms |
| POST | /api/book/ |
Create a new booking |
| GET | /api/bookings/{id}/ |
Get booking details |
| POST | /api/bookings/{id}/checkout/ |
Initiate payment |
| POST | /api/bookings/{id}/cancel/ |
Cancel a booking |
| POST | /api/webhook/ |
Stripe webhook handler |
| POST | /api/auth/login/ |
JWT authentication |
Booking Engine/ # repository root
βββ .env.example # example env variables
βββ manage.py # Django management entrypoint
βββ README.md # this file
βββ requirements.txt # Python dependencies
β
βββ authentication/ # auth: registration & JWT
β βββ admin.py # Django admin registrations
β βββ models.py # auth-related models (users/profiles)
β βββ serializers.py # DRF serializers for auth
β βββ urls.py # endpoints: register/login/refresh
β βββ views.py # registration & auth views
β
βββ bookings/ # booking domain logic
β βββ admin.py # admin for bookings/models
β βββ models.py # Booking, Reservation, etc.
β βββ serializers.py # DRF serializers for bookings
β βββ services.py # business logic & helpers
β βββ tasks.py # Celery tasks (e.g., expire bookings)
β βββ tests.py # unit tests for bookings
β βββ urls.py # booking-related endpoints
β βββ views.py # booking API views
β
βββ core/ # project core settings & entrypoints
β βββ celery.py # Celery app configuration
β βββ settings.py # Django settings
β βββ urls.py # root URL config (includes app urls)
β
βββ inventory/ # rooms, room types, availability
β βββ admin.py # admin for RoomType model
β βββ filters.py # DRF filters for search/listing
β βββ models.py # Room, RoomType, PricingRule models
β βββ serializers.py # DRF serializers for inventory
β βββ services.py # inventory helpers & pricing engine
β βββ urls.py # endpoints: room search
β βββ views.py # search & listing rooms API views
β
βββ payments/ # Stripe payment integration
β βββ services.py # create payment intents, webhooks
β βββ urls.py # endpoints: webhook
β βββ views.py # Stripe webhook handler
β
βββ user/ # user profile & wishlist & reviews
βββ admin.py # user profile, wishlist and reviews dashboards
βββ models.py # Profile, Wishlist models
βββ serializers.py # DRF serializers for user
βββ urls.py # endpoints: profile, wishlist, review
βββ views.py # user API views