Order Module Backend Documentation
Order Module - Backend Documentation
1. Backend Scope and Boundaries
Order backend owns:
- checkout and buy-now initiation
- order state transitions and status history
- async order commands (cancel/process-refund)
- payment callback-driven finalization handoff
- outbox dispatch and retention cleanup for order-owned maintenance runtime
Order domain supports:
payment_method:online
order_payment_method is intentionally constrained to online today. The enum remains in place as a forward-compatible contract so future payment methods can be introduced through coordinated migrations and client rollout.
2. Module Composition (Aggregate + Leaf)
OrderModule composes:
OrderCoreModuleOrderCustomerModuleOrderAdminModuleOrderProcessingModule
Ownership model:
OrderCoreModuleexports shared domain service (OrderService)- customer/admin modules own their HTTP surfaces
OrderProcessingModuleowns queues, processors, maintenance scheduler, outbox dispatch, and cleanup
3. Data Model (Drizzle / PostgreSQL)
Primary tables:
orderorder_itemorder_status_historyasync_requestoutbox_event
Schema source of truth:
packages/db/src/schema/order/enums.tspackages/db/src/schema/order/orders.tspackages/db/src/schema/order/order-items.tspackages/db/src/schema/order/order-status-history.ts
Monetary integrity constraints (paisa):
- order totals:
total_mrp,total_sp,discount,coupon_discount,final_payable,refund_amount - order line values:
unit_mrp,unit_sp,discount,final_value - DB check constraints enforce non-negative values.
Actor provenance model (order_status_history):
actor_type = customer+created_by_customer_idactor_type = admin+created_by_admin_idactor_type = system+ both null
4. Runtime Rules and Domain Invariants
4.1 Synchronous initiation paths
POST /api/orders/checkoutPOST /api/orders/buy-now
These create order/payment intent synchronously and return payment initiation payload immediately.
Buy-now product mapping:
- physical products (
thangka,singing_bowl,statue,jewellery) createorder_type = physical
4.2 Asynchronous finalization and commands
- payment success/failure jobs from payment redirect events
- retry reconciliation (
order.payment_retry) - auto-cancel for unpaid orders (
order.auto_cancel) - async customer/admin cancellation and refund processing (
order.cancel,order.process_refund)
4.3 Payment redirect contract
Gateway verification uses backend-owned redirect handlers:
GET|POST /api/payments/redirect/:paymentId/successGET|POST /api/payments/redirect/:paymentId/failure
Return URL and callback URL resolution use runtime config (API_PUBLIC_BASE_URL, FRONTEND_BASE_URL, PAYMENT_RESULT_PAGE_URL).
4.4 Idempotency and atomicity
- idempotency-key replay for checkout/buy-now is deterministic
- async request dedupe via
async_requests - outbox dedupe via
(aggregate_type, aggregate_id, job_name, dedupe_key) - queue jobs use deterministic
jobId - multi-table mutations execute in DB transactions
4.5 Payment success artifact creation
On successful payment, processor finalizes order state and emits inventory-finalization outbox events:
- physical products transition through reserve -> finalize inventory lifecycle
4.6 Queues used by order runtime
ordersorders_maintenancecart(outbox dispatch target for cart-clear intent)
4.7 Outbox lifecycle and cleanup behavior
outbox_events is shared infrastructure. Order runtime writes outbox events while maintenance runtime handles dispatch and retention cleanup.
Dispatch ownership:
OutboxDispatcherServiceclaimspendingrows only for owned target queues:ordersorders_maintenancecart
Cleanup flow:
OrdersMaintenanceSchedulerenqueuesorders_maintenance.cleanup_outbox.OrdersMaintenanceProcessorrunsOutboxCleanupService.cleanup().- Completed rows older than
OUTBOX_RETENTION_DAYSand failed rows older thanOUTBOX_FAILED_RETENTION_DAYSare removed in batches. - DLQ health check compares failed-job count against
OUTBOX_CLEANUP_DLQ_THRESHOLDand emits alert-level logs on breach.
5. Caching Strategy
Read-side keyspaces:
order:*order:customer:list:*order:admin:list:*order:admin:detail:*
Cross-module keys invalidated by order processing when applicable:
Configured TTLs:
ORDER_HISTORY_CACHE_TTL_SECONDS(default120)ORDER_ADMIN_CACHE_TTL_SECONDS(default60)
6. Rate Limiting Strategy
Customer-side controls:
ORDER_CHECKOUT_RATE_LIMIT(default10)ORDER_RETRY_PAYMENT_RATE_LIMIT(default5)ORDER_CANCEL_RATE_LIMIT(default10)ORDER_REFUND_REQUEST_RATE_LIMIT(default5)ORDER_CHECKOUT_RATE_WINDOW_SECONDS(default60)
Admin-side controls:
ORDER_ADMIN_OPERATION_RATE_LIMIT(default120)ORDER_ADMIN_RATE_WINDOW_SECONDS(default60)
All rate limiting paths use Redis-backed counters/sliding windows and throw RateLimitExceededException on breach.
Additional order runtime knobs:
ORDER_AUTO_CANCEL_MINUTES(default30)ORDER_PAYMENT_RETRY_MAX_ATTEMPTS(default3)OUTBOX_RETENTION_DAYS(default7)OUTBOX_FAILED_RETENTION_DAYS(default30)OUTBOX_CLEANUP_ENABLED(defaulttrue)OUTBOX_CLEANUP_CRON(default0 3 * * *)ORDERS_DISPATCH_CRON(default* * * * *)ORDERS_FAILED_MONITOR_CRON(default*/5 * * * *)OUTBOX_CLEANUP_DLQ_THRESHOLD(default100)DLQ_WARNING_THRESHOLD(default50)OUTBOX_BATCH_SIZE(default300)OUTBOX_PENDING_PREVIEW_LIMIT(default10)RETRY_BASE_DELAY_MS(default2000)RETRY_MAX_DELAY_MS(default120000)PAYMENT_RETRY_DELAY_ATTEMPT_1_MS(default60000)PAYMENT_RETRY_DELAY_ATTEMPT_2_MS(default300000)PAYMENT_RETRY_DELAY_ATTEMPT_3_MS(default900000)WORKER_ORDERS_CONCURRENCY(default20)WORKER_ORDERS_MAINTENANCE_CONCURRENCY(default8)
7. Error and Resilience Contracts
Representative API/domain errors:
| HTTP | errorCode | Message |
|---|---|---|
| 400 | ORDER_CART_INACTIVE | Only active cart can be checked out. |
| 400 | ORDER_CART_EMPTY | Cart has no items. |
| 400 | ORDER_PAYMENT_AMOUNT_MISMATCH | Payment amount mismatch detected. |
| 400 | ORDER_PRODUCT_NOT_AVAILABLE | Product is not available for purchase. |
| 400 | ORDER_PAYMENT_METHOD_NOT_SUPPORTED | Only online payment is supported. |
| 400 | ORDER_CANCEL_NOT_ALLOWED | Order cannot be cancelled in current status. |
| 400 | ORDER_NOT_PENDING_REFUND | Order is not pending refund processing. |
| 400 | ORDER_NOTE_REQUIRED | Note is required. |
| 403 | ORDER_REFUND_ACCESS_DENIED | You do not have permission to request refund for this order. |
| 404 | ORDER_CART_NOT_FOUND | Cart not found. |
| 404 | ORDER_ASYNC_REQUEST_NOT_FOUND | Async request not found. |
| 404 | ORDER_NOT_FOUND | Order not found. |
| 409 | ORDER_IDEMPOTENCY_MISMATCH | Request with this idempotency key is already in progress. |
| 503 | ORDER_ASYNC_REQUEST_CREATION_FAILED | Failed to create async order request. |
| 503 | ERR_CONFIG_INVALID | Configuration value is missing/invalid. |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests. Please try again later. |
Resilience controls in processing runtime:
- retry + backoff for queued failures
- queue failed-set threshold monitoring (
DLQ_WARNING_THRESHOLD,QUEUE_FAILED_THRESHOLD_*) - outbox retention cleanup with separate thresholds (
OUTBOX_CLEANUP_DLQ_THRESHOLD)
8. Performance Notes
- Services use select projections instead of broad row selection for list/detail views.
- Pagination is normalized and translated via
PaginationUtil, with count queries only when pagination is enabled. - Independent operations use
Promise.all(...)in critical paths (for example, outbox dispatcher scan and cleanup stats). - Hot order list/detail reads are cached in Redis with deterministic cache keys.
- Processor cache invalidation is prefix-based (
invalidatePattern(prefix*)) to avoid stale reads after async state transitions.
9. Backend Diagram
10. Release/QA Checklist
- Checkout/buy-now initiation remains synchronous and returns gateway payload.
- Payment redirect callbacks enqueue correct order jobs for success/failure.
- Cancel/refund async commands create pollable async requests and deterministic job ids.
- Status history entries preserve actor provenance constraints.
- Payment success replay does not duplicate entitlement artifacts.
- Outbox dispatcher only claims owned target queues (
orders,orders_maintenance,cart). - Outbox cleanup retention and DLQ threshold behavior is validated in non-prod run.
- Runtime env defaults are present and pass startup validation.
11. File Map
apps/api/src/modules/order/admin/*apps/api/src/modules/order/customer/*apps/api/src/modules/order/processing/*packages/db/src/schema/order/*
12. Environment Variables
| Variable | Default | Description |
|---|---|---|
ORDER_CHECKOUT_RATE_LIMIT | 10 | Rate limit for checkout requests per window |
ORDER_CHECKOUT_RATE_WINDOW_SECONDS | 60 | Rate limit window in seconds for checkout |
ORDER_RETRY_PAYMENT_RATE_LIMIT | 5 | Rate limit for retry payment requests |
ORDER_RETRY_PAYMENT_RATE_WINDOW_SECONDS | 60 | Rate limit window for retry payment |
ORDER_CANCEL_RATE_LIMIT | 10 | Rate limit for order cancellation requests |
ORDER_CANCEL_RATE_WINDOW_SECONDS | 60 | Rate limit window for cancellation |
ORDER_REFUND_REQUEST_RATE_LIMIT | 5 | Rate limit for refund request submissions |
ORDER_REFUND_REQUEST_RATE_WINDOW_SECONDS | 60 | Rate limit window for refund requests |
ORDER_ADMIN_OPERATION_RATE_LIMIT | 120 | Rate limit for admin order operations |
ORDER_ADMIN_RATE_WINDOW_SECONDS | 60 | Rate limit window for admin operations |
ORDER_HISTORY_CACHE_TTL_SECONDS | 120 | Cache TTL for order history in seconds |
ORDER_ADMIN_CACHE_TTL_SECONDS | 60 | Cache TTL for admin order views in seconds |
ORDER_AUTO_CANCEL_MINUTES | 30 | Minutes before unpaid orders are auto-cancelled |
ORDER_PAYMENT_RETRY_MAX_ATTEMPTS | 3 | Maximum payment retry attempts |
OUTBOX_RETENTION_DAYS | 7 | Days to retain completed outbox events |
OUTBOX_FAILED_RETENTION_DAYS | 30 | Days to retain failed outbox events |
OUTBOX_CLEANUP_ENABLED | true | Enable outbox cleanup job |
OUTBOX_CLEANUP_CRON | 0 3 * * * | Cron schedule for outbox cleanup |
ORDERS_DISPATCH_CRON | * * * * * | Cron schedule for orders dispatch |
ORDERS_FAILED_MONITOR_CRON | */5 * * * * | Cron schedule for failed order monitoring |
OUTBOX_CLEANUP_DLQ_THRESHOLD | 100 | DLQ threshold for outbox cleanup alerts |
DLQ_WARNING_THRESHOLD | 50 | Warning threshold for failed jobs |
OUTBOX_BATCH_SIZE | 300 | Batch size for outbox processing |
OUTBOX_PENDING_PREVIEW_LIMIT | 10 | Preview limit for pending outbox events |
RETRY_BASE_DELAY_MS | 2000 | Base delay for retry backoff in milliseconds |
RETRY_MAX_DELAY_MS | 120000 | Maximum retry delay in milliseconds |
PAYMENT_RETRY_DELAY_ATTEMPT_1_MS | 60000 | Delay before first payment retry |
PAYMENT_RETRY_DELAY_ATTEMPT_2_MS | 300000 | Delay before second payment retry |
PAYMENT_RETRY_DELAY_ATTEMPT_3_MS | 900000 | Delay before third payment retry |
WORKER_ORDERS_CONCURRENCY | 20 | Worker concurrency for orders queue |
WORKER_ORDERS_MAINTENANCE_CONCURRENCY | 8 | Worker concurrency for maintenance queue |
Time fields in this module are stored as timezone-aware values and should be handled as ISO-8601 instants by API consumers.
See Also
- Feature Guide: See Order - Feature List Section 6 (State Models) for order lifecycle diagram.
- API Reference: See Order - API & Integration Guide Section 7 (Endpoint Reference + Payload Cheatsheet) for API contracts.