DEV Community

Alex Kane
Alex Kane

Posted on

n8n for E-Commerce: 5 Automations That Work on Any Platform (Free Workflow JSON)

Running an online store means drowning in repetitive tasks: sending order confirmations, chasing abandoned carts, requesting reviews, pulling daily metrics. These tasks don't care what platform you're on — Shopify, WooCommerce, BigCommerce, headless commerce, or a custom stack.

n8n is a self-hosted automation platform that connects to any API or webhook. Here are 5 e-commerce automations you can run regardless of your platform.

Why n8n for E-Commerce

Most automation tools charge per task and lock you into their ecosystem. n8n is self-hosted (or cloud), workflows are portable JSON files, and there's no per-execution pricing. Connect your store's webhooks or API and automate everything from order flow to customer retention.

Workflow 1: Order Confirmation & Fulfillment Sequence

When an order is placed, this workflow sends a branded HTML confirmation email, logs the order to Google Sheets for reporting, and notifies your team in Slack. Works with any platform that can send a webhook on order creation.

Nodes: Webhook (order.created) → Code (extract + validate order data) → Gmail (HTML confirmation to customer) → Google Sheets (log to orders sheet) → Slack (notify #orders-new)

{
  "name": "Order Confirmation Sequence",
  "nodes": [
    {"id":"1","name":"Order Webhook","type":"n8n-nodes-base.webhook","parameters":{"httpMethod":"POST","path":"order-created","responseMode":"onReceived","responseData":"firstEntryJson"}},
    {"id":"2","name":"Extract Order","type":"n8n-nodes-base.code","parameters":{"jsCode":"const o = $input.first().json.body || $input.first().json;\nreturn [{ json: {\n  orderId: o.id || o.order_id,\n  customerName: o.customer?.name || o.billing?.first_name + ' ' + o.billing?.last_name,\n  customerEmail: o.customer?.email || o.billing?.email,\n  total: o.total_price || o.total,\n  currency: o.currency || 'USD',\n  items: (o.line_items || o.items || []).length,\n  createdAt: new Date().toISOString()\n}}];"}},
    {"id":"3","name":"Send Confirmation","type":"n8n-nodes-base.gmail","parameters":{"operation":"send","to":"={{$json.customerEmail}}","subject":"Order Confirmed — #{{$json.orderId}}","message":"<h2>Thank you, {{$json.customerName}}!</h2><p>Your order <strong>#{{$json.orderId}}</strong> has been received and is being processed.</p><p>Order total: <strong>{{$json.total}} {{$json.currency}}</strong></p><p>We'll send you a shipping notification once your order is on its way.</p><p>Questions? Reply to this email anytime.</p>","options":{"bodyContentType":"html"}}},
    {"id":"4","name":"Log to Sheets","type":"n8n-nodes-base.googleSheets","parameters":{"operation":"append","documentId":"YOUR_SHEET_ID","sheetName":"Orders","columns":{"mappingMode":"defineBelow","value":{"orderId":"={{$json.orderId}}","customer":"={{$json.customerName}}","email":"={{$json.customerEmail}}","total":"={{$json.total}}","items":"={{$json.items}}","createdAt":"={{$json.createdAt}}"}}}},
    {"id":"5","name":"Slack Notify","type":"n8n-nodes-base.slack","parameters":{"channel":"#orders-new","text":"New order #{{$json.orderId}} from {{$json.customerName}} — {{$json.total}} {{$json.currency}} ({{$json.items}} items)"}}
  ],
  "connections": {"Order Webhook":{"main":[[{"node":"Extract Order"}]]},"Extract Order":{"main":[[{"node":"Send Confirmation"}]]},"Send Confirmation":{"main":[[{"node":"Log to Sheets"}]]},"Log to Sheets":{"main":[[{"node":"Slack Notify"}]]}}
}
Enter fullscreen mode Exit fullscreen mode

Workflow 2: Post-Purchase Review Request Sequence

7 days after order fulfillment, send a review request email. If the customer doesn't respond, send a gentle follow-up 5 days later. Drives reviews without any manual work — and reviews drive sales.

Nodes: Webhook (order.fulfilled) → Wait (7 days) → Gmail (review request) → Wait (5 days) → Gmail (follow-up)

{
  "name": "Review Request Sequence",
  "nodes": [
    {"id":"1","name":"Order Fulfilled","type":"n8n-nodes-base.webhook","parameters":{"httpMethod":"POST","path":"order-fulfilled","responseMode":"onReceived"}},
    {"id":"2","name":"Extract Data","type":"n8n-nodes-base.code","parameters":{"jsCode":"const o = $input.first().json.body || $input.first().json;\nreturn [{ json: {\n  orderId: o.id || o.order_id,\n  customerName: o.customer?.name || o.shipping?.name,\n  customerEmail: o.customer?.email || o.shipping?.email,\n  productName: (o.line_items?.[0]?.name || o.items?.[0]?.name || 'your recent purchase')\n}}];"}},
    {"id":"3","name":"Wait 7 Days","type":"n8n-nodes-base.wait","parameters":{"amount":7,"unit":"days"}},
    {"id":"4","name":"Review Request Email","type":"n8n-nodes-base.gmail","parameters":{"operation":"send","to":"={{$json.customerEmail}}","subject":"How was your {{$json.productName}}?","message":"Hi {{$json.customerName}},\n\nWe hope you're enjoying your order #{{$json.orderId}}!\n\nWould you take 2 minutes to leave a review? Your feedback helps other customers and helps us improve.\n\n[Leave a Review] — [link to your store review page]\n\nThank you,\nThe Team"}},
    {"id":"5","name":"Wait 5 More Days","type":"n8n-nodes-base.wait","parameters":{"amount":5,"unit":"days"}},
    {"id":"6","name":"Follow-Up Email","type":"n8n-nodes-base.gmail","parameters":{"operation":"send","to":"={{$json.customerEmail}}","subject":"Quick reminder — how was your order?","message":"Hi {{$json.customerName}},\n\nJust a quick follow-up on order #{{$json.orderId}}.\n\nIf you have a moment, we'd love your review. It only takes 2 minutes and means a lot to us.\n\n[Leave a Review]\n\nThank you,\nThe Team"}}
  ],
  "connections": {"Order Fulfilled":{"main":[[{"node":"Extract Data"}]]},"Extract Data":{"main":[[{"node":"Wait 7 Days"}]]},"Wait 7 Days":{"main":[[{"node":"Review Request Email"}]]},"Review Request Email":{"main":[[{"node":"Wait 5 More Days"}]]},"Wait 5 More Days":{"main":[[{"node":"Follow-Up Email"}]]}}
}
Enter fullscreen mode Exit fullscreen mode

Workflow 3: Cart Abandonment Recovery

The classic: customer adds items, doesn't checkout. This workflow catches the abandon webhook from your store, waits 1 hour, sends a reminder, then follows up 12 hours later with a discount code if they still haven't purchased.

Nodes: Webhook (cart.abandoned) → Wait (1h) → Gmail (soft reminder) → Wait (12h) → Gmail (10% discount offer)

{
  "name": "Cart Abandonment Recovery",
  "nodes": [
    {"id":"1","name":"Cart Abandoned","type":"n8n-nodes-base.webhook","parameters":{"httpMethod":"POST","path":"cart-abandoned","responseMode":"onReceived"}},
    {"id":"2","name":"Extract Cart","type":"n8n-nodes-base.code","parameters":{"jsCode":"const c = $input.first().json.body || $input.first().json;\nreturn [{ json: {\n  cartId: c.id || c.cart_id,\n  customerName: c.customer?.first_name || c.billing_address?.first_name || 'there',\n  customerEmail: c.customer?.email || c.email,\n  cartTotal: c.total_price || c.subtotal_price,\n  currency: c.currency || 'USD',\n  checkoutUrl: c.checkout_url || c.recovery_url || '#'\n}}];"}},
    {"id":"3","name":"Wait 1 Hour","type":"n8n-nodes-base.wait","parameters":{"amount":1,"unit":"hours"}},
    {"id":"4","name":"Reminder Email","type":"n8n-nodes-base.gmail","parameters":{"operation":"send","to":"={{$json.customerEmail}}","subject":"You left something behind…","message":"Hi {{$json.customerName}},\n\nYou left items in your cart worth {{$json.cartTotal}} {{$json.currency}}.\n\nYour cart is saved and ready whenever you are:\n{{$json.checkoutUrl}}\n\nThe Team"}},
    {"id":"5","name":"Wait 12 Hours","type":"n8n-nodes-base.wait","parameters":{"amount":12,"unit":"hours"}},
    {"id":"6","name":"Discount Email","type":"n8n-nodes-base.gmail","parameters":{"operation":"send","to":"={{$json.customerEmail}}","subject":"Here's 10% off your cart — today only","message":"Hi {{$json.customerName}},\n\nYour cart is still waiting. Use code SAVE10 for 10% off — valid for 24 hours.\n\nComplete your order: {{$json.checkoutUrl}}\n\nThe Team"}}
  ],
  "connections": {"Cart Abandoned":{"main":[[{"node":"Extract Cart"}]]},"Extract Cart":{"main":[[{"node":"Wait 1 Hour"}]]},"Wait 1 Hour":{"main":[[{"node":"Reminder Email"}]]},"Reminder Email":{"main":[[{"node":"Wait 12 Hours"}]]},"Wait 12 Hours":{"main":[[{"node":"Discount Email"}]]}}
}
Enter fullscreen mode Exit fullscreen mode

Workflow 4: Daily E-Commerce Metrics Briefing

Every morning at 8AM, pulls yesterday's orders from your sheet (or store API), calculates key KPIs — revenue, order count, average order value, top product — and emails you a clean HTML summary. No more logging into your dashboard just to see the numbers.

Nodes: Schedule (8AM daily) → Google Sheets (yesterday's orders) → Code (calculate KPIs: revenue, AOV, order count, top product) → Gmail (HTML report)

{
  "name": "Daily Ecommerce Metrics",
  "nodes": [
    {"id":"1","name":"Daily 8AM","type":"n8n-nodes-base.scheduleTrigger","parameters":{"rule":{"interval":[{"field":"cronExpression","expression":"0 8 * * *"}]}}},
    {"id":"2","name":"Get Orders","type":"n8n-nodes-base.googleSheets","parameters":{"operation":"read","documentId":"YOUR_SHEET_ID","sheetName":"Orders"}},
    {"id":"3","name":"Calculate KPIs","type":"n8n-nodes-base.code","parameters":{"jsCode":"const today = new Date();\nconst yesterday = new Date(today - 86400000);\nconst yDate = yesterday.toISOString().split('T')[0];\nconst orders = $input.all().map(i => i.json).filter(o => (o.createdAt || '').startsWith(yDate));\nconst revenue = orders.reduce((s, o) => s + parseFloat(o.total || 0), 0);\nconst count = orders.length;\nconst aov = count > 0 ? (revenue / count).toFixed(2) : 0;\nconst productCounts = {};\norders.forEach(o => { if (o.product) productCounts[o.product] = (productCounts[o.product] || 0) + 1; });\nconst topProduct = Object.entries(productCounts).sort((a,b) => b[1]-a[1])[0]?.[0] || 'N/A';\nconst html = `<h2>Daily Store Report — ${yDate}</h2><table border='1' cellpadding='8'><tr><th>Metric</th><th>Value</th></tr><tr><td>Revenue</td><td>$${revenue.toFixed(2)}</td></tr><tr><td>Orders</td><td>${count}</td></tr><tr><td>Avg Order Value</td><td>$${aov}</td></tr><tr><td>Top Product</td><td>${topProduct}</td></tr></table>`;\nreturn [{ json: { html, revenue: revenue.toFixed(2), count, aov, topProduct, date: yDate }}];}"},
    {"id":"4","name":"Email Report","type":"n8n-nodes-base.gmail","parameters":{"operation":"send","to":"owner@yourstore.com","subject":"Store Report — {{$json.date}}: ${{$json.revenue}} | {{$json.count}} orders","message":"={{$json.html}}","options":{"bodyContentType":"html"}}}
  ],
  "connections": {"Daily 8AM":{"main":[[{"node":"Get Orders"}]]},"Get Orders":{"main":[[{"node":"Calculate KPIs"}]]},"Calculate KPIs":{"main":[[{"node":"Email Report"}]]}}
}
Enter fullscreen mode Exit fullscreen mode

Workflow 5: Customer Win-Back Campaign

Every Monday, checks your customer list for anyone who ordered more than 60 days ago and hasn't bought since. Sends a personalized win-back email with a special offer. Reactivates dormant customers automatically.

Nodes: Schedule (Monday 9AM) → Google Sheets (customer + order history) → Code (filter 60-day dormant) → Gmail (personalized win-back offer)

{
  "name": "Customer Win-Back Campaign",
  "nodes": [
    {"id":"1","name":"Monday 9AM","type":"n8n-nodes-base.scheduleTrigger","parameters":{"rule":{"interval":[{"field":"cronExpression","expression":"0 9 * * 1"}]}}},
    {"id":"2","name":"Get Customers","type":"n8n-nodes-base.googleSheets","parameters":{"operation":"read","documentId":"YOUR_SHEET_ID","sheetName":"Customers"}},
    {"id":"3","name":"Find Dormant","type":"n8n-nodes-base.code","parameters":{"jsCode":"const cutoff = new Date(Date.now() - 60 * 86400000);\nconst dormant = $input.all().map(i => i.json).filter(c => {\n  const lastOrder = new Date(c.lastOrderDate);\n  return lastOrder < cutoff && c.email && c.orderCount > 0;\n});\nreturn dormant.map(c => ({ json: c }));"}},
    {"id":"4","name":"Win-Back Email","type":"n8n-nodes-base.gmail","parameters":{"operation":"send","to":"={{$json.email}}","subject":"We miss you, {{$json.firstName}}! Here's 15% off","message":"Hi {{$json.firstName}},\n\nIt's been a while since your last order, and we wanted to reach out.\n\nAs a thank-you for being a customer, here's an exclusive 15% off your next order:\n\nCode: WELCOME15\n\nValid for the next 7 days. No minimum order.\n\n[Shop Now — link to your store]\n\nWe hope to see you again!\nThe Team"}}
  ],
  "connections": {"Monday 9AM":{"main":[[{"node":"Get Customers"}]]},"Get Customers":{"main":[[{"node":"Find Dormant"}]]},"Find Dormant":{"main":[[{"node":"Win-Back Email"}]]}}
}
Enter fullscreen mode Exit fullscreen mode

ROI

  • Order confirmation automation: 2-5 min saved per order × volume = hours saved weekly
  • Review requests: even a 1% improvement in review rate compounds over months (more reviews = more trust = more conversions)
  • Cart abandonment: industry average 5-10% recovery rate — on $10K/month in abandoned carts, that's $500-1,000 recovered
  • Daily report: replaces 10-15 minutes of daily dashboard logging
  • Win-back campaign: dormant customer reactivation at near-zero marginal cost

Get the Ready-to-Use Templates

Building each workflow from scratch takes time. At FlowKit, we've pre-built, tested, and documented 15 n8n workflow templates — import and configure instead of build from scratch.

Browse FlowKit n8n Templates →

Individual templates from $12. Full bundle $97.

Top comments (0)