{
  "id": "ERLmJaR4fzrd1sXe",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "WooCommerce Daily Revenue Spike Monitor \u2192 Slack Alert",
  "tags": [],
  "nodes": [
    {
      "id": "ea2de751-1904-4bd0-b8b5-1e4e73defbe4",
      "name": "Fetch WooCommerce Orders",
      "type": "n8n-nodes-base.wooCommerce",
      "position": [
        32,
        -112
      ],
      "parameters": {
        "options": {},
        "resource": "order",
        "operation": "getAll",
        "returnAll": true
      },
      "credentials": {
        "wooCommerceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ab622b50-2e8b-40f7-8192-99d3b2970f18",
      "name": "Filter Paid Orders (Completed / Processing)",
      "type": "n8n-nodes-base.filter",
      "position": [
        224,
        -112
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "28829d78-0164-4899-8168-dd8ac595f43c",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "Processing"
            },
            {
              "id": "5f862d0b-6617-422e-90e0-d982d959f561",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "completed"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "9e34d0a5-da75-40f4-b4b6-40d27f2b907d",
      "name": "Filter Orders from Last 24 Hours",
      "type": "n8n-nodes-base.code",
      "position": [
        416,
        -112
      ],
      "parameters": {
        "jsCode": "// 1. Current execution time (same as schedule time)\nconst now = new Date();\n\n// 2. Calculate 24 hours ago\nconst cutoff = new Date(now.getTime() - 24 * 60 * 60 * 1000);\n\n// 3. Orders coming from previous node\nconst orders = items;\n\n// 4. Filter orders from last 24 hours\nconst last24hOrders = orders.filter(order => {\n  const created = new Date(order.json.date_created);\n  return created >= cutoff;\n});\n\nreturn last24hOrders;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "17c3ed92-b37f-4863-9307-122b437189a5",
      "name": "Calculate Total Revenue (24h)",
      "type": "n8n-nodes-base.code",
      "position": [
        832,
        -48
      ],
      "parameters": {
        "jsCode": "let totalRevenue = 0;\nlet currency = null;\nlet orderCount = items.length;\n\nfor (const item of items) {\n  const order = item.json;\n\n  // Convert string \u2192 number\n  const orderTotal = parseFloat(order.total || 0);\n  totalRevenue += orderTotal;\n\n  // Capture currency once\n  if (!currency) {\n    currency = order.currency;\n  }\n}\n\n// NEW: Average Order Value\nconst avgOrderValue =\n  orderCount > 0 ? totalRevenue / orderCount : 0;\n\nreturn [\n  {\n    json: {\n      revenue_last_24h: Number(totalRevenue.toFixed(2)),\n      currency: currency,\n      order_count: orderCount,\n      avg_order_value: Number(avgOrderValue.toFixed(2))\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "7fbcb634-4b06-443a-b8f5-a9cfb250e063",
      "name": "Daily Revenue Spike Monitor",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -288,
        -112
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 10
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "2fbb1a07-875e-414f-bd62-29969929f70f",
      "name": "Revenue Spike Threshold Check",
      "type": "n8n-nodes-base.if",
      "position": [
        1648,
        -112
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "18b55126-c51d-4344-9dff-9a177e5c93c6",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.revenue_last_24h }}",
              "rightValue": 100000
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "1958057e-c157-4b52-b4ed-d6784967c7f7",
      "name": "Send Slack Sales Spike Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        1936,
        -224
      ],
      "parameters": {
        "text": "=\ud83c\udf89 *Sales Spike Alert!* \ud83d\ude80\n\n\ud83d\udcb0 *Revenue (Last 24h):* \u20b9{{ $json.revenue_last_24h }}  \n\ud83e\uddfe *Orders:* {{ $json.order_count }}  \n\ud83d\udcca *Avg Order Value:* \u20b9{{ $json.avg_order_value }}\n\n\ud83d\udd25 *Top Products Sold:*\n{{ $json.top_products.map(p => `\u2022 ${p[0]} \u2014 ${p[1]} unit(s)`).join('\\n') }}\n\n\u274c *Cancellations Overview (Last 24h):*\n\u2022 Orders Cancelled: {{ $json.cancelled_orders_24h }}\n\u2022 Revenue Impact: \u20b9{{ $json.cancelled_revenue_24h }}\n\n\ud83d\udc49 *Suggested Actions:*\n\u2022 \ud83d\udce6 Check inventory levels  \n\u2022 \ud83d\udce2 Boost marketing / social posts  \n\u2022 \ud83e\udd1d Notify ops team\n",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09S57E2JQ2",
          "cachedResultName": "n8n"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "8dc8c38f-0984-415f-a523-37311b868960",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -400,
        -400
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 512,
        "content": "## Daily Revenue Check\nStarts the workflow automatically each day. It ensures the revenue check runs on schedule without any manual action and prepares the system to review daily sales performance consistently."
      },
      "typeVersion": 1
    },
    {
      "id": "6e6a5478-cdd8-4d4a-9b25-41dcd944bc57",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -32,
        -400
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 512,
        "content": "## Fetch & Filter Orders\nThis section fetches orders from WooCommerce, keeps only paid orders, and filters them to include orders from the last 24 hours. This helps ensure that only valid and recent sales data is used for revenue calculation."
      },
      "typeVersion": 1
    },
    {
      "id": "f485090f-17e4-497f-9715-c1c5579b23d6",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1568,
        -384
      ],
      "parameters": {
        "color": 7,
        "width": 672,
        "height": 496,
        "content": "## Revenue Threshold & Alerts\nThis section checks whether the total revenue from the last 24 hours has reached the set threshold. It then sends Slack notifications: one to celebrate a sales spike and another to provide a status update if the target hasn\u2019t been met, keeping the team informed."
      },
      "typeVersion": 1
    },
    {
      "id": "8b7c28bd-3c4d-4e7e-bf65-3284645890ab",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -832,
        -1392
      ],
      "parameters": {
        "width": 384,
        "height": 1504,
        "content": "## How This Workflow Works\nThe workflow runs automatically once every day using a Schedule Trigger.\n\nIt fetches recent orders from WooCommerce via the API.\n\nOnly paid orders (Completed / Processing) are considered for revenue calculations to ensure accurate sales data.\n\nOrders created within the last 24 hours are filtered using a Code node.\n\nThe workflow calculates total revenue, order count, average order value, and identifies the top-selling products for the last 24 hours.\n\nIn parallel, cancelled orders are fetched, filtered for the last 24 hours, and analyzed to calculate cancelled order count and cancelled revenue.\n\nSales data and cancellation metrics are merged and formatted into a single, structured object.\n\nAn IF node checks whether the total revenue has crossed the predefined sales threshold.\n\nIf the threshold is crossed, a Slack Sales Spike Alert is sent, including revenue, top products, and cancellation impact.\n\nIf the threshold is not reached, a Slack Status / Pending Alert is sent, showing current performance, top products, and cancellation insights to keep the team informed.\n\n## How to Set Up This Workflow\n\nAdd a Schedule Trigger to run the workflow daily.\n\nAdd a WooCommerce node to fetch all recent orders.\n\nFilter orders by Completed / Processing status.\n\nUse a Code node to filter orders from the last 24 hours.\n\nAdd Code nodes to calculate total revenue, order count, average order value, and top-selling products.\n\nAdd a separate WooCommerce branch to fetch Cancelled orders.\n\nFilter cancelled orders and limit them to the last 24 hours using a Code node.\n\nAdd a Code node to calculate cancelled order count and cancelled revenue.\n\nUse a Merge node to combine sales data and cancellation metrics into a single object.\n\nAdd an IF node to compare revenue against the defined threshold.\n\nConnect a Slack node to send a Sales Spike Alert when the threshold is met.\n\nConnect another Slack node to send a Target Not Reached / Pending Alert when the threshold is not met.\n\nTest the workflow and activate it."
      },
      "typeVersion": 1
    },
    {
      "id": "9af5b24b-8a4a-4302-8ec3-402c247c4402",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        1152,
        -96
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition",
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "a1852a73-ae5e-46c3-9427-109a4a179d99",
      "name": "Calculate Top Products (24h)",
      "type": "n8n-nodes-base.code",
      "position": [
        832,
        -208
      ],
      "parameters": {
        "jsCode": "const productMap = {};\n\n// Loop through all orders\nfor (const item of items) {\n  const order = item.json;\n\n  // Safety check\n  if (!order.line_items) continue;\n\n  // Loop through products in the order\n  for (const line of order.line_items) {\n    const name = line.name;\n    const qty = line.quantity || 0;\n\n    // Add quantity per product\n    productMap[name] = (productMap[name] || 0) + qty;\n  }\n}\n\n// Convert object to array & sort\nconst topProducts = Object.entries(productMap)\n  .sort((a, b) => b[1] - a[1])\n  .slice(0, 3);\n\n// Return final output\nreturn [\n  {\n    json: {\n      top_products: topProducts\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "3c278039-9b1c-49f4-858e-227e162c2fea",
      "name": "Format Sales Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1344,
        -112
      ],
      "parameters": {
        "jsCode": "let finalObject = {};\n\n// Loop through all merged items\nfor (const item of items) {\n  finalObject = {\n    ...finalObject,\n    ...item.json\n  };\n}\n\n// Return ONE item\nreturn [\n  {\n    json: finalObject\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "5ec1fd95-12d4-4186-88f3-8ceabec334f4",
      "name": "Progress Alert (Target Pending)",
      "type": "n8n-nodes-base.slack",
      "position": [
        1952,
        -48
      ],
      "parameters": {
        "text": "=\ud83d\ude42 *Sales Update (Last 24 Hours)*  \n\u26a0\ufe0f *Target Not Reached Yet*\n\n\ud83d\udcb0 *Revenue So Far:* \u20b9{{ $json.revenue_last_24h }}  \n\ud83c\udfaf *Target:* \u20b9100,000  \n\n\ud83e\uddfe *Orders Completed:* {{ $json.order_count }}  \n\ud83d\udcca *Avg Order Value:* \u20b9{{ $json.avg_order_value }}\n\n\ud83d\udce6 *Products Sold (Last 24h):*\n{{ $json.top_products.map(p => `\u2022 ${p[0]} \u2014 ${p[1]} unit(s)`).join('\\n') }}\n\n\u274c *Cancellations Impact (Last 24h):*\n\u2022 Orders Cancelled: {{ $json.cancelled_orders_24h }}\n\u2022 Revenue Lost: \u20b9{{ $json.cancelled_revenue_24h }}\n\n\ud83d\udca1 *Suggestions to Close the Gap:*\n\u2022 \u23f0 Push limited-time offers  \n\u2022 \ud83c\udfaf Retarget visitors who didn\u2019t convert  \n\u2022 \ud83d\udecd\ufe0f Promote best-selling products prominently  \n\n\ud83d\ude80 *Let\u2019s close the gap and hit today\u2019s target!*\n",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09S57E2JQ2",
          "cachedResultName": "n8n"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "c32134e6-4f91-4d6e-9b96-1d92031abd25",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        -400
      ],
      "parameters": {
        "color": 7,
        "width": 768,
        "height": 512,
        "content": "## 24-Hour Sales Summary\nThis section calculates the total revenue and top-selling products from the last 24 hours. It then merges and formats the data into a single object, providing a clear snapshot of recent sales performance for reporting and alerts."
      },
      "typeVersion": 1
    },
    {
      "id": "a11b6f2a-7c8f-4f9f-ab2f-5baba39578e1",
      "name": "Filter Orders from Last 24 Hours2",
      "type": "n8n-nodes-base.code",
      "position": [
        704,
        400
      ],
      "parameters": {
        "jsCode": "// 1. Current execution time (same as schedule time)\nconst now = new Date();\n\n// 2. Calculate 24 hours ago\nconst cutoff = new Date(now.getTime() - 24 * 60 * 60 * 1000);\n\n// 3. Orders coming from previous node\nconst orders = items;\n\n// 4. Filter orders from last 24 hours\nconst last24hOrders = orders.filter(order => {\n  const created = new Date(order.json.date_created);\n  return created >= cutoff;\n});\n\nreturn last24hOrders;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "f328ffd8-1b07-40d3-ab8f-79c10e39f1e9",
      "name": "Calculate Cancelled Metrics (24h)",
      "type": "n8n-nodes-base.code",
      "position": [
        944,
        400
      ],
      "parameters": {
        "jsCode": "let cancelledRevenue = 0;\nlet cancelledCount = items.length;\n\nfor (const item of items) {\n  cancelledRevenue += parseFloat(item.json.total || 0);\n}\n\nreturn [\n  {\n    json: {\n      cancelled_orders_24h: cancelledCount,\n      cancelled_revenue_24h: Number(cancelledRevenue.toFixed(2))\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "6cbb9d05-a9ec-4e17-935c-2dfbb6fd7273",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        224
      ],
      "parameters": {
        "color": 7,
        "width": 912,
        "height": 384,
        "content": "## Cancellation Monitoring (Last 24 Hours)\nThis section tracks cancelled WooCommerce orders from the last 24 hours to measure revenue loss and order drop-offs. It calculates total cancelled orders and associated revenue, helping teams identify potential issues such as payment failures, delivery concerns, or customer experience problems that may impact overall sales performance."
      },
      "typeVersion": 1
    },
    {
      "id": "cf1e0a0c-bab5-4c28-b744-28179b8872f5",
      "name": " Filter Paid Orders (Completed / Processing)",
      "type": "n8n-nodes-base.filter",
      "position": [
        480,
        400
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "77300748-aa74-40d6-a931-ec66fd86de7b",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "cancelled"
            }
          ]
        }
      },
      "typeVersion": 2.2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "cf0e3d62-c348-4992-82cd-699091d86fb1",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Format Sales Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Sales Data": {
      "main": [
        [
          {
            "node": "Revenue Spike Threshold Check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch WooCommerce Orders": {
      "main": [
        [
          {
            "node": "Filter Paid Orders (Completed / Processing)",
            "type": "main",
            "index": 0
          },
          {
            "node": " Filter Paid Orders (Completed / Processing)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Revenue Spike Monitor": {
      "main": [
        [
          {
            "node": "Fetch WooCommerce Orders",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Top Products (24h)": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Total Revenue (24h)": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Revenue Spike Threshold Check": {
      "main": [
        [
          {
            "node": "Send Slack Sales Spike Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Progress Alert (Target Pending)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Orders from Last 24 Hours": {
      "main": [
        [
          {
            "node": "Calculate Top Products (24h)",
            "type": "main",
            "index": 0
          },
          {
            "node": "Calculate Total Revenue (24h)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Cancelled Metrics (24h)": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Filter Orders from Last 24 Hours2": {
      "main": [
        [
          {
            "node": "Calculate Cancelled Metrics (24h)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Paid Orders (Completed / Processing)": {
      "main": [
        [
          {
            "node": "Filter Orders from Last 24 Hours",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    " Filter Paid Orders (Completed / Processing)": {
      "main": [
        [
          {
            "node": "Filter Orders from Last 24 Hours2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}