{
  "id": "9JUfq4EIsoSRjZmS",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Weekly WooCommerce Finance KPI Automation with HTTP APIs & Slack",
  "tags": [],
  "nodes": [
    {
      "id": "3f54a9aa-e7a6-4a84-bd75-b9d4ce1826ff",
      "name": "Weekly KPI Scheduler",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        256,
        416
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 10
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "2bf5cde8-0168-4bb7-8072-850d8fbdbaa2",
      "name": "Configure WooCommerce Store",
      "type": "n8n-nodes-base.set",
      "position": [
        448,
        416
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "3430ea5f-30bf-46ee-9c2f-3ce12af176ca",
              "name": "wc_domain",
              "type": "string",
              "value": ""
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "29bb5e64-1f35-410c-bd7e-947b157a0985",
      "name": "Fetch WooCommerce Orders",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        832,
        208
      ],
      "parameters": {
        "url": "=https://{{$json.wc_domain}}/wp-json/wc/v3/orders",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth"
      },
      "credentials": {
        "httpBasicAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "9c533720-39af-4356-bde2-15beea052073",
      "name": "Filter Completed Orders",
      "type": "n8n-nodes-base.filter",
      "position": [
        1040,
        208
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "762ed53a-b695-4259-beb5-e33b7a4bf1c7",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "completed"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "8c61be2c-2990-40e5-ac02-77200fb0bc1d",
      "name": "Normalize Order Data",
      "type": "n8n-nodes-base.set",
      "position": [
        1232,
        208
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "9e8a7b94-40b8-48cc-8164-933ec9ca5080",
              "name": "order_id",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "8ab3f584-2589-4f10-9a66-45e35ec4d924",
              "name": "order_date",
              "type": "string",
              "value": "={{ $json.date_created }}"
            },
            {
              "id": "ee7783a6-c341-4115-a1e8-9a7606bd530c",
              "name": "order_total",
              "type": "string",
              "value": "={{ $json.total }}"
            },
            {
              "id": "71f02e7d-3517-44ba-818d-5fc02349d919",
              "name": "line_items",
              "type": "array",
              "value": "={{ $json.line_items }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "0152d7b7-5e0d-4f26-8b13-df64570cd99a",
      "name": "Fetch WooCommerce Refunds",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        912,
        560
      ],
      "parameters": {
        "url": "=https://{{ $('Configure WooCommerce Store').item.json.wc_domain }}/wp-json/wc/v3/refunds",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth"
      },
      "credentials": {
        "httpBasicAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "df2a22ab-ce71-4b11-89a6-fde6a627be9c",
      "name": "Normalize Refund Data",
      "type": "n8n-nodes-base.set",
      "position": [
        1120,
        560
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0205f680-86cd-47b1-83c0-9ee4757cde4f",
              "name": "refund_id",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "3db527e1-2731-4ed8-9da4-f77a75fde78d",
              "name": "order_id",
              "type": "string",
              "value": "={{ $json.parent_id }}"
            },
            {
              "id": "3a0bead2-1b8d-477c-bd3d-67abc4ec6ab2",
              "name": "refund_amount",
              "type": "number",
              "value": "={{ $json.amount }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "3f851e5d-a896-4adb-9718-dd85de31b4b7",
      "name": "Combine Orders & Refunds",
      "type": "n8n-nodes-base.merge",
      "position": [
        1680,
        384
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "5672e8f5-04d6-4783-b20d-bec7fce37b1a",
      "name": "Calculate Finance KPIs",
      "type": "n8n-nodes-base.code",
      "position": [
        1872,
        384
      ],
      "parameters": {
        "jsCode": "// Get inputs\nconst orders = $input.all(0).map(i => i.json);\nconst refundsRaw = $input.all(1).map(i => i.json);\n\n// --------------------\n// 1. SALES KPIs\n// --------------------\nlet totalSalesAmount = 0;\nlet totalOrderCount = orders.length;\n\nfor (const order of orders) {\n  totalSalesAmount += Number(order.order_total || 0);\n}\n\n// --------------------\n// 2. REFUND KPIs (Deduplicate)\n// --------------------\nconst refundMap = new Map();\n\nfor (const refund of refundsRaw) {\n  if (!refundMap.has(refund.refund_id)) {\n    refundMap.set(refund.refund_id, refund);\n  }\n}\n\nconst refunds = Array.from(refundMap.values());\n\nlet totalRefundAmount = 0;\nlet totalRefundCount = refunds.length;\n\nfor (const refund of refunds) {\n  totalRefundAmount += Number(refund.refund_amount || 0);\n}\n\n// --------------------\n// 3. RATIOS (Safe Divide)\n// --------------------\nconst refundRatioAmount =\n  totalSalesAmount > 0\n    ? ((totalRefundAmount / totalSalesAmount) * 100).toFixed(2)\n    : 0;\n\nconst refundRatioCount =\n  totalOrderCount > 0\n    ? ((totalRefundCount / totalOrderCount) * 100).toFixed(2)\n    : 0;\n\n// --------------------\n// 4. FLAGS / RISK INDICATORS\n// --------------------\nconst flags = [];\n\nif (refundRatioAmount > 10) {\n  flags.push(\"High refund ratio (>10%)\");\n}\n\nif (totalRefundAmount > totalSalesAmount) {\n  flags.push(\"Refund amount exceeds sales\");\n}\n\nif (totalSalesAmount === 0 && totalRefundAmount > 0) {\n  flags.push(\"Refunds exist with zero sales\");\n}\n\n// --------------------\n// 5. CFO SUMMARY OBJECT\n// --------------------\nreturn [\n  {\n    json: {\n      total_sales_amount: totalSalesAmount,\n      total_order_count: totalOrderCount,\n      total_refund_amount: totalRefundAmount,\n      total_refund_count: totalRefundCount,\n      refund_ratio_amount_pct: refundRatioAmount,\n      refund_ratio_count_pct: refundRatioCount,\n      flags,\n      period_generated_at: new Date().toISOString()\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "e616ddbe-2de2-4e70-9e82-dbab66b71619",
      "name": "Send Weekly KPI Digest to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        2080,
        384
      ],
      "parameters": {
        "text": "=\ud83d\udcca Weekly WooCommerce Finance KPI Digest\nPeriod Generated: {{ $json.period_generated_at }}\n\n\ud83d\udcb0 Sales Performance\n\u2022 Total Sales Amount:{{ $json.total_sales_amount }}\n\u2022 Total Orders: {{ $json.total_order_count }}\n\n\ud83d\udd01 Refund Overview\n\u2022 Total Refund Amount: \u20b9{{ $json.total_refund_amount }}\n\u2022 Total Refund Count: {{ $json.total_refund_count }}\n\n\ud83d\udcc9 Key Ratios\n\u2022 Refund-to-Sales Ratio (Amount): {{ $json.refund_ratio_amount_pct }}%\n\u2022 Refund-to-Order Ratio (Count): {{ $json.refund_ratio_count_pct }}%\n\n\ud83d\udea8 Risk Alerts\n{{ $json.flags }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09S57E2JQ2",
          "cachedResultName": "n8n"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "f70ac891-a5b2-42af-b4b3-754ee12e4ccd",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        176,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 368,
        "content": "## Schedule & Store Setup\nThis section controls when the workflow runs and which WooCommerce store it connects to. The scheduler triggers the automation on a weekly basis, while the store configuration ensures all API requests point to the correct WooCommerce domain."
      },
      "typeVersion": 1
    },
    {
      "id": "d6fac5fa-9707-4c4d-8619-91c6a058e896",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        768,
        48
      ],
      "parameters": {
        "color": 7,
        "width": 704,
        "height": 336,
        "content": "## Order Data Collection & Preparation\nThis section fetches order data from WooCommerce and prepares it for financial analysis. Only completed or paid orders are considered as valid sales. The data is cleaned and structured so totals, dates and line items can be used reliably for KPI calculations."
      },
      "typeVersion": 1
    },
    {
      "id": "6d398e77-8a73-4a25-bc98-38d798b93862",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        768,
        432
      ],
      "parameters": {
        "color": 7,
        "width": 704,
        "height": 304,
        "content": "## Refund Data Collection & Preparation\nThis section retrieves refund information from WooCommerce and formats it for analysis. Refund records are cleaned and standardized so refund amounts and counts can be accurately calculated and compared against sales data in later steps."
      },
      "typeVersion": 1
    },
    {
      "id": "42c83350-9e59-43f2-bf4f-cca80528858a",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1568,
        240
      ],
      "parameters": {
        "color": 7,
        "width": 784,
        "height": 352,
        "content": "## KPI Calculation & Executive Reporting\nThis final section combines sales and refund data to calculate key financial KPIs such as refund ratios and risk indicators. A concise, CFO-ready summary is then generated and automatically sent to Slack, providing leadership with clear weekly insights."
      },
      "typeVersion": 1
    },
    {
      "id": "9e901f1a-488d-45d8-b742-024f69476e86",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -416,
        -544
      ],
      "parameters": {
        "width": 480,
        "height": 1008,
        "content": "## How It Works\nThe workflow runs automatically on a weekly schedule using a Cron trigger.\n\nIt connects to your WooCommerce store and fetches all completed orders within the selected time period.\n\nOrder data is cleaned and normalized to extract only relevant finance fields such as order total and order count.\n\nIn parallel, the workflow fetches refund data from WooCommerce and removes duplicate refund records.\n\nBoth datasets are then combined to calculate key finance KPIs like total sales, total refunds and refund ratios.\n\nRisk indicators are added automatically when refund values cross predefined thresholds.\n\nFinally, a clear weekly KPI summary is generated and sent to Slack for easy review by finance and leadership teams.\n\n## Setup Steps\n\n### Cron Schedule:\nConfigure the Weekly KPI Scheduler node to define when the report should run (for example, every Monday morning).\n\n### WooCommerce Domain:\nSet your store URL in the Configure WooCommerce Store node so all API requests target the correct site.\n\n### WooCommerce API Access:\nAdd your WooCommerce Consumer Key and Consumer Secret to the Fetch Orders and Fetch Refunds HTTP Request nodes using authentication.\n\n### Data Processing Nodes:\nNo configuration is required for the filter and normalize nodes unless you want to customize fields or calculations.\n\n### Slack Integration:\nConnect your Slack account in the Send Weekly KPI Digest to Slack node and select the channel where reports should be posted.\n\n### Activate Workflow:\nEnable the workflow to start receiving automated weekly WooCommerce sales and refund KPI updates."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "d7712e4f-6149-45d8-98e7-44157ab4561b",
  "connections": {
    "Normalize Order Data": {
      "main": [
        [
          {
            "node": "Combine Orders & Refunds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weekly KPI Scheduler": {
      "main": [
        [
          {
            "node": "Configure WooCommerce Store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Refund Data": {
      "main": [
        [
          {
            "node": "Combine Orders & Refunds",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Calculate Finance KPIs": {
      "main": [
        [
          {
            "node": "Send Weekly KPI Digest to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Completed Orders": {
      "main": [
        [
          {
            "node": "Normalize Order Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine Orders & Refunds": {
      "main": [
        [
          {
            "node": "Calculate Finance KPIs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch WooCommerce Orders": {
      "main": [
        [
          {
            "node": "Filter Completed Orders",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch WooCommerce Refunds": {
      "main": [
        [
          {
            "node": "Normalize Refund Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configure WooCommerce Store": {
      "main": [
        [
          {
            "node": "Fetch WooCommerce Orders",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch WooCommerce Refunds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}