关于 order-management-system
这项技能为电商平台规划订单管理系统,面向商家和平台开发者,涵盖履约路由、缺货订单、拆分发货及审计记录。
主要功能
- 01多地点订单路由
- 02拆分发货处理
- 03缺货订单工作流
- 04订单变更审计记录
- 05平台配置指南
适用场景
- 01在仓库与 3PL 间路由订单
- 02先发有货商品并处理缺货商品
- 03构建自定义订单处理流程
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ finsilabs/ awesome-ecommerce-skills --skill order-management-system安装后在 Claude Code 中输入/order-management-system确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
tile.jsonevals/backorder-management-and-inventory-reple/criteria.jsontask.mdevals/multi-source-fulfillment-routing-and-pla/criteria.jsontask.mdevals/order-state-machine-and-audit-trail/criteria.jsontask.md详细介绍
订单管理系统
概述
订单管理系统(OMS)负责处理从下单到配送的完整订单生命周期:将订单路由到合适的履约来源(自有仓库、3PL 或代发货供应商)、在商品必须从多个地点发货时拆分订单、处理延期交货,并维护完整的审计跟踪。对于大多数商家来说,平台原生功能加上配送应用就能满足 80–90% 的 OMS 需求。当你拥有多个履约地点、复杂的路由规则,或正在为其他品牌构建平台时,才有必要使用定制 OMS。
何时使用此技能
- 当订单量已超出单仓库工作流的承载范围,需要多地点路由时
- 当包含有库存和缺货商品的订单需要分开配送,且不能因此阻碍履约时
- 当需要将多个履约来源(自有仓库、3PL、代发货供应商)整合到统一路由引擎中时
- 当为支持高订单量的新平台构建核心订单处理流水线时
- 当需要记录每次订单状态变更的完整审计跟踪,以供客户服务和财务部门使用时
核心说明
步骤 1:确定你的平台并选择合适的 OMS 方案
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 单仓库,Shopify | Shopify + ShipStation | ShipStation 原生处理订单管理、标签创建和追踪 |
| 多地点,Shopify | Shopify Locations + ShipStation 或 Shopify Fulfillment Network | Shopify 支持最多 10 个地点;ShipStation 根据规则将订单路由到合适的地点 |
| 3PL 集成 | ShipBob、Whiplash 或 Flexport + 你平台的应用 | 每家 3PL 都提供适用于 Shopify、WooCommerce 和 BigCommerce 的原生应用 |
| 复杂路由 + 延期交货 | Skubana(Extensiv)、Linnworks 或 ShipHero | 这些专用 OMS 工具可处理多仓库路由、延期交货队列和拆分配送 |
| 定制 / 无头架构 | 构建 OMS 状态机 + 集成 Shippo/EasyPost 以创建标签 | 全面掌控路由规则、状态转换和审计跟踪 |
步骤 2:设置多地点订单路由
Shopify
Shopify Locations(标准方案最多支持 10 个地点):
- 前往 Settings → Locations → Add location,为每个仓库或履约中心添加地点
- 在 Settings → Shipping and delivery → Fulfill orders from 中设置履约优先级:
- Shopify 会根据你的优先级规则,自动将订单路由到距离客户最近且有库存的地点
- 为每个商品变体设置哪些地点有该商品库存:前往 Products → [Product] → Inventory → Check each location's stock level
- 下单后,Shopify 会根据你的优先级规则自动选择最合适的履约地点
对于 3PL 集成:
- 安装 3PL 的原生 Shopify 应用(ShipBob、Whiplash、Flexport 均提供 Shopify 应用)
- 在应用设置中配置哪些商品由 3PL 履约,哪些由你自己的仓库履约
- 3PL 应用会在 Shopify 中创建一个额外的“地点”,并自动接收订单通知
对于拆分配送:
- 当订单从多个地点发货时,Shopify 会自动创建单独的履约记录
- 每个履约记录都有自己的追踪号码,并会分别向客户发送配送通知
WooCommerce
使用 ATUM Inventory Management:
- 安装 ATUM Inventory Management(免费/高级版,WordPress.org)
- ATUM 会为 WooCommerce 添加多地点库存追踪功能
- 在 ATUM → Settings → Multi-inventory 中配置履约优先级
- 系统会根据你的优先级规则,将订单路由到有库存的地点
对于 3PL 集成:
- ShipBob 提供 WooCommerce 插件;安装该插件并配置哪些商品从 ShipBob 发货
- ShipStation 的 WooCommerce 插件可连接多个承运商和仓库;在 ShipStation → Automation → Rules 中配置路由规则
BigCommerce
- 前往 Inventory → Locations 添加多个履约地点(Plus 及以上版本可用)
- 为每个产品设置各地点的库存水平
- BigCommerce 会根据你的设置,将订单分配到距离客户最近且有库存的地点
- 如需对接 3PL:ShipBob、Whiplash 和 ShipStation 均可通过 App Marketplace 与 BigCommerce 原生集成
步骤 3:处理延期交货
当客户下单购买缺货商品时,就会产生延期交货。客户仍然需要该商品;你需要在库存到货后完成履约。
Shopify
启用延期交货:
- 前往 Products → [Product] → Variants → [Variant]
- 设置库存跟踪:勾选“缺货时继续销售”——即使库存 = 0,也允许客户下单
- 信息透明:库存为 0 时,在产品页面显示“2–3 周内发货”的消息
沟通延期交货信息:
- 产品发生延期交货时,Shopify 的标准订单确认邮件不会自动标记这一情况
- 使用 Klaviyo 或 Shopify Email 创建触发器:当订单中的某个行项目数量 > 可用库存时 → 发送一封包含预计补货日期的“延期交货”邮件
履行延期交货订单:
- 库存到货时(收到货件后):在 Shopify 中手动履行延期交货订单 → Orders → 按“Unfulfilled”筛选,并按下单日期排序
- 如需自动履行延期交货订单:使用 Shopify Flow(Plus)或 webhook,在库存补充时触发履约
WooCommerce
- 前往 WooCommerce → Settings → Products → Inventory
- 在全局层级启用“允许延期交货”,或针对单个产品设置:Products → [Product] → Inventory → Allow Backorders
- 选项:“不允许”“允许,但通知客户”“允许,且不通知客户”
- 建议选择“允许,但通知客户”——WooCommerce 会添加“延期交货”徽标,并在结账时通知客户
- 根据付款流程,延期交货订单会以“On Hold”或“Processing”状态显示在 WooCommerce → Orders 中
BigCommerce
- 前往 Products → [Product] → Inventory
- 启用“允许购买缺货商品”——库存 = 0 时,BigCommerce 会自动将产品显示为“可预购”
- 在 Store Setup → Store Settings → Product Settings 中设置“延期交货”消息文本
步骤 4:维护订单审计跟踪
每次订单状态变更都应记录操作人和变更时间。这对客户服务和欺诈调查至关重要。
Shopify
- Shopify 会自动在 Orders → [Order] → Timeline 中记录所有订单状态变更
- Timeline 会显示每个事件:付款确认、创建履约、购买运输标签、更新跟踪信息等
- 对于任何手动操作,可在 Timeline 中添加备注(仅工作人员可见)
WooCommerce
- WooCommerce 会在每个订单的 Order Notes 部分记录订单备注
- 系统会自动记录状态变更(“订单状态从 Processing 更改为 Completed”)
- 如需更全面的审计日志:安装 WooCommerce Order Status Manager 或 Activity Log 插件
BigCommerce
- BigCommerce 会在每个订单的 Order Activity 部分记录订单状态变更
- 活动日志会显示所有状态变更、添加的备注和系统操作
自定义 / Headless — 带事件日志的订单状态机
// 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
}
}
最佳实践
- 先使用专用的 OMS,再考虑自定义开发 — Skubana/Extensiv($500+/月)或 Linnworks 可可靠地处理多仓路由、缺货待发和拆分发货;只有这些工具无法满足特定需求时,才应开始自定义开发
- 将订单和履约作为独立实体处理 — 订单是与客户之间的财务合同;履约指实物发货;一个订单可以产生多次履约
- 异步安排履约计划 — 不要在结账时同步路由订单;付款确认后立即将路由任务加入队列,并在后台工作进程中处理
- 绝不默默丢弃缺货待发的商品行 — 始终通知客户,并提供等待或取消的选项;如果客户几周后才发现缺货待发,默不作声会损害信任
- 针对在「等待履约」状态停留 24 小时以上的订单发出警报 — 设置每日警报,检查尚未进入履约流程的订单;这通常意味着路由错误或系统问题
常见陷阱
| 问题 | 解决方案 |
|---|---|
| 订单意外拆分为多个包裹发货 | 如果订单将从多个地点发货,请在结账时提前告知客户;分别显示每个包裹的预计送达时间 |
| 补货后缺货待发订单仍未履约 | 设置自动触发器:当库存补充量超过缺货待发数量时,为最早的待处理缺货订单触发履约(FIFO) |
| 部分取消导致订单状态异常 | 实现部分取消功能 — 仅取消尚未拣货的商品行;为已取消的商品行退款;更新订单总额 |
| Shopify 显示「部分履约」,但客户以为整笔订单都会发货 | 每次发货时发送清晰的电子邮件,说明该包裹中的商品以及后续将发出的剩余商品 |
相关技能
- @order-fulfillment-workflow
- @returns-management
- @multi-channel-selling
- @dropshipping-integration
- @demand-forecasting
评论
支持 Markdown