This workflow corresponds to n8n.io template #12370 — we link there as the canonical source.
This workflow follows the Airtable → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "A3K6Mns3rcFI8RT1",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "WooCommerce VIP Customer Automation",
"tags": [],
"nodes": [
{
"id": "ebef1b4a-6f48-4588-93f1-74e3caa2f0f8",
"name": "Scheduled Check for New Orders",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-4176,
-1072
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "8481e4f1-3278-405a-98b1-905ad3ed73cb",
"name": "Set WooCommerce Domain",
"type": "n8n-nodes-base.set",
"position": [
-3952,
-1072
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "3a9c6d3d-4d92-4dfc-9995-d36a1628a1d6",
"name": "wc_domain",
"type": "string",
"value": "{{Your WC Domain Here}}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "f860b654-71a8-4ef6-b60b-8eeac683aa75",
"name": "Fetch Orders",
"type": "n8n-nodes-base.httpRequest",
"position": [
-3808,
-1072
],
"parameters": {
"url": "=https://{{ $json.wc_domain}}/wp-json/wc/v3/orders",
"options": {},
"sendQuery": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"queryParameters": {
"parameters": [
{
"name": "sta"
}
]
}
},
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "63256274-c16f-4837-9b6e-cfdec28e144a",
"name": "Filter Completed & Processing Orders",
"type": "n8n-nodes-base.if",
"position": [
-3664,
-1072
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "d4f2a312-db70-409c-babc-20f93ed15c65",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "completed"
},
{
"id": "d46e+1234567890d3e-8db8-f82a20eccedc",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "processing"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "d98d0a39-59a8-40d0-aa58-f68359ed2584",
"name": "Format order data",
"type": "n8n-nodes-base.set",
"position": [
-3408,
-1136
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "06c4633d-28a6-4a3f-9e27-12f93cfe54a3",
"name": "id",
"type": "number",
"value": "={{ $json.id }}"
},
{
"id": "3e47ce7f-1f02-4afb-b5d7-00e0cdadbbe1",
"name": "status",
"type": "string",
"value": "={{ $json.status }}"
},
{
"id": "6b25ccbb-2613-452e-9296-df99ba7baa87",
"name": "customer_id",
"type": "number",
"value": "={{ $json.customer_id }}"
},
{
"id": "336a07b0-7e67-4542-baf5-f4fc1fe21bc8",
"name": "customer_name",
"type": "string",
"value": "={{ $json.billing.first_name }} {{ $json.billing.last_name }}"
},
{
"id": "dc67cd5b-18c9-4921-a23d-6d095a2d355f",
"name": "customer_note",
"type": "string",
"value": "={{ $json.customer_note }}"
},
{
"id": "db42c8a3-846e-4b43-92fd-1796d8cb3c92",
"name": "date_created_gmt",
"type": "string",
"value": "={{ $json.date_created_gmt }}"
},
{
"id": "d21b4f0a-972b-4db2-ba5f-5486e39d98f8",
"name": "payment_url",
"type": "string",
"value": "={{ $json.payment_url }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "f54f6a18-7092-4c82-8d37-6489b9e99da9",
"name": "Deduplicate Customers",
"type": "n8n-nodes-base.code",
"position": [
-3232,
-1136
],
"parameters": {
"jsCode": "const unique = {};\nconst items = $input.all();\n\n// Get domain from previous node\nconst domain = $('Set WooCommerce Domain').first().json.wc_domain;\n\nfor (const item of items) {\n const c = item.json.customer_id;\n\n if (!unique[c]) {\n unique[c] = {\n ...item.json,\n wc_domain: domain // <-- add domain here\n };\n }\n}\n\nreturn Object.values(unique);\n"
},
"typeVersion": 2
},
{
"id": "d7df71bd-6157-47dc-bf2b-0b7a4599997b",
"name": "Fetch Customer Orders",
"type": "n8n-nodes-base.httpRequest",
"position": [
-3040,
-1136
],
"parameters": {
"url": "=https://{{ $json.wc_domain }}/wp-json/wc/v3/orders?customer={{ $json.customer_id }}&status=completed,processing",
"options": {},
"sendQuery": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"queryParameters": {
"parameters": [
{
"name": "=customer",
"value": "={{ $json.customer_id }}"
}
]
}
},
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "ea8f201a-4d47-425b-bcca-0ca383b89cd6",
"name": "Calculate VIP Tier",
"type": "n8n-nodes-base.code",
"position": [
-2864,
-1136
],
"parameters": {
"jsCode": "const orders = $input.all(); // all fetched orders\n\nconst customers = {};\n\nfor (const order of orders) {\n const orderData = order.json;\n\n // Ignore orders with total 0 or not completed\n if (parseFloat(orderData.total) <= 0 || orderData.status !== 'completed') continue;\n\n const custId = orderData.customer_id;\n\n if (!customers[custId]) {\n customers[custId] = {\n customer_id: custId,\n customer_name: `${orderData.billing.first_name} ${orderData.billing.last_name}`,\n lifetime_value: 0,\n total_orders: 0,\n order_ids: new Set() // track unique order ids\n };\n }\n\n // Count order only if it is unique\n if (!customers[custId].order_ids.has(orderData.id)) {\n customers[custId].order_ids.add(orderData.id);\n customers[custId].total_orders += 1;\n customers[custId].lifetime_value += parseFloat(orderData.total);\n }\n}\n\n// Assign tier and VIP reason\nfor (const custId in customers) {\n const cust = customers[custId];\n\n if (cust.lifetime_value >= 20000) {\n cust.tier = \"Platinum\";\n cust.vip_reason = \"lifetime_value\";\n } else if (cust.total_orders >= 5) {\n cust.tier = \"Gold\";\n cust.vip_reason = \"total_orders\";\n } else {\n cust.tier = \"Silver\";\n cust.vip_reason = null;\n }\n\n // Remove helper property\n delete cust.order_ids;\n}\n\n// Remove customers with invalid customer_id (guest checkouts)\nconst validCustomers = Object.values(customers).filter(c => c.customer_id && c.customer_id != 0);\nreturn validCustomers;\n"
},
"typeVersion": 2
},
{
"id": "95f31115-430e-4233-9434-3eee435a6f46",
"name": "Check VIP Eligibility",
"type": "n8n-nodes-base.if",
"position": [
-2592,
-1248
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0ac5988f-8e10-4f65-a0b1-b4f57adc1eb3",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $json.tier }}",
"rightValue": "none"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "e94b1a94-4e0f-4030-8c0f-0d77cdfa9012",
"name": "Save VIP Customer",
"type": "n8n-nodes-base.airtable",
"position": [
-2336,
-1264
],
"parameters": {
"base": {
"__rl": true,
"mode": "list",
"value": "appF2iYPgVqqyXDC1",
"cachedResultUrl": "https://airtable.com/appF2iYPgVqqyXDC1",
"cachedResultName": "n8n Demo"
},
"table": {
"__rl": true,
"mode": "list",
"value": "tblfU9DsiUwVEowKM",
"cachedResultUrl": "https://airtable.com/appF2iYPgVqqyXDC1/tblfU9DsiUwVEowKM",
"cachedResultName": "VIP Customer"
},
"columns": {
"value": {
"Id": "={{ $json.customer_id }}",
"VIP Tier": "={{ $json.tier }}",
"Vip reason": "={{ $json.vip_reason }}",
"Total Orders": "={{ $json.total_orders }}",
"Customer Name": "={{ $json.customer_name }}",
"Lifetime value": "={{ $json.lifetime_value }}"
},
"schema": [
{
"id": "Id",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Customer Name",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Customer Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "VIP Tier",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "VIP Tier",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Vip reason",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Vip reason",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Lifetime value",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Lifetime value",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Total Orders",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Total Orders",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "create"
},
"credentials": {
"airtableTokenApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "c470f2b6-5847-48b3-8237-a41c5d432338",
"name": "Notify Team",
"type": "n8n-nodes-base.slack",
"position": [
-2080,
-1264
],
"parameters": {
"text": "=VIP Order from {{ $json.fields[\"Customer Name\"] }}\nLifetime Value: {{ $json.fields['Lifetime value'] }}\nVip tier: {{ $json.fields['VIP Tier'] }}\nTotal Orders: {{ $json.fields['Total Orders'] }}\nVip Reason: {{ $json.fields['Vip reason'] }}\nAction: Please prioritise support and consider VIP gesture.",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C09S57E2JQ2",
"cachedResultName": "n8n"
},
"otherOptions": {
"includeLinkToWorkflow": false
}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "f9a25b40-f306-4a26-9ff1-4f8d209d6839",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-4240,
-1136
],
"parameters": {
"color": 7,
"width": 224,
"height": 224,
"content": "Triggers the workflow automatically at a set interval (minutes)."
},
"typeVersion": 1
},
{
"id": "d1d48b6c-d0de-443a-82bd-9af4ef03be1c",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-4000,
-1200
],
"parameters": {
"color": 7,
"width": 496,
"height": 304,
"content": "## Fetch and Filter WooCommerce Orders\nThis process retrieves all orders from the WooCommerce store and filters only those that are completed or processing using the configured store domain."
},
"typeVersion": 1
},
{
"id": "f69b8094-5571-4779-9bce-24b5919e58bf",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-3472,
-1264
],
"parameters": {
"color": 7,
"width": 752,
"height": 320,
"content": "## VIP Qualification Process\nThis step cleans customer data, gathers all their past orders and decides whether they are a VIP based on how much they spent or how many orders they made."
},
"typeVersion": 1
},
{
"id": "65d499b6-7d1e-4494-b39d-1f3574c38272",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2672,
-1376
],
"parameters": {
"color": 7,
"width": 800,
"height": 288,
"content": "## Store & Notify VIP Customers \nThis part makes sure the customer truly qualifies as a VIP, saves their VIP details into Airtable and sends a Slack alert to notify the team."
},
"typeVersion": 1
},
{
"id": "cc02c62a-be91-492c-8286-fa3ea23565b3",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-5088,
-1824
],
"parameters": {
"width": 448,
"height": 688,
"content": "## I'm a note \nThis workflow automatically finds your important (VIP) customers based on their WooCommerce orders. Every time new orders come in, it checks whether the customer has spent a lot over time or has placed many orders. If they qualify as a VIP, the workflow saves their information into Airtable and sends a Slack message to notify your team. This helps you keep track of high-value customers and respond quickly with special offers, support or follow-ups.\n\n\n## Setup Steps\n\n**Connect WooCommerce** \u2013 Add your WooCommerce base URL, consumer key and consumer secret.\n\n**Fetch Orders** \u2013 Use the HTTP node to pull all completed/processing orders.\n\n**Prepare Customer Data** \u2013 Extract customer details and remove duplicates.\n\n**Get Order History** \u2013 For each customer, fetch all their past orders.\n\n**Compute VIP Tier** \u2013 Calculate total spend and total orders to assign the correct VIP level.\n\n**Filter VIP Only** \u2013 Allow only valid VIP customers to move forward.\n\n**Send to Airtable & Slack** \u2013 Store the VIP record and notify your team instantly."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "51922f65-d9ff-47f8-9dce-36412795a47e",
"connections": {
"Fetch Orders": {
"main": [
[
{
"node": "Filter Completed & Processing Orders",
"type": "main",
"index": 0
}
]
]
},
"Format order data": {
"main": [
[
{
"node": "Deduplicate Customers",
"type": "main",
"index": 0
}
]
]
},
"Save VIP Customer": {
"main": [
[
{
"node": "Notify Team",
"type": "main",
"index": 0
}
]
]
},
"Calculate VIP Tier": {
"main": [
[
{
"node": "Check VIP Eligibility",
"type": "main",
"index": 0
}
]
]
},
"Check VIP Eligibility": {
"main": [
[
{
"node": "Save VIP Customer",
"type": "main",
"index": 0
}
]
]
},
"Deduplicate Customers": {
"main": [
[
{
"node": "Fetch Customer Orders",
"type": "main",
"index": 0
}
]
]
},
"Fetch Customer Orders": {
"main": [
[
{
"node": "Calculate VIP Tier",
"type": "main",
"index": 0
}
]
]
},
"Set WooCommerce Domain": {
"main": [
[
{
"node": "Fetch Orders",
"type": "main",
"index": 0
}
]
]
},
"Scheduled Check for New Orders": {
"main": [
[
{
"node": "Set WooCommerce Domain",
"type": "main",
"index": 0
}
]
]
},
"Filter Completed & Processing Orders": {
"main": [
[
{
"node": "Format order data",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
airtableTokenApihttpBasicAuthslackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automatically identifies VIP customers from your WooCommerce store based on their total spending and number of completed orders. It pulls new orders on a schedule, filters valid transactions, groups customers, calculates their VIP tier, stores them into Airtable…
Source: https://n8n.io/workflows/12370/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This automated workflow fetches Upwork job postings using Apify, removes duplicate job listings via Airtable, and sends new job opportunities to Slack. Automated job retrieval from Upwork via Apify AP
This workflow is designed for engineering teams, project managers, and IT operations who need consistent visibility into team availability across multiple projects. It’s perfect for organizations that
This workflow is an automated system that tracks End-of-Life (EOL) dates for software and technologies used across your projects. It eliminates the need to manually monitor EOL dates in spreadsheets o
This workflow continuously monitors the Meta Ads Library for new creatives from a specific competitor pages, logs them into Google Sheets, and sends a concise Telegram notification with the number of
Enhance financial oversight with this automated n8n workflow. Triggered every 5 minutes, it fetches real-time bank transactions via an API, enriches and transforms the data, and applies smart logic to