com um clique
order-management-system
// Design an order management system that routes orders to the right warehouse, handles split shipments, and manages backorders gracefully
// Design an order management system that routes orders to the right warehouse, handles split shipments, and manages backorders gracefully
| name | order-management-system |
| description | Design an order management system that routes orders to the right warehouse, handles split shipments, and manages backorders gracefully |
| category | business-operations |
| risk | critical |
| source | curated |
| date_added | 2026-03-12 |
| tags | ["OMS","order-management","split-orders","backorders","distributed-fulfillment","fulfillment-routing"] |
| triggers | ["order management system","OMS","split orders","backorder handling","fulfillment routing","distributed fulfillment","order routing"] |
| tools | ["claude-code","cursor","gemini-cli","copilot","codex-cli","kiro","opencode"] |
| platforms | ["shopify","woocommerce","bigcommerce","custom"] |
| difficulty | advanced |
An Order Management System (OMS) handles the full order lifecycle from placement to delivery: routing orders to the right fulfillment source (own warehouse, 3PL, or dropship supplier), splitting orders when items must ship from multiple locations, handling backorders, and maintaining a complete audit trail. For most merchants, platform-native features plus a shipping app cover 80–90% of OMS needs. A custom OMS is warranted when you have multiple fulfillment locations, complex routing rules, or are building a platform for other brands.
| Scenario | Recommended Approach | Why |
|---|---|---|
| Single warehouse, Shopify | Shopify + ShipStation | ShipStation handles order management, label creation, and tracking natively |
| Multi-location, Shopify | Shopify Locations + ShipStation or Shopify Fulfillment Network | Shopify supports up to 10 locations; ShipStation routes to the right location based on rules |
| 3PL integration | ShipBob, Whiplash, or Flexport + your platform's app | Each 3PL has native apps for Shopify, WooCommerce, and BigCommerce |
| Complex routing + backorders | Skubana (Extensiv), Linnworks, or ShipHero | These purpose-built OMS tools handle multi-warehouse routing, backorder queues, and split shipments |
| Custom / Headless | Build an OMS state machine + integrate Shippo/EasyPost for labels | Full control over routing rules, state transitions, and audit trail |
Shopify Locations (up to 10 locations on standard plans):
For 3PL integration:
For split shipments:
Using ATUM Inventory Management:
For 3PL integration:
A backorder occurs when an order is placed for an item that is out of stock. The customer still wants the item; you need to fulfill it when stock arrives.
Enable backorders:
Communicate backorders:
Fulfilling backordered orders:
Every order status change should be logged with who made the change and when. This is essential for customer service and fraud investigation.
// Order status state machine with full audit trail
type OrderStatus =
| 'pending'
| 'payment_processing'
| 'paid'
| 'awaiting_fulfillment'
| 'partially_fulfilled'
| 'fulfilled'
| 'delivered'
| 'cancelled'
| 'refunded';
const VALID_TRANSITIONS: Partial<Record<OrderStatus, OrderStatus[]>> = {
pending: ['payment_processing', 'cancelled'],
payment_processing: ['paid', 'cancelled'],
paid: ['awaiting_fulfillment', 'cancelled'],
awaiting_fulfillment: ['partially_fulfilled', 'fulfilled', 'cancelled'],
partially_fulfilled: ['fulfilled'],
fulfilled: ['delivered', 'refunded'],
delivered: ['refunded'],
};
async function transitionOrder(params: {
orderId: string;
newStatus: OrderStatus;
actorId: string;
note?: string;
}): Promise<void> {
const order = await db.orders.findById(params.orderId);
const allowed = VALID_TRANSITIONS[order.status] ?? [];
if (!allowed.includes(params.newStatus)) {
throw new Error(`Invalid transition: ${order.status} → ${params.newStatus}`);
}
await db.transaction(async tx => {
await tx.orders.update(params.orderId, { status: params.newStatus, updated_at: new Date() });
// Every transition is recorded — this IS the audit trail
await tx.orderEvents.insert({
order_id: params.orderId,
from_status: order.status,
to_status: params.newStatus,
actor_id: params.actorId,
note: params.note ?? null,
occurred_at: new Date(),
});
});
}
// Route an order to the right fulfillment source
async function routeOrder(orderId: string): Promise<void> {
const order = await db.orders.findById(orderId);
const lines = await db.orderLines.findByOrderId(orderId);
for (const line of lines) {
// Check own warehouse first
const warehouseStock = await db.inventory.findAvailable(line.sku, line.quantity);
if (warehouseStock) {
await db.fulfillmentLines.insert({
order_id: orderId,
order_line_id: line.id,
source: 'warehouse',
source_id: warehouseStock.location_id,
status: 'pending',
});
continue;
}
// Fall back to dropship supplier
const supplier = await db.supplierProducts.findBestSupplier(line.product_id, line.quantity);
if (supplier) {
await db.fulfillmentLines.insert({
order_id: orderId,
order_line_id: line.id,
source: 'dropship',
source_id: supplier.supplier_id,
status: 'pending',
});
continue;
}
// No source available — create a backorder
await db.backorders.insert({
order_id: orderId,
order_line_id: line.id,
product_id: line.product_id,
quantity: line.quantity,
status: 'pending',
});
// Notify customer about the backorder
}
}
| Problem | Solution |
|---|---|
| Order splits into multiple shipments unexpectedly | Pre-warn customers at checkout if an order will ship from multiple locations; show estimated delivery per shipment separately |
| Backorder never fulfilled after stock arrives | Set up an automatic trigger: when inventory is replenished above the backorder quantity, trigger fulfillment for the oldest pending backorder (FIFO) |
| Partial cancellation leaves the order in a broken state | Implement partial cancellation — cancel only lines that haven't been picked; issue a refund for cancelled lines; update the order total |
| Shopify shows "partially fulfilled" but customer thinks full shipment is coming | Send a clear email explaining each shipment as it ships, with the items in that specific shipment and the remaining items to follow |
Manage supplier invoices and vendor payments with automated receipt matching, payment scheduling, early discount optimization, and reconciliation workflows
Enable wholesale and B2B sales with company accounts, custom catalogs, quote workflows, purchase orders, and net payment terms
Predict future inventory needs using historical sales data, seasonal trends, and reorder points to prevent stockouts and overstock
Launch a multi-vendor marketplace with seller onboarding, commission rules, automated payouts via Stripe Connect, and vendor dashboards
Control which products appear first in collections using automated ranking rules, manual overrides, and performance-based sorting algorithms
Sync your catalog and inventory across your own site, Amazon, eBay, and wholesale channels to sell everywhere from one system