DEV Community

Pirate Prentice
Pirate Prentice

Posted on

n8n Shopify Node: Automate Orders, Customers, and Inventory in Your Workflows [Free Workflow JSON]

n8n Shopify Node: Automate Orders, Customers, and Inventory in Your Workflows [Free Workflow JSON]

If you're running a Shopify store, you're already drowning in repetitive tasks: exporting orders to spreadsheets, tagging customers by purchase history, emailing suppliers when stock runs low, and reconciling payments in your accounting tool. The n8n Shopify node connects your store to every other tool in your stack—without middleware, without Zapier's per-task pricing, and without writing custom API code.

This guide covers every Shopify node operation, the six most common gotchas, three production-ready workflow patterns, and a free downloadable JSON you can import directly into n8n.


What the n8n Shopify Node Can Do

The Shopify node in n8n covers the core Shopify Admin REST API resources. Here's what you can read, create, and update:

Orders

  • Get Order: fetch a single order by ID
  • Get All Orders: list orders with filters (status, date range, fulfillment status, financial status)
  • Create Order: programmatically create an order (useful for phone/offline orders)
  • Update Order: change tags, notes, or metafields on existing orders
  • Delete Order: remove a draft order

Customers

  • Get Customer / Get All Customers: retrieve customer records with purchase history
  • Create Customer: add new customers to your Shopify CRM
  • Update Customer: add tags, notes, addresses, or metafields
  • Delete Customer

Products

  • Get Product / Get All Products: list products with variant details, inventory levels, images
  • Create Product / Update Product / Delete Product

Triggers (Shopify Trigger node)

  • Order Created / Updated / Paid / Fulfilled / Cancelled / Partially Fulfilled
  • Customer Created / Updated
  • Product Created / Updated / Deleted
  • Checkout Created / Updated

Prerequisites

  1. A Shopify store (any plan — even development stores work for testing)
  2. A Custom App with the scopes your workflow needs
  3. The Admin API access token from that app

Creating the credential in n8n

  1. In Shopify Admin: Settings → Apps and sales channels → Develop apps → Create an app
  2. Configure API scopes:
    • Orders: read_orders, write_orders
    • Customers: read_customers, write_customers
    • Products: read_products, write_products
    • Inventory: read_inventory, write_inventory
  3. Install the app → copy the Admin API access token (shown only once)
  4. In n8n: Credentials → New → Shopify API
    • Shop subdomain: your-store (not your-store.myshopify.com)
    • Access token: paste the token

Scope tip: Request only the scopes your workflow actually needs. Shopify logs scope usage — over-permissioned apps get flagged in security reviews.


The Six Gotchas That Will Bite You

1. The API rate limit is 40 requests/second — not per minute

Shopify's REST API uses a leaky-bucket rate limiter: 40 requests/second per store, replenishing at 2/second. For bulk operations (Get All Orders, syncing large product catalogs), n8n will hit this fast. Add a Wait node (500ms–1000ms delay) between batches, or use Split In Batches with a 10-item chunk and a pause. Hitting the limit returns 429 Too Many Requests and n8n will retry — but repeated retries can cascade into longer delays.

2. "Get All" has a default limit of 250 records — pagination is manual

The Shopify node's Get All operation fetches up to 250 records per call and doesn't auto-paginate. For stores with thousands of orders or customers, you need to implement cursor-based pagination manually using page_info from the response headers or switch to the Shopify GraphQL Admin API (via the HTTP Request node) which supports proper pagination. For most small-to-mid stores, 250 is enough for recent records.

3. Order financial_status vs fulfillment_status — they're independent

financial_status (pending, paid, refunded, partially_refunded) and fulfillment_status (fulfilled, partial, unfulfilled) are separate fields. A common mistake: filtering for status=any to get "all paid unfulfilled orders" — this requires filtering on both fields. Use Get All Orders with financial_status=paid and then a Filter node to check fulfillment_status != 'fulfilled'.

4. Webhooks need a public URL — use ngrok or a cloud n8n instance for development

The Shopify Trigger node registers a webhook with Shopify, which requires a publicly reachable URL. localhost:5678 won't work — Shopify can't reach it. Options:

  • n8n Cloud: URL is already public
  • Self-hosted on a VPS: public IP + the n8n webhook path works
  • Local dev: use ngrok (ngrok http 5678) — but the tunnel URL changes on restart, which re-registers the webhook

5. Webhook deduplication is your responsibility

Shopify guarantees at-least-once delivery, not exactly-once. During high-traffic events (flash sales, Black Friday), the same order.paid webhook can fire twice. Build deduplication into your workflow: use a Redis Set node or a Google Sheet to check order_id before processing. Without this, you'll send duplicate fulfillment emails, double-count revenue in sheets, or create duplicate CRM records.

6. Customer email is not always present

Guest checkouts in Shopify can produce orders where customer.email is null (the email lives at order.email instead). If your workflow sends confirmation or fulfillment emails, always fall back to {{ $json.order.email || $json.customer.email }} — never assume customer.email is populated.


Pattern 1: Order → Google Sheets Revenue Sync

Use case: Append every paid Shopify order to a Google Sheet for daily revenue tracking without exporting CSVs.

Trigger: Shopify Trigger node → Event: order/paid

Workflow:

Shopify Trigger (order/paid)
  → Set node: extract order_id, created_at, total_price, customer.email, line_items count, financial_status
  → Google Sheets (Append Row): sheet "Orders Log", columns: Date | Order ID | Customer Email | Total | Items | Status
Enter fullscreen mode Exit fullscreen mode

Why it works: The order/paid webhook fires the instant payment is confirmed — not when the order is created (which may be unpaid). This avoids syncing abandoned checkouts or pending orders.

Dedup guard: Add a Google Sheets lookup (Get Row) before the append to check if order_id already exists in column B. If it does, stop execution. This handles Shopify's at-least-once delivery.

Free JSON: [included at end of article]


Pattern 2: Low-Stock Alert → Slack + Supplier Email

Use case: When a product variant drops below a stock threshold, alert the team on Slack and email the supplier automatically.

Trigger: Schedule Trigger → every 6 hours (or Shopify Trigger → product/updated if you want real-time)

Workflow:

Schedule Trigger (every 6h)
  → Shopify (Get All Products): limit=250
  → Split Out (operation: Split Out, field: variants)
  → Filter: inventory_quantity < 10 AND inventory_management == "shopify"
  → IF: no items pass filter → stop
  → Set node: build alert message with title, SKU, quantity, product URL
  → Slack (Send Message): channel #ops, message "⚠️ Low stock: {title} SKU {sku} — {qty} remaining"
  → Gmail (Send Email): to supplier@example.com, subject "Reorder needed: {title}", body with qty + Shopify admin link
Enter fullscreen mode Exit fullscreen mode

Threshold config tip: Store the threshold (10) in a Set node at the top so you can change it without editing the Filter. Or use a Google Sheet as a config store — one row per SKU with its reorder point.


Pattern 3: New Order → CRM Contact Sync + Tag Enrichment

Use case: When a customer places their first order, create or update their record in HubSpot (or Airtable), add a "buyer" tag in Shopify, and trigger a post-purchase email sequence in Brevo.

Trigger: Shopify Trigger → order/paid

Workflow:

Shopify Trigger (order/paid)
  → IF: customer.orders_count == 1  (first-time buyer)
    YES →
      → HubSpot (Create/Update Contact): email, first/last name, "buyer" lifecycle stage
      → Shopify (Update Customer): add tag "buyer-first-order"
      → Brevo (Add Contact to List): list "post-purchase-sequence-new"
    NO → (repeat buyer path)
      → HubSpot (Update Contact): increment purchase_count property
      → IF: orders_count == 3
        YES → Shopify (Update Customer): add tag "loyal-customer"
        YES → Brevo (Add to List): "vip-sequence"
Enter fullscreen mode Exit fullscreen mode

Why tag in Shopify too: Tags in Shopify make it easy to segment customers for future discount campaigns directly inside Shopify without needing to query your CRM.


Shopify Node vs HTTP Request Node (GraphQL)

Capability Shopify Node HTTP Request (GraphQL)
Setup complexity Low — credential + select operation Medium — GraphQL query syntax
Pagination Manual (250/page limit) Cursor-based (proper pagination)
Bulk exports (10K+ records) Impractical ✅ via Bulk Operations API
Metafields Limited ✅ Full access
Custom storefronts ✅ Storefront API
Best for Triggers + small CRUD ops Large catalog syncs, complex queries

For most automation workflows (order events, customer tagging, stock checks), the native Shopify node is sufficient. Switch to GraphQL via HTTP Request only when you need bulk exports or metafield depth.


Free Workflow JSON

Import this directly into n8n (Settings → Import from clipboard):

{
  "name": "Shopify Order Revenue Sync + Low Stock Alert",
  "nodes": [
    {
      "parameters": {
        "event": "order/paid"
      },
      "name": "Shopify Trigger",
      "type": "n8n-nodes-base.shopifyTrigger",
      "typeVersion": 1,
      "position": [250, 300]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            { "name": "order_id", "value": "={{ $json.id }}", "type": "string" },
            { "name": "created_at", "value": "={{ $json.created_at }}", "type": "string" },
            { "name": "total_price", "value": "={{ $json.total_price }}", "type": "string" },
            { "name": "customer_email", "value": "={{ $json.email }}", "type": "string" },
            { "name": "item_count", "value": "={{ $json.line_items.length }}", "type": "number" },
            { "name": "financial_status", "value": "={{ $json.financial_status }}", "type": "string" }
          ]
        }
      },
      "name": "Extract Fields",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [450, 300]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": { "__rl": true, "mode": "list", "value": "YOUR_SHEET_ID" },
        "sheetName": { "__rl": true, "mode": "list", "value": "Orders Log" },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Date": "={{ $json.created_at }}",
            "Order ID": "={{ $json.order_id }}",
            "Customer Email": "={{ $json.customer_email }}",
            "Total": "={{ $json.total_price }}",
            "Items": "={{ $json.item_count }}",
            "Status": "={{ $json.financial_status }}"
          }
        }
      },
      "name": "Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [650, 300]
    }
  ],
  "connections": {
    "Shopify Trigger": { "main": [[{ "node": "Extract Fields", "type": "main", "index": 0 }]] },
    "Extract Fields": { "main": [[{ "node": "Log to Google Sheets", "type": "main", "index": 0 }]] }
  }
}
Enter fullscreen mode Exit fullscreen mode

Replace YOUR_SHEET_ID with your Google Sheets document ID. Add a Google Sheets credential and a Shopify API credential before running.


Where to Go From Here

The Shopify node handles the most common e-commerce automations well. For production stores, consider these additions:

  • Inventory webhooks (inventory_levels/update) for real-time stock alerts instead of polling
  • Fulfillment automation: when an order is marked paid, trigger a fulfillment request to your 3PL via HTTP Request
  • Abandoned checkout recovery: use the checkouts/create trigger to start a Brevo sequence for carts left behind
  • Metafield sync: use the HTTP Request node (GraphQL) to read/write product metafields for custom attribute management

Get the Pre-Built n8n Workflow Pack

The free JSON above gives you the basics. If you want a complete Shopify automation bundle — order sync, customer tagging, low-stock alerts, and post-purchase sequences — all pre-wired and documented:

👉 n8n Workflow Starter Pack ($29) — pirateprentice.gumroad.com/l/sxcoe

Or if you'd rather have it built specifically for your store:

👉 Done-For-You n8n Workflow Build ($99) — buy.stripe.com/4gMdRaetT3Yv3yxbOs2go03

Send your store setup and what you want automated — I'll deliver a working n8n workflow within 48 hours.

Top comments (1)

Collapse
 
pirateprentice profile image
Pirate Prentice

Are you using the Shopify node to sync orders into a spreadsheet, trigger low-stock alerts, or push new customers into your CRM? Drop your use case in the comments — always curious what automation people are building on top of Shopify.