Web Commerce Domain

Location: api/nextango/apps/web_commerce/ Added: November 2025 Last Updated: 2026-07-08

Overview

The Web Commerce domain handles web checkout sessions, cart management, and inventory reservations for the web storefront. It mirrors the POS domain architecture but is optimized for web checkout flows with TTL-based sessions instead of heartbeat-based terminal sessions.

The app's URLconf mounts at web-commerce/ on the root URLconf (nextango/urls.py:167), so every Django-level endpoint is an absolute path under /web-commerce/. See Views for the full endpoint list and the storefront proxy prefix distinction.

Key Architectural Principles

  1. Pure orchestration: services coordinate existing domain services (TransactionService, PaymentService, InventoryAdjustmentService) rather than implementing business logic
  2. TTL-based sessions: checkout sessions expire after 30 minutes by default, with auto-expiry of inventory reservations
  3. Guest and authenticated: supports both guest checkout and authenticated customer checkout
  4. Atomic inventory: row-level locking ensures inventory reservations are consistent
  5. Ownership-based cart and checkout access: cart and checkout endpoints authorize by web_session FK ownership, not by trusting session['cart_id'] byte-equality. A cart-session token (X-Cart-Session-Token header, hashed with SHA-256 and stored on WebSession.cart_token_hash) is the primary identity credential, with the session cookie as fallback, so identity survives cookie-hostile contexts such as embedded webviews. See Views for the authorization gates and Services for SessionService.

Domain Structure

web_commerce/
├── models.py           # CheckoutSession, CheckoutReservationContext
├── services/
│   ├── cart_service.py       # Cart validation and composition
│   ├── checkout_service.py   # Checkout flow orchestration
│   ├── email_service.py      # Order confirmation & notification emails (Updated Dec 2025)
│   ├── reservation_service.py # Inventory reservation management
│   ├── session_service.py    # Web session management
│   └── lifecycle_service.py  # Session cleanup and expiry
├── views.py            # API endpoints
├── serializers.py      # DRF serializers
├── middleware.py       # Session/CSRF middleware
├── signals.py          # Event handlers
├── tasks.py            # Celery background tasks
└── urls.py             # URL routing

Relationship to Other Domains

┌─────────────────────────────────────────────────────────────┐
│                     WEB COMMERCE                            │
│    (Orchestrates checkout flow for web storefront)          │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  CheckoutSession ─────────────► transactions.SaleTransaction │
│       │                                    │                │
│       └──► transactions.Cart              │                 │
│       │                                    │                │
│       └──► web_auth.WebSession            │                 │
│                                            │                │
│  CheckoutReservationContext                ▼                │
│       │                         transactions.Fulfillment    │
│       └──► products.InventoryLevel              │           │
│                                         transactions.Shipment│
│                                                              │
└─────────────────────────────────────────────────────────────┘

Key Relationships:

  • transactions.Cart: Uses the existing Cart model with JSONField line_items
  • transactions.SaleTransaction: Creates transaction on checkout completion
  • transactions.Fulfillment/Shipment: Created for shipping orders
  • products.InventoryLevel: Reservations increment stock_reserved
  • web_auth.WebSession: Guest/authenticated session context

Checkout Flow

┌─────────────────────────────────────────────────────────────┐
│                    CHECKOUT FLOW                            │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  1. CART STAGE                                              │
│     └──► CartService.add_to_cart()                          │
│     └──► CartService.validate_cart()                        │
│                                                              │
│  2. INITIATE CHECKOUT                                       │
│     └──► CheckoutService.initiate_checkout()                │
│         - Creates CheckoutSession                           │
│         - Sets fulfillment_method (ship/pickup/digital)     │
│         - Validates cart                                    │
│                                                              │
│  3. COLLECT INFORMATION                                     │
│     - Frontend collects address, payment, delivery          │
│     - Session expires_at extended on activity               │
│                                                              │
│  4. COMPLETE CHECKOUT                                       │
│     └──► CheckoutService.complete_checkout()                │
│         - Creates SaleTransaction                           │
│         - Adds line items                                   │
│         - Processes payment                                 │
│         - Commits inventory                                 │
│         - Creates Fulfillment/Shipment                      │
│         - Clears cart                                       │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Inventory Reservation Lifecycle

┌─────────────────────────────────────────────────────────────┐
│               RESERVATION LIFECYCLE                         │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ACTIVE ──────────► COMMITTED (checkout completed)          │
│     │                                                        │
│     └────────────► RELEASED (checkout cancelled)            │
│     │                                                        │
│     └────────────► EXPIRED (TTL elapsed)                    │
│                                                              │
│  Process:                                                   │
│  1. reserve_for_checkout() increments stock_reserved         │
│  2. On completion: commit_reservations() marks committed    │
│  3. On cancel: release_reservations() decrements reserved   │
│  4. Background task: expire_old_reservations() auto-release │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Documentation Files

  • Models: CheckoutSession, CheckoutReservationContext
  • Services: CartService, CheckoutService, ReservationService, SessionService, LifecycleService
  • Views: API endpoints, including ownership-based authorization and guest order tracking
  • Serializers: request/response serialization
  • Middleware: CartValidationMiddleware
  • Signals: reservation cleanup on session lifecycle events
  • Tasks: periodic cleanup Celery tasks

Storefront API Proxy (Next.js)

The storefront (storefront/web/) uses a Next.js API route to proxy requests to Django.

Location: storefront/web/app/api/[[...path]]/route.ts

How It Works

  1. All methods proxied: GET, POST, PUT, PATCH, DELETE
  2. Cookie forwarding: Browser cookies forwarded to Django for session validation
  3. Service account auth: Injects Authorization: Token <token> from Docker secret or env var
  4. URL mapping: /api/foo/bar on storefront maps to http://api:8000/foo/bar on Django

Configuration

Environment VariablePurposeDefault
DJANGO_API_URLBackend API URLhttp://api:8000
DJANGO_API_TOKENService account tokenDocker secret fallback

Docker Secret Path

Token can be stored at /run/secrets/storefront_api_token for Docker Swarm deployments.

Request Flow

Browser → Storefront (/api/products/) → Proxy → Django (http://api:8000/products/)

                                    + Cookie header
                                    + Authorization header
                                    + X-Forwarded-Proto: https

Guest Order Tracking

Added: December 2025

Enables guest customers to track orders without creating an account.

Flow

  1. Checkout completion: guest_access_token generated and stored on SaleTransaction
  2. Confirmation email: Token included in order confirmation
  3. Order lookup: Guest uses token via POST /web-commerce/guest-order/

Security

  • 32-character alphanumeric token generated with secrets.choice()
  • Rate-limited endpoint (AnonRateThrottle)
  • Generic error messages prevent token enumeration
  • No personal data in URL (POST body only)

Was this page helpful?