{
  "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
          }
        ]
      ]
    }
  }
}