---
title: 'How to Build an Order Management System in Airtable'
description: 'Build a complete Airtable order management system — order intake, line items, fulfillment tracking, shipping status, customer emails, and inventory updates.'
canonical_url: 'https://www.business-automated.com/tutorials/airtable-order-management-system'
md_url: 'https://www.business-automated.com/tutorials/airtable-order-management-system.md'
last_updated: 2026-06-11
---

Order management is where most operations either get organized or quietly fall apart. Orders arrive by web form, email, and phone; someone retypes them into a spreadsheet; stock counts drift from reality; customers email asking "where's my order?" because nobody told them it shipped. [Airtable](/airtable-consultant) fixes all of this — if you build the data model correctly.

This guide is the complete Airtable order management build: schema with linked records, order intake forms (and their one big limitation), fulfillment tracking, shipping integrations, customer notification emails, purchase orders with PDF generation, and inventory that updates itself from order activity.

## When Airtable Wins for Orders

Be honest about the fit before you build. Airtable beats dedicated order management software when:

- You process **up to a few thousand orders a month** — wholesale, B2B, made-to-order, subscription boxes, niche ecommerce.
- Your order workflow is **custom** — approval steps, production stages, partial shipments, mixed sales channels — and off-the-shelf OMS tools force you into their flow.
- You want orders connected to **everything else** — CRM, purchasing, invoicing, production — in one base.
- Your "system" today is a spreadsheet plus a shared inbox, and you need structure more than scale.

A dedicated OMS or ERP wins when you need barcode-driven warehouse picking, multi-location stock allocation, carrier rate shopping at volume, or accounting-grade audit trails. More on those thresholds at the end.

## Step 1: Schema — Five Tables, Not Two

The most common mistake in Airtable for orders is two tables: Orders and Products, with products multi-linked straight onto the order. That model cannot store quantity or price per product on an order. The correct model uses a junction table.

### Core tables

| Table | Purpose |
| --- | --- |
| **Customers** | Who's buying — contact details, shipping address |
| **Products** | What you sell — SKU, price, stock math |
| **Orders** | One record per order — status, totals, shipping |
| **Order Line Items** | One record per product-per-order — the junction table |
| **Invoices** | Billing records linked to orders |
| **Purchase Orders** + **PO Line Items** | Restocking from suppliers |

The Order Line Items table is the heart of the system. Each record links to exactly one Order and one Product and carries quantity and price. If the junction-table pattern is new to you, read our [guide to junction tables and many-to-many relationships](/tutorials/airtable-junction-tables-many-to-many) first — everything else in this build depends on it.

### Orders fields

| Field | Type | Purpose |
| --- | --- | --- |
| Order ID | Formula | `"ORD-" & RIGHT("0000" & {Auto Number}, 5)` |
| Customer | Linked record (Customers, single) | Who ordered |
| Line Items | Linked records (Order Line Items) | What they ordered |
| Status | Single select | New → Confirmed → In Fulfillment → Shipped → Delivered / Cancelled |
| Order Total | Rollup | SUM of `{Line Total}` from Line Items |
| Order Date | Created time | When it came in |
| Channel | Single select | Web Form / Shopify / Email / Phone / Wholesale |
| Payment Status | Single select | Unpaid / Paid / Refunded |
| Shipping Address | Long text | Snapshot at order time |
| Carrier | Single select | USPS / UPS / FedEx / DHL |
| Tracking Number | Single line text | Filled at shipment |
| Shipped Date | Date | Filled by automation |
| Customer Email | Lookup (from Customers) | For notification automations |
| Status Updated | Last modified time (Status only) | For stuck-order reports |

### Order Line Items fields

| Field | Type | Purpose |
| --- | --- | --- |
| Name | Formula | `{Order ID} & " — " & {Product Name}` |
| Order | Linked record (Orders, single) | Parent order |
| Product | Linked record (Products, single) | What |
| Quantity | Number | How many |
| Unit Price | Currency | Copied from Product at order time |
| Line Total | Formula | `{Quantity} * {Unit Price}` |

Note the deliberate choice on Unit Price: it's a real currency field, not a lookup. If you look up the live product price, every past order silently changes when you update your price list. Copy the price in (by hand or via automation) so historical orders stay historically accurate.

### Products fields

| Field | Type | Purpose |
| --- | --- | --- |
| Product Name | Single line text | Primary field |
| SKU | Single line text | Unique identifier |
| Unit Price | Currency | Current sell price |
| Starting Stock | Number | Stock at system go-live |
| Units Sold | Rollup | SUM of `{Quantity}` from Order Line Items |
| Units Received | Rollup | SUM of `{Quantity Received}` from PO Line Items |
| Current Stock | Formula | `{Starting Stock} + {Units Received} - {Units Sold}` |
| Reorder Point | Number | Threshold for restock alerts |
| Supplier | Linked record (Suppliers) | Default vendor |

## Step 2: Order Intake — Forms and Their One Big Limitation

How orders enter the system depends on your channel. Three patterns cover almost every business.

### Pattern A: The Airtable order form (and why it falls short)

Here's the limitation nobody discovers until they're mid-build: **a native Airtable form creates exactly one record**. It cannot create an Order plus three Line Item records in one submission. So a native Airtable order form works only for single-product orders — "book a workshop seat," "order one sample kit."

For multi-product carts, use **Fillout**. It connects natively to Airtable, lets customers add unlimited line items in one form, calculates the running total live, and on submit creates the Order record plus one linked Line Item record per product — exactly the schema from Step 1. miniExtensions does the same job natively; Cognito Forms can too, via its repeating sections plus a Make or Zapier step to split rows into line-item records. This is the single most important tool decision in the whole build; basics of forms are covered in our [Airtable forms guide](/tutorials/how-to-create-airtable-forms).

### Pattern B: Shopify (or any ecommerce platform) sync

If you sell through Shopify or WooCommerce, don't retype orders. A Make scenario or Zap triggers on each new paid order and:

1. **Finds or creates** the Customer record (match on email).
2. **Creates** the Order record with channel = "Shopify" and the shipping address snapshot.
3. **Creates one Line Item record per product** in the order, linked to the matching Product by SKU.

Airtable becomes your operations layer — fulfillment, purchasing, reporting — while Shopify stays the storefront. Two-way sync tools like SyncBase can push status and stock back the other way. See our [Make automation guide](/tutorials/automate-airtable-with-make-guide) for the scenario-building fundamentals, and our [ecommerce solutions page](/solutions/ecommerce) for what a full ecommerce back office looks like.

### Pattern C: Wholesale and email orders

For B2B orders arriving by email or phone, the ops team enters them via an Interface form, or a Make scenario watches a shared inbox and parses attachments into draft Order records that a human confirms. Drafts get Status = "New" and sit in a review view — never auto-confirm parsed orders.

## Step 3: Inventory That Updates Itself

The inventory rule that separates working systems from broken ones: **stock is calculated, never typed**.

The Products table fields from Step 1 do the work:

```airtable
{Starting Stock} + {Units Received} - {Units Sold}
```

- `Units Sold` is a rollup summing `{Quantity}` across that product's Order Line Items.
- `Units Received` is a rollup summing received quantities across PO Line Items.

Every order placed decrements available stock instantly; every purchase order received increments it. Nobody updates a number; the number is a fact derived from records. If rollups are unfamiliar, our [rollup fields guide](/tutorials/how-to-use-airtable-rollup-fields) covers the mechanics.

Two refinements worth adding:

- **Exclude cancelled orders.** Add a lookup of Order Status onto Line Items and set the Units Sold rollup to only count line items where the order isn't Cancelled — otherwise cancellations permanently eat your stock.
- **Low-stock alert.** Formula field `IF({Current Stock} <= {Reorder Point}, "🔴 Reorder", "🟢 OK")`, plus an automation that notifies purchasing (or auto-drafts a PO — Step 6) when it flips.

For the deeper version of this pattern — stock takes, adjustments, multi-location — see our [inventory tracking automation guide](/tutorials/automate-inventory-tracking-airtable) and the [inventory tracking solution](/solutions/inventory-tracking-automation) we build for clients.

## Step 4: Fulfillment Tracking — Status and Views

Fulfillment lives in the Status single select on Orders:

```text
New → Confirmed → In Fulfillment → Shipped → Delivered
                       ↓
                   Cancelled
```

Resist adding more stages. Each one needs a clear owner and a clear exit condition, or orders rot in ambiguous statuses.

Build these views on Orders:

- **Fulfillment Queue (Kanban)** — grouped by Status, filtered to exclude Delivered and Cancelled. The warehouse's working board; drag orders through the pipeline.
- **Ship Today (Grid)** — Status = "In Fulfillment", sorted oldest first. The pick-and-pack list.
- **Stuck Orders (Grid)** — `DATETIME_DIFF(NOW(), {Status Updated}, 'days') > 3` and not Delivered/Cancelled. Every order in this view is a customer about to email you.
- **Unpaid Shipped (Grid)** — Payment Status = "Unpaid" and Status = "Shipped" or later. For wholesale, this is your receivables early-warning view.
- **Orders Calendar** — by Shipped Date, for spotting volume crunches.

## Step 5: Customer Notifications and Status Automations

The cheapest customer-service win in this entire build: tell customers what's happening before they ask. Each automation uses the "When a record matches conditions" trigger watching the Status field.

### Order confirmation

1. **Trigger:** Order Status changes to "Confirmed."
2. **Action:** Send email to `{Customer Email}` (the lookup field) with order ID, line-item summary, and total.

### Shipping notification

1. **Trigger:** Status changes to "Shipped" **and** Tracking Number is not empty — the second condition stops emails firing before tracking exists.
2. **Action:** Send email with carrier, tracking number, and tracking link built by formula, e.g. for USPS: `"https://tools.usps.com/go/TrackConfirmAction?tLabels=" & {Tracking Number}`.

### Internal alerts

- New order over a value threshold → Slack message to the ops channel.
- Order stuck in "In Fulfillment" more than 3 days → daily digest to the fulfillment lead.
- Payment Status flips to "Paid" → notify fulfillment to release the order.

Send customer-facing emails from a connected Gmail or Outlook account so they come from your domain rather than Airtable's mailer. Mind your plan's automation quota too — runs are a hard monthly cap, and a busy order system burns them fast (more in the outgrowing section). Patterns and deliverability details are in our [email automation guide](/tutorials/airtable-email-automation-guide) and the broader [automation guide](/tutorials/airtable-automation-guide).

## Step 6: Shipping Integrations

Airtable won't print a shipping label, but Shippo and ShipStation will, and both connect through Make or Zapier.

**The Shippo pattern (lighter, per-label pricing):**

1. Order Status changes to "In Fulfillment" → Make scenario sends address and parcel details to Shippo.
2. Shippo purchases the label and returns label URL and tracking number.
3. Make writes both back to the Order, attaches the label PDF, and sets Status to "Shipped" — which fires the customer notification from Step 5 automatically.

**The ShipStation pattern (heavier, for real daily volume):** push confirmed orders into ShipStation, let the warehouse pick, pack, and rate-shop carriers there, then a webhook writes the tracking number back to Airtable when the label is created. ShipStation owns the dock; Airtable stays the system of record.

Either way, the goal is the same: tracking numbers appear on order records without anyone copy-pasting them.

## Step 7: Purchase Orders and PDF Generation

The other half of "airtable order management" is the orders *you* place. The schema mirrors the sales side:

| Field (Purchase Orders) | Type | Purpose |
| --- | --- | --- |
| PO Number | Formula | `"PO-" & RIGHT("0000" & {Auto Number}, 5)` |
| Supplier | Linked record (Suppliers) | Vendor |
| PO Line Items | Linked records | Products + quantities ordered |
| Status | Single select | Draft → Approved → Sent → Partially Received → Received |
| PO Total | Rollup | SUM of line totals |
| Expected Delivery | Date | For follow-up automations |
| PO PDF | Attachment | Generated document |

PO Line Items carry Quantity Ordered and **Quantity Received** as separate fields — suppliers short-ship constantly, and the Units Received rollup in Step 3 must sum what actually arrived, not what you asked for.

The workflow that makes this feel like a real Airtable purchase order system:

1. **Low stock triggers a draft.** When `{Current Stock}` drops below `{Reorder Point}`, an automation creates a Draft PO (or adds a line item to an existing draft for that supplier).
2. **A human approves.** Purchasing reviews the draft in an Interface and flips Status to "Approved." Don't automate spending money.
3. **Approval generates the PDF.** A tool like DocsAutomator or CraftMyPDF merges PO number, supplier details, and the line-item table into a branded PDF and saves it to the attachment field — full walkthrough in our [PDF generation guide](/tutorials/airtable-generate-pdfs-guide).
4. **The PDF emails itself.** The same automation sends it to the supplier contact and sets Status to "Sent."
5. **Receiving closes the loop.** Goods arrive, the team fills Quantity Received, stock levels update via rollup. Done.

### Invoices

For customer billing, the Invoices table links to Orders and either generates PDF invoices with the same tooling as POs, or — better for most businesses — pushes to real accounting software. We cover that pattern in [creating invoices in Xero from Airtable](/tutorials/creating-invoices-in-xero-with-airtable). Keep accounting truth in the accounting system; keep operational truth in Airtable.

## When You've Outgrown Airtable for Orders

We build these systems for a living, and we'll tell you plainly where the ceiling is.

**Record limits.** Plans cap records per base — 50,000 on Team, 125,000 on Business — and the line-items pattern multiplies records fast. A business doing 1,500 orders a month at 4 line items each creates roughly 90,000 records a year across Orders and Line Items alone. You can archive old orders to a separate base, but if you're archiving quarterly just to stay alive, you've outgrown the tool.

**Automation run limits.** Runs are a hard monthly cap per workspace (25,000 on Team, 100,000 on Business). We've seen order operations hit the cap mid-month and stop processing entirely until the meter reset. If your order volume puts you within range of the cap, move the heavy automation load to Make — or move platforms.

**Warehouse operations.** Barcode-driven pick/pack at speed, multi-warehouse allocation, wave picking, carrier rate shopping at volume — that's WMS/OMS territory (ShipStation, Cin7, Linnworks, or a real ERP). Airtable can't do it and shouldn't try.

**Financial controls.** When finance needs immutable audit trails, period locks, and accounting-grade permissions, Airtable's flexibility becomes the liability. That's the ERP signal.

The honest framing: Airtable is the best order management system for businesses doing dozens to a few thousand orders a month who need the workflow to fit *them*. Past that, it becomes the operations layer alongside specialized tools — and eventually it hands off entirely.

## Common Mistakes

**Mistake 1: No line-items table.** Multi-linking products straight to orders means no quantities, no per-order pricing, no inventory math. This is the error that forces rebuilds.

**Mistake 2: Looking up live prices on historical orders.** Lookup fields recalculate; last year's orders shouldn't reprice when you update the catalog. Copy prices into line items at order time.

**Mistake 3: Typing stock numbers manually.** Hand-edited inventory is wrong within a week. Stock must be a formula over rollups.

**Mistake 4: Counting cancelled orders in Units Sold.** Filter the rollup by order status, or cancellations silently corrupt stock levels forever.

**Mistake 5: Building the order form before checking the line-item limitation.** Teams build a beautiful native Airtable order form, then discover it can't handle a cart. Choose Fillout (or similar) on day one for multi-product intake.

## Troubleshooting

**Order Total shows 0.** The rollup is summing the wrong field, or line items aren't linked to the order. Check the link, then the rollup's source field.

**Current Stock is negative.** Either Starting Stock was never set at go-live, or cancelled orders are counting in Units Sold. Run a physical count, reset Starting Stock, fix the rollup condition.

**Shipping emails fired without tracking numbers.** The trigger is watching Status alone. Add "Tracking Number is not empty" as a second condition.

**Shopify orders create duplicate customers.** The Make scenario isn't doing find-before-create on email. Add a search module and route to update instead of create on a match.

**PO PDF is missing line items.** The document template isn't iterating the linked line-item records. In DocsAutomator/CraftMyPDF, configure the line-item table as a repeating section bound to the linked records, not a single text field.

## Next Steps

A working order system is the spine of an operations base — the natural extensions all connect to it:

- **Customer portal** — let wholesale customers see order status without emailing you, via [a Softr client portal](/tutorials/build-client-portal-airtable-softr).
- **Reporting layer** — revenue by channel, fulfillment cycle times, top SKUs, using [client-style dashboards](/tutorials/airtable-client-reporting-dashboards).
- **Quote-to-cash** — connect orders to invoicing and payment tracking end to end.

If you'd rather have this built right the first time — schema, intake forms, shipping integrations, and the automation budget mapped to your actual order volume — that's exactly what we do. [Get in touch](/contact).


## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
