20+ hours a week sounds like a bold claim. So let's do the math before we do anything else.
A mid-sized D2C ecommerce brand processing 40-50 orders per day typically has three workflow categories bleeding time:
- Inventory management: Manual stock checks, spreadsheet updates, supplier emails — 8 hours/week
- Order operations: Invoice generation, fulfillment alerts, order confirmation follow-ups — 15 hours/week
- Support triage: Categorising and routing incoming emails, handling "where's my order?" messages manually — 4 hours/week
Total: 27 hours/week. Every week. Across a team that should be focused on growth, product, and customer experience.
We've automated all three categories for ecommerce clients using n8n. This post walks through the exact workflows — real node configurations, real trigger logic, and real client outcomes.
Why n8n for Ecommerce?
Before the walkthroughs: why n8n over Zapier or Make.com?
Three reasons that matter in practice:
- Self-hosting: Your order data, your customer data, your Shopify webhooks — all flowing through your own server. For clients with any data governance requirements, this matters.
- Cost structure: n8n charges per workflow execution, not per step. A 15-node workflow costs the same as a 2-node one. For high-volume ecommerce (500+ orders/day), this is significant.
- Code nodes: When Shopify's API returns nested JSON that no-code tools struggle with, n8n's JavaScript/Python Code node handles it cleanly. For SSE-level implementations, this is non-negotiable.
We covered the full n8n vs. alternatives debate in our n8n vs Zapier vs Make comparison. Here, we focus purely on implementation.
Workflow 1: Shopify Orders → Google Sheets Live Inventory Sync
What it replaces: Manual spreadsheet updates, twice-daily stock checks Time saved: 8 hours/week for the ops team Build time: 1 sprint day
The Node Architecture
[Shopify Trigger] → [Function Node] → [Google Sheets: Update Row]
→ [IF: Stock < Threshold] → [Gmail: Reorder Alert]
Node 1 — Shopify Trigger (Webhook)
Configure this in n8n as a Webhook node, then register it in Shopify:
Settings → Notifications → Webhooks → orders/paid
URL: https://your-n8n-instance.com/webhook/shopify-orders
Format: JSON
In n8n, set the Webhook node to POST and enable "Respond Immediately" so Shopify doesn't timeout waiting for your workflow to finish.
Node 2 — Function Node: Extract SKUs
Shopify's orders/paid webhook sends a nested payload. Here's how to extract what you need:
const items = $input.item.json.body.line_items;
return items.map(item => ({
json: {
sku: item.sku,
variant_id: item.variant_id,
quantity_sold: item.quantity,
product_title: item.title,
variant_title: item.variant_title,
order_id: $input.item.json.body.id,
timestamp: new Date().toISOString()
}
}));
This splits a single order (which may have 5 line items) into 5 separate items for parallel processing.
Node 3 — Google Sheets: Find + Update
Use the Google Sheets node in "Update Row" mode. Match on sku column. Update: decrement current_stock by quantity_sold using an expression:
={{ parseInt($node["Google Sheets"].json["current_stock"]) - $json["quantity_sold"] }}
Node 4 — IF Node: Low Stock Check
Condition: {{ $json.updated_stock }} is less than {{ $json.reorder_threshold }}
True path → Gmail node → generates a supplier reorder email with SKU, current stock, and suggested quantity.
Real outcome: A D2C skincare brand with 80+ SKUs eliminated twice-daily manual stock checks entirely. Their ops manager now starts the day with a 3-minute email review instead of 90 minutes of spreadsheet work.
Workflow 2: WhatsApp Abandoned Cart Recovery
What it replaces: No recovery at all (most brands rely only on email) Revenue recovered: ₹4.2L launch-month contribution for Baby Forest India Cart abandonment reduction: 22% Build time: 1 sprint day
This is the highest-ROI automation we've deployed. WhatsApp open rates run at 98% vs 20% for email. For Indian D2C brands, this isn't a nice-to-have — it's the difference between leaving money on the table and not.
The Node Architecture
[Shopify Trigger: checkouts/create]
→ [Wait Node: 60 minutes]
→ [Shopify: Check if order completed]
→ [IF: Order exists?]
→ True: [Stop — order was placed]
→ False: [WhatsApp Business API: Send recovery message]
Node 1 — Shopify Trigger: checkouts/create
Register this webhook in Shopify for checkouts/create. This fires the moment a customer starts checkout — before they complete it.
Node 2 — Wait Node
Set to 60 minutes. This is the window: long enough that the customer has clearly abandoned, short enough that the product is still fresh in their mind.
Gotcha: n8n Cloud has no issues here, but self-hosted instances need the queue mode enabled for Wait nodes to work reliably across server restarts. In your docker-compose.yml:
environment:
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
Node 3 — Shopify HTTP Request: Check Order Status
We use the HTTP Request node (not the Shopify node) for this check because we need to query by email, not order ID:
Method: GET
URL: https://{{ $env.SHOPIFY_STORE }}.myshopify.com/admin/api/2024-01/orders.json
Headers: X-Shopify-Access-Token: {{ $env.SHOPIFY_ACCESS_TOKEN }}
Query Parameters:
email={{ $json.email }}
created_at_min={{ $json.checkout_created_at }}
financial_status=paid
Node 4 — IF: Did they complete the order?
Condition: {{ $json.orders.length }} > 0
True → Stop (they bought, don't send)
False → Continue to WhatsApp
Node 5 — WhatsApp Business API
We use MSG91 or Gupshup as the WhatsApp provider for Indian brands (they're registered BSPs). HTTP Request node:
{
"to": "{{ $json.phone }}",
"type": "template",
"template": {
"name": "cart_recovery_v2",
"language": { "code": "en" },
"components": [{
"type": "body",
"parameters": [
{ "type": "text", "text": "{{ $json.first_name }}" },
{ "type": "text", "text": "{{ $json.line_items[0].title }}" },
{ "type": "text", "text": "{{ $json.abandoned_checkout_url }}" }
]
}]
}
}
We built this for Baby Forest India as a post-launch automation after their Shopify store went live. Their Shopify development was sprint one. The WhatsApp recovery flow was sprint two, two weeks later. The result contributed meaningfully to their ₹4.2L launch-month revenue.
Workflow 3: Automated GST Invoice Generation + Email
What it replaces: Manual invoice creation in Tally, PDF export, Gmail send Time saved: 3-4 hours/day (for a brand processing 40-50 orders daily) Build time: 2 sprint days (Google Docs API setup takes longer than the workflow)
The Node Architecture
[Shopify Trigger: orders/paid]
→ [Function: Extract buyer + order data]
→ [Google Docs API: Populate invoice template]
→ [Google Drive: Export as PDF]
→ [Gmail: Send to customer]
→ [Google Sheets: Log invoice number]
The Key Technical Detail
Google Docs doesn't have a "template fill" API natively. The approach we use: create a Google Doc with placeholder text ({{CUSTOMER_NAME}}, {{GSTIN}}, {{ORDER_TOTAL}}, {{GST_AMOUNT}}), then use the documents.batchUpdate API with replaceAllText requests:
const requests = [
{
replaceAllText: {
containsText: { text: '{{CUSTOMER_NAME}}', matchCase: true },
replaceText: $json.billing_address.name
}
},
{
replaceAllText: {
containsText: { text: '{{ORDER_TOTAL}}', matchCase: true },
replaceText: `₹${$json.total_price}`
}
},
// ... repeat for all placeholders
];
This runs via n8n's HTTP Request node to https://docs.googleapis.com/v1/documents/{documentId}:batchUpdate.
Gotcha: Create a copy of the template for each invoice — don't modify the master. Use the Drive API files.copy endpoint first, then populate the copy.
For a business processing 40-50 orders daily, this automation runs 40-50 times a day, generating a correctly formatted, GSTIN-accurate invoice within 90 seconds of every payment. The accuracy improvement was as significant as the time saving — no more copy-paste errors in GSTIN numbers.
Workflow 4: Support Email Triage + Auto-Routing
What it replaces: Morning inbox review, manual Freshdesk assignment Time saved: 45 min/day (3.75 hrs/week) Build time: Half a sprint day
The Node Architecture
[Gmail Trigger: New email to support@]
→ [OpenAI: Classify category]
→ [Switch Node: Route by category]
→ Billing → Freshdesk: Create ticket (Billing team)
→ Shipping → Freshdesk: Create ticket (Ops team)
→ Returns → Freshdesk: Create ticket (Returns team)
→ Technical → Freshdesk: Create ticket (Dev team)
The OpenAI Prompt
Classify this customer support email into exactly one category:
- BILLING (payment issues, invoice requests, refund status)
- SHIPPING (delivery status, tracking, address changes)
- RETURNS (return requests, exchange requests)
- TECHNICAL (product defects, app issues, account problems)
- GENERAL (anything else)
Respond with only the category name. No explanation.
Email subject: {{ $json.subject }}
Email body: {{ $json.snippet }}
Using gpt-4o-mini for this — it's more than capable of classification and costs a fraction of GPT-4o. At 200 emails/day, the API cost is under ₹150/day.
The 20+ Hours: Verified
Let's close the loop on the math claim:
| Workflow | Task eliminated | Hours saved/week |
|---|---|---|
| Inventory sync | Manual stock checks + spreadsheet updates | 8 hrs |
| Invoice generation | Tally → PDF → Gmail cycle | 15 hrs (40 orders/day × 5 min each) |
| Support triage | Morning inbox review + manual routing | 3.75 hrs |
| Total | 26.75 hrs/week |
For a brand with higher order volume or more support load, the number goes higher. For a lean 5-person team, 27 hours per week reclaimed is effectively adding a full-time team member's productive output — without the salary.
Error Handling: The Part Most Tutorials Skip
Every workflow above needs error handling. In production, webhooks fail, APIs rate-limit, and Google Docs times out.
n8n has a built-in Error Trigger node. Here's the pattern we use for every client deployment:
- Create a second workflow with just an Error Trigger node
- That workflow sends a Slack message to
#ops-alerts:Workflow {{ $json.workflow.name }} failed at node {{ $json.execution.lastNodeExecuted }}. Error: {{ $json.error.message }} - In every production workflow: Settings → Error Workflow → point to this error handler
Without this, a broken webhook at 11 PM on a Friday means you find out Monday morning when a client asks why 200 invoices weren't sent.
We Build and Maintain These
If you're an ecommerce brand recognising your own workflows in what you just read, we scope and build these on a fixed-price sprint basis via our AI automation service. Most single workflows go live in 1-3 business days. We also offer ongoing maintenance through our managed services — error monitoring, API version updates, and workflow adjustments as your business scales.