order-management-system

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Order Management System

订单管理系统

Overview

概述

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.
订单管理系统(OMS)负责处理从下单到交付的完整订单生命周期:将订单分配至合适的履约渠道(自有仓库、3PL或代发货供应商),当商品需从多个地点发货时拆分订单,处理缺货订单,并维护完整的审计追踪记录。对于大多数商家而言,平台原生功能搭配物流应用即可满足80%-90%的OMS需求。当您拥有多个履约地点、复杂的分配规则,或是为其他品牌搭建平台时,定制化OMS则是必要选择。

When to Use This Skill

何时使用该方案

  • When your order volume has outgrown a single-warehouse workflow and you need multi-location routing
  • When orders that mix in-stock and out-of-stock items need to ship in separate shipments without blocking fulfillment
  • When integrating multiple fulfillment sources (own warehouse, 3PLs, dropship suppliers) into a unified routing engine
  • When building the core order processing pipeline for a new platform that will support high order volume
  • When you need a complete audit trail of every order state change for customer service and finance
  • 当您的订单量超出单仓库工作流,需要多地点订单分配时
  • 当订单同时包含有货和缺货商品,需分开发货且不阻碍履约时
  • 当需要将多个履约渠道(自有仓库、3PL、代发货供应商)整合至统一分配引擎时
  • 当为新平台搭建核心订单处理流程以支持高订单量时
  • 当需要完整的订单状态变更审计追踪记录,用于客服和财务工作时

Core Instructions

核心操作指南

Step 1: Determine your platform and choose the right OMS approach

步骤1:确定平台并选择合适的OMS方案

ScenarioRecommended ApproachWhy
Single warehouse, ShopifyShopify + ShipStationShipStation handles order management, label creation, and tracking natively
Multi-location, ShopifyShopify Locations + ShipStation or Shopify Fulfillment NetworkShopify supports up to 10 locations; ShipStation routes to the right location based on rules
3PL integrationShipBob, Whiplash, or Flexport + your platform's appEach 3PL has native apps for Shopify, WooCommerce, and BigCommerce
Complex routing + backordersSkubana (Extensiv), Linnworks, or ShipHeroThese purpose-built OMS tools handle multi-warehouse routing, backorder queues, and split shipments
Custom / HeadlessBuild an OMS state machine + integrate Shippo/EasyPost for labelsFull control over routing rules, state transitions, and audit trail
场景推荐方案原因
单仓库,ShopifyShopify + ShipStationShipStation原生支持订单管理、面单创建和物流追踪
多地点,ShopifyShopify Locations + ShipStation 或 Shopify Fulfillment NetworkShopify标准版支持最多10个地点;ShipStation可根据规则将订单分配至合适地点
3PL集成ShipBob、Whiplash或Flexport + 平台对应应用每个3PL都有适用于Shopify、WooCommerce和BigCommerce的原生应用
复杂分配规则 + 缺货订单Skubana(Extensiv)、Linnworks或ShipHero这些专用OMS工具可处理多仓库分配、缺货订单队列和拆分发货
定制化 / 无头架构搭建OMS状态机 + 集成Shippo/EasyPost生成面单可完全控制分配规则、状态转换和审计追踪记录

Step 2: Set up multi-location order routing

步骤2:设置多地点订单分配

Shopify

Shopify

Shopify Locations (up to 10 locations on standard plans):
  1. Go to Settings → Locations → Add location for each warehouse or fulfillment center
  2. In Settings → Shipping and delivery → Fulfill orders from, set your fulfillment priority:
    • Shopify will automatically route orders to the location closest to the customer with available stock
  3. For each product variant, set which locations stock that item: go to Products → [Product] → Inventory → Check each location's stock level
  4. When an order is placed, Shopify selects the optimal fulfillment location automatically based on your priority rules
For 3PL integration:
  • Install the 3PL's native Shopify app (ShipBob, Whiplash, Flexport all have Shopify apps)
  • Configure which products are fulfilled by the 3PL vs. your own warehouse in the app settings
  • The 3PL app creates an additional "location" in Shopify and receives order notifications automatically
For split shipments:
  • Shopify automatically creates separate fulfillments when an order ships from multiple locations
  • Each fulfillment gets its own tracking number and triggers its own shipping notification to the customer
Shopify Locations(标准版最多支持10个地点):
  1. 进入设置 → 地点 → 添加地点,为每个仓库或履约中心添加信息
  2. 设置 → 配送和交付 → 从以下地点履约订单中设置履约优先级:
    • Shopify会自动将订单分配给距离客户最近且有库存的地点
  3. 为每个商品变体设置库存地点:进入产品 → [对应产品] → 库存 → 勾选各地点的库存水平
  4. 下单后,Shopify会根据您设置的优先级规则自动选择最优履约地点
3PL集成:
  • 安装3PL的Shopify原生应用(ShipBob、Whiplash、Flexport均有Shopify应用)
  • 在应用设置中配置哪些商品由3PL履约,哪些由自有仓库履约
  • 3PL应用会在Shopify中创建一个额外的「地点」,并自动接收订单通知
拆分发货:
  • 当订单从多个地点发货时,Shopify会自动创建独立的履约记录
  • 每个履约记录会生成单独的追踪号,并向客户发送对应的发货通知

WooCommerce

WooCommerce

Using ATUM Inventory Management:
  1. Install ATUM Inventory Management (free/premium, WordPress.org)
  2. ATUM adds multi-location inventory tracking to WooCommerce
  3. Configure fulfillment priority in ATUM → Settings → Multi-inventory
  4. Orders are routed to the location with available stock based on your priority rules
For 3PL integration:
  • ShipBob has a WooCommerce plugin; install it and configure which products ship from ShipBob
  • ShipStation's WooCommerce plugin connects to multiple carriers and warehouses; configure routing rules in ShipStation → Automation → Rules
使用ATUM Inventory Management:
  1. 安装ATUM Inventory Management(免费/付费版,可从WordPress.org获取)
  2. ATUM为WooCommerce添加多地点库存追踪功能
  3. 在ATUM → 设置 → 多库存中配置履约优先级
  4. 系统会根据您设置的优先级规则,将订单分配至有库存的地点
3PL集成:
  • ShipBob有WooCommerce插件;安装后配置哪些商品由ShipBob发货
  • ShipStation的WooCommerce插件可连接多个承运商和仓库;在ShipStation → 自动化 → 规则中配置分配规则

BigCommerce

BigCommerce

  1. Go to Inventory → Locations to add multiple fulfillment locations (available on Plus and above)
  2. Set inventory levels per location for each product
  3. BigCommerce routes orders to the location with stock closest to the customer based on your settings
  4. For 3PL integration: ShipBob, Whiplash, and ShipStation all have native BigCommerce integrations via the App Marketplace
  1. 进入库存 → 地点添加多个履约地点(Plus及以上版本可用)
  2. 为每个商品设置各地点的库存水平
  3. BigCommerce会根据您的设置,将订单分配至距离客户最近且有库存的地点
  4. 3PL集成:ShipBob、Whiplash和ShipStation均通过应用市场提供BigCommerce原生集成

Step 3: Handle backorders

步骤3:处理缺货订单

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.
缺货订单指客户下单时商品无库存,但客户仍希望在补货后收到商品的订单。

Shopify

Shopify

Enable backorders:
  1. Go to Products → [Product] → Variants → [Variant]
  2. Set inventory tracking: check "Continue selling when out of stock" — this allows orders to come in even when stock = 0
  3. Be transparent: show a "Ships in 2–3 weeks" message on the product page when stock is 0
Communicate backorders:
  • When a product is backordered, Shopify's standard order confirmation doesn't flag this automatically
  • Use Klaviyo or Shopify Email to create a trigger: when order has a line item with quantity > available stock → send a "Backordered" email with the estimated restock date
Fulfilling backordered orders:
  • When stock arrives (you receive a shipment): manually fulfill the backordered orders in Shopify → Orders → filter by "Unfulfilled" and sort by order date
  • For automatic backorder fulfillment: use Shopify Flow (Plus) or a webhook to trigger fulfillment when inventory is replenished
启用缺货订单功能:
  1. 进入产品 → [对应产品] → 变体 → [对应变体]
  2. 设置库存追踪:勾选「库存为0时继续销售」—— 即使库存为0也可接收订单
  3. 保持透明:当库存为0时,在商品页面显示「2-3周后发货」的提示
缺货订单通知:
  • 当商品缺货时,Shopify的标准订单确认邮件不会自动标记该状态
  • 使用KlaviyoShopify Email创建触发规则:当订单中存在商品数量大于可用库存的订单项时,发送包含预计补货日期的「缺货订单」邮件
履约缺货订单:
  • 补货后(收到库存):在Shopify → 订单中手动履约缺货订单,筛选「未履约」并按下单日期排序
  • 自动履约缺货订单:使用Shopify Flow(Plus版)或webhook,在库存补充时触发履约

WooCommerce

WooCommerce

  1. Go to WooCommerce → Settings → Products → Inventory
  2. Enable "Allow backorders" at the global level, or set per product: Products → [Product] → Inventory → Allow Backorders
  3. Options: "Do not allow", "Allow but notify customer", "Allow without notification"
  4. Recommend: "Allow but notify customer" — WooCommerce adds a "On backorder" badge and notifies the customer at checkout
  5. Backordered orders appear in WooCommerce → Orders with status "On Hold" or "Processing" depending on your payment flow
  1. 进入WooCommerce → 设置 → 产品 → 库存
  2. 在全局层面启用「允许缺货订单」,或按商品设置:产品 → [对应产品] → 库存 → 允许缺货订单
  3. 选项:「不允许」、「允许但通知客户」、「允许不通知客户」
  4. 推荐选择「允许但通知客户」—— WooCommerce会添加「缺货预订」标识,并在结账时通知客户
  5. 缺货订单会显示在WooCommerce → 订单中,状态为「待处理」或「处理中」,具体取决于支付流程

BigCommerce

BigCommerce

  1. Go to Products → [Product] → Inventory
  2. Enable "Allow Purchasing Out of Stock" — BigCommerce shows the product as "Available for Pre-Order" automatically when stock = 0
  3. Set "Back Ordering" message text in Store Setup → Store Settings → Product Settings
  1. 进入产品 → [对应产品] → 库存
  2. 启用「允许库存为0时购买」—— 当库存为0时,BigCommerce会自动将商品标记为「可预订」
  3. 在店铺设置 → 店铺设置 → 产品设置中设置「缺货订单」提示文本

Step 4: Maintain an order audit trail

步骤4:维护订单审计追踪记录

Every order status change should be logged with who made the change and when. This is essential for customer service and fraud investigation.
所有订单状态变更都应记录变更人及变更时间,这对客服和欺诈调查至关重要。

Shopify

Shopify

  • Shopify automatically logs all order status changes in Orders → [Order] → Timeline
  • The Timeline shows every event: payment confirmed, fulfillment created, shipping label purchased, tracking updated, etc.
  • Add manual notes to the Timeline (visible to staff only) for any manual actions taken
  • Shopify会自动在订单 → [对应订单] → 时间线中记录所有订单状态变更
  • 时间线会显示所有事件:支付确认、履约创建、面单购买、追踪信息更新等
  • 可在时间线中添加仅员工可见的手动备注,记录所有手动操作

WooCommerce

WooCommerce

  • WooCommerce logs order notes in each order's Order Notes section
  • Status changes are logged automatically ("Order status changed from Processing to Completed")
  • For more comprehensive audit logging: install WooCommerce Order Status Manager or Activity Log plugin
  • WooCommerce会在每个订单的订单备注部分记录订单备注
  • 状态变更会自动记录(如「订单状态从处理中变更为已完成」)
  • 如需更全面的审计日志:安装WooCommerce Order Status ManagerActivity Log插件

BigCommerce

BigCommerce

  • BigCommerce logs order status changes in the Order Activity section of each order
  • The activity log shows all status changes, notes added, and system actions
  • BigCommerce会在每个订单的订单活动部分记录订单状态变更
  • 活动日志会显示所有状态变更、添加的备注和系统操作

Custom / Headless — order state machine with event log

定制化 / 无头架构 —— 带事件日志的订单状态机

typescript
// 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
  }
}
typescript
// 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
  }
}

Best Practices

最佳实践

  • Use a purpose-built OMS before building custom — Skubana/Extensiv ($500+/month) or Linnworks handles multi-warehouse routing, backorders, and split shipments with proven reliability; custom development should only start when these tools can't meet your specific needs
  • Keep orders and fulfillments as separate entities — an order is a financial contract with the customer; fulfillments are physical shipments; one order can generate multiple fulfillments
  • Queue fulfillment planning asynchronously — don't route orders synchronously during checkout; enqueue routing immediately after payment confirmation and process in a background worker
  • Never silently drop backordered lines — always notify the customer and give them the option to wait or cancel; silent backorders erode trust when the customer discovers weeks later
  • Alert on orders stuck in "awaiting fulfillment" for 24+ hours — set up a daily alert for orders that haven't moved to fulfillment; these usually indicate a routing error or system issue
  • 优先使用专用OMS而非定制开发 —— Skubana/Extensiv(每月500美元起)或Linnworks可可靠处理多仓库分配、缺货订单和拆分发货;只有当这些工具无法满足特定需求时,才考虑定制开发
  • 将订单与履约记录分开管理 —— 订单是与客户的财务契约;履约记录是实际发货记录;一个订单可生成多个履约记录
  • 异步处理履约规划 —— 不要在结账时同步分配订单;支付确认后立即将分配任务加入队列,由后台worker处理
  • 切勿静默处理缺货订单项 —— 务必通知客户,并提供等待或取消的选项;静默缺货订单会在客户数周后发现时损害信任
  • 对「等待履约」状态超过24小时的订单发出警报 —— 设置每日警报,提醒未进入履约流程的订单;这类订单通常意味着分配错误或系统问题

Common Pitfalls

常见问题及解决方案

ProblemSolution
Order splits into multiple shipments unexpectedlyPre-warn customers at checkout if an order will ship from multiple locations; show estimated delivery per shipment separately
Backorder never fulfilled after stock arrivesSet 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 stateImplement 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 comingSend a clear email explaining each shipment as it ships, with the items in that specific shipment and the remaining items to follow
问题解决方案
订单意外拆分为多个发货结账前提前告知客户订单将从多个地点发货;分别显示每个发货的预计送达时间
补货后缺货订单未履约设置自动触发规则:当库存补充量超过缺货订单数量时,触发最早的待处理缺货订单履约(先进先出)
部分取消导致订单状态异常实现部分取消功能 —— 仅取消未拣货的订单项;为取消的订单项退款;更新订单总额
Shopify显示「部分履约」但客户认为是完整发货每次发货时发送清晰的邮件,说明该次发货的商品及剩余待发货商品

Related Skills

相关方案

  • @order-fulfillment-workflow
  • @returns-management
  • @multi-channel-selling
  • @dropshipping-integration
  • @demand-forecasting
  • @order-fulfillment-workflow
  • @returns-management
  • @multi-channel-selling
  • @dropshipping-integration
  • @demand-forecasting