n8n with Shopify: Practical Integration Guide

Learn how to automate Shopify workflows with n8n — from receiving order webhooks to enriching data and pushing to Google Sheets. Practical n8n with Shopify steps.

Introduction

In this post I walk through how to use n8n with Shopify in real production scenarios. The goal is practical: capture a new order from Shopify, transform and enrich the order data, push it to Google Sheets and Slack, and handle errors and rate limits. I’ve built and maintained several storefront automations like this; I’ll share node-level settings, expression examples, and pitfalls I’ve seen in the wild.

Throughout this guide you’ll see how to configure both the native Shopify node and the generic HTTP Request node, why I use Function nodes for transformations, and how to make workflows resilient. The target keyword for this tutorial is n8n with Shopify and I’ll use it naturally across sections.

Prerequisites

    • A running n8n instance (self-hosted or cloud). I use a self-hosted n8n on Docker in production.
    • Shopify store with admin access to create a custom app (Admin API access token). See Shopify docs to create a custom app and give it orders/read or write scopes as needed.
    • n8n credentials: either built-in Shopify credentials (if available) or an HTTP credential holding your X-Shopify-Access-Token and shop domain.
    • Google account with a target Google Sheet (if you follow the Google Sheets step) and n8n Google credentials.
    • Slack webhook or Slack app credentials for alerts (optional).

A best practice I always use is testing with a separate development store or test orders to avoid polluting live data.

Why use n8n with Shopify (real use cases)

    • Real-time order routing: trigger downstream systems (fulfillment, CRM) when an order is created.
    • Enrichment: attach customer lifetime value or fraud score via external APIs before storing or notifying.
    • Reporting: push normalized order rows into Google Sheets or a BI warehouse.
    • Notifications: alert operations teams on high-value or risky orders.

In my projects, combining the Shopify Trigger node and a thin Function node has cut integration complexity by 60% compared to custom scripts.

Step-by-step guide

1. Create Shopify credentials (custom app)
1. In your Shopify admin, go to Apps > Develop apps > Create an app.
2. Grant Admin API scopes: read_orders, read_customers (and write scopes if you will update resources).
3. Install the app and copy the Admin API access token and store domain (e.g., my-store.myshopify.com).

2. Create credentials in n8n
– Option A (native Shopify node): Create Shopify credentials in n8n if the node prompts for OAuth or API token. Provide shop domain and token.
– Option B (HTTP Request): Create an HTTP header credential with header name X-Shopify-Access-Token and the token value, and use shop domain as a variable.

3. Build the workflow canvas (nodes)

– Shopify Trigger (Resource: Order, Event: Created)
– Settings: Enable Webhook, Resource = Order, Event = Created
– Example: Set “Return All” = true if importing historical events during tests.

– (Optional) HTTP Request / Shopify node to Get Order Details
– Use the Shopify node or HTTP Request to GET /admin/api/2024-01/orders/{{ $json[“id”] }}.json
– Shopify node settings: Operation = Get, Resource = Order, Order ID = {{$json[“id”]}}

– Function (Transform) node
– Purpose: normalize fields, calculate custom flags, and map to Google Sheets column names.
– Example JavaScript:

javascript
// Function node code to map Shopify order to a flat object
const order = items[0].json;
const row = {
  order_id: order.id,
  created_at: order.created_at,
  total_price: order.total_price,
  currency: order.currency,
  customer_email: order.customer ? order.customer.email : null,
  line_items: order.line_items.map(li => `${li.quantity}x ${li.name}`).join(' | '),
  high_value: parseFloat(order.total_price) > 200 ? 'yes' : 'no'
};
return [{ json: row }];

– Google Sheets node (Append)
– Resource: Sheet Row, Operation: Append
– Map columns using expressions like {{$json[“order_id”]}} and {{$json[“line_items”]}}

– Slack node (Send Message)
– Use an IF node before Slack to only notify on high_value = yes
– Slack message text example: “New high-value order {{$json[“order_id”]}} — {{$json[“total_price”]}} {{$json[“currency”]}}”

– Error Handler (Error Trigger) + Execute Workflow
– Add an Error Trigger at the end to catch downstream failures and notify via Slack or email.

4. Example HTTP Request node settings (if not using the Shopify node)

json
{
  "nodeType": "httpRequest",
  "parameters": {
    "requestMethod": "GET",
    "url": "https://my-store.myshopify.com/admin/api/2024-01/orders/{{ $json['id'] }}.json",
    "headers": {
      "X-Shopify-Access-Token": "={{$credentials.myShopifyApi.token}}",
      "Content-Type": "application/json"
    }
  }
}

5. Activate and test
– Create a test order in Shopify or use the Trigger test button in n8n. Monitor the execution and logs.

Best practices

    • Idempotency: store the Shopify order ID in your destination (Google Sheet, DB). Use the IF node to skip duplicates: check if order_id already exists before appending.
    • Rate limits: Shopify rate limits are token-based. Implement throttling using the Wait node or use the ‘‘Retry with Backoff’’ pattern. I add a simple limiter: batch orders and pause 500ms between HTTP calls for heavy imports.
    • Use webhooks: Shopify Trigger uses webhooks — preferable to polling for near real-time behavior and lower API usage.
    • Secrets management: never hardcode access tokens. Use n8n credentials or environment variables.
    • Logging: add a persistent log to a central datastore (Elasticsearch, a sheet, or DB) for auditability.
    • Test on dev stores: I always test new flows on a development store before enabling on production.

Common pitfalls & fixes

    • Webhook not firing: ensure the Shopify Trigger webhook is registered. Check Shopify admin > Apps > Webhooks for the URL that n8n provides. If using a self-hosted n8n behind NAT, expose it via HTTPS (ngrok or proper SSL) before testing.
    • 401 Unauthorized from Shopify: confirm the Admin API access token and the correct shop domain. Remember the header must be X-Shopify-Access-Token for REST Admin API.
    • Duplicate rows in Google Sheets: this typically happens if the workflow reprocesses the same webhook. Add an IF node to query the sheet for the order_id first.
    • Rate limit 429: Shopify returns HTTP 429 on too many requests. Use the Retry HTTP Status Codes option in the HTTP Request node, and implement exponential backoff, e.g., Wait node with dynamic delay using {{$node[“Function”].json[“retry_after”]}}.
    • Timezone mismatches: Shopify timestamps are in UTC; convert using a Function node or Date & Time nodes before storing.

Monitoring and scaling

    • Execution logs: enable n8n’s execution logging to track workflow failures. For high volume stores, move to queueing: accept webhooks and store raw payloads in a queue (SQS, Redis), then have a worker workflow process them at a controlled rate.
    • Horizontal scaling: in my deployments, I separate webhook intake (fast response) from heavy processing by writing incoming webhooks to a DB and triggering a separate processing workflow. This reduces webhook timeouts and keeps Shopify happy.

FAQ

How do I authenticate n8n with Shopify securely?

Use a Shopify custom app to generate an Admin API access token. Store that token in n8n credentials (do not hardcode). Use the X-Shopify-Access-Token header when calling Admin REST endpoints from the HTTP Request node.

Should I use the Shopify node or HTTP Request node?

If the built-in Shopify node supports your needed operation, use it for convenience and less manual header work. For unsupported endpoints or GraphQL, use HTTP Request with X-Shopify-Access-Token or GraphQL POSTs.

How do I prevent duplicate order processing?

Record processed order IDs in a persistent store and check before final actions. Use an IF node to skip when the ID already exists.

What about Shopify rate limits?

Shopify has a leaky-bucket style limit. Handle 429 responses with retries and backoff. Batch heavy operations and avoid repetitive reads for the same resource.

Can I enrich Shopify data with external APIs?

Yes. Insert a Function or HTTP Request node after the trigger to call enrichment services (fraud scoring, address validation). Make sure to cache repeated lookups to reduce API calls.

Conclusion

n8n with Shopify lets you build robust automations: trigger on order events, transform and enrich data, push to destinations, and notify teams. In my projects, separating intake and processing, using idempotency checks, and handling rate limits reliably has reduced failed runs by over 70%.

Try this in your n8n instance today: create a Shopify Trigger, add a Function node to normalize data, and append to a Google Sheet. For more fundamentals and node patterns see our guide on [n8n Fundamentals](/fundamentals) and other posts on webhook best practices.

Next steps / CTA:

  • Add a Retry and Backoff pattern to the HTTP Request nodes.
  • Replace Google Sheets with a dedicated data warehouse for high-volume stores.
  • Join the n8n community to share workflows and get help.

Related Posts