{
  "name": "Create and send Pennylane invoices from webhook data",
  "nodes": [
    {
      "id": "2432a919-ea99-4529-969d-2f94a9f44110",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -592,
        -272
      ],
      "parameters": {
        "width": 720,
        "height": 1376,
        "content": "# Create and send Pennylane invoices from webhook data\n\n## Who is this for\n\nSMEs and freelancers using Pennylane (French accounting platform) who want to automate invoice creation from their CRM, forms, or any business tool.\n\n## What it does\n\nThis workflow receives deal or order data via a POST webhook, searches for the customer in Pennylane (or creates one), generates a customer invoice with line items and VAT, optionally sends it by email through Pennylane, and notifies your team via Slack and/or Gmail.\n\n## How to set up\n\n1. Import this workflow into n8n\n2. Create a Header Auth credential: name `Authorization`, value `Bearer <YOUR_PENNYLANE_TOKEN>`\n3. Select your Slack channel in the SL Send Notification node\n4. (Optional) Connect your Gmail credential for email notifications\n5. Configure invoice numbering in your Pennylane settings\n6. Send a test POST request to the webhook URL\n\n## Requirements\n\n- Pennylane account with API access (Essentiel plan or higher)\n- Pennylane API token with scopes: customer_invoices:all, customers:all\n- (Optional) Slack workspace\n- (Optional) Gmail OAuth credentials\n\nFull documentation: https://github.com/Gauthier-Huguenin/n8n-pennylane-auto-invoicing\n\n---\n\n### Flow\n\n`WH Receive Invoice Data`\n  \u2192 `Code Validate Payload`\n  \u2192 `PL Search Customer`\n  \u2192 `IF Customer Exists`\n    \u2192 \u2705 `Set Customer ID`\n    \u2192 \u274c `PL Create Customer` \u2192 `Set Customer ID`\n  \u2192 `Code Build Invoice Payload`\n  \u2192 `PL Create Invoice`\n  \u2192 `IF Send Email`\n    \u2192 \u2705 `Wait PDF Generation` \u2192 `PL Send Invoice Email`\n  \u2192 `Code Build Notification`\n    \u2192 `SL Send Notification`\n    \u2192 `IF Has Notification Email`\n      \u2192 \u2705 `GM Send Notification`\n  \u2192 `Set Output Response`\n\n---\n\n### Node refs for $()\n\n- WH Receive Invoice Data\n- Code Validate Payload\n- PL Search Customer\n- IF Customer Exists\n- Set Customer ID\n- PL Create Customer\n- Code Build Invoice Payload\n- PL Create Invoice\n- IF Send Email\n- Wait PDF Generation\n- PL Send Invoice Email\n- Code Build Notification\n- SL Send Notification\n- IF Has Notification Email\n- GM Send Notification\n- Set Output Response"
      },
      "typeVersion": 1
    },
    {
      "id": "402c4d14-ab30-4baf-85b5-daec4ceb06f4",
      "name": "WH Receive Invoice Data",
      "type": "n8n-nodes-base.webhook",
      "position": [
        272,
        32
      ],
      "parameters": {
        "path": "pennylane-invoice",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "585218e8-449a-40da-8ce7-d8157998c2f7",
      "name": "Code Validate Payload",
      "type": "n8n-nodes-base.code",
      "position": [
        528,
        32
      ],
      "parameters": {
        "jsCode": "// Refs: 'WH Receive Invoice Data'\nconst input = $input.first().json;\n\nconst errors = [];\n\nif (!input.customer_name || input.customer_name.trim() === '') {\n  errors.push('customer_name is required');\n}\n\nif (!input.customer_email || !input.customer_email.includes('@')) {\n  errors.push('customer_email is required and must be valid');\n}\n\nif (!input.items || !Array.isArray(input.items) || input.items.length === 0) {\n  errors.push('items array is required and must contain at least one item');\n} else {\n  input.items.forEach((item, i) => {\n    if (!item.label) errors.push(`items[${i}].label is required`);\n    if (!item.quantity || item.quantity <= 0) errors.push(`items[${i}].quantity must be > 0`);\n    if (!item.unit_price || item.unit_price <= 0) errors.push(`items[${i}].unit_price must be > 0`);\n  });\n}\n\nif (errors.length > 0) {\n  throw new Error('Validation failed: ' + errors.join('; '));\n}\n\nreturn [{\n  json: {\n    customer_name: input.customer_name.trim(),\n    customer_email: input.customer_email.trim().toLowerCase(),\n    customer_address: input.customer_address || '',\n    customer_postal_code: input.customer_postal_code || '00000',\n    customer_city: input.customer_city || 'Non renseign\u00e9',\n    customer_country: input.customer_country || 'FR',\n    items: input.items.map(item => ({\n      label: item.label,\n      quantity: item.quantity,\n      unit_price: item.unit_price,\n      vat_rate: item.vat_rate || 'FR_200'\n    })),\n    due_date: input.due_date || new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],\n    currency: input.currency || 'EUR',\n    payment_conditions: input.payment_conditions || '30_days',\n    reference: input.reference || null,\n    send_email: input.send_email || false,\n    notification_email: input.notification_email || null\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "5440a265-819f-42d4-8c26-d83cb51eb219",
      "name": "PL Search Customer",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        832,
        32
      ],
      "parameters": {
        "url": "https://app.pennylane.com/api/external/v2/customers",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "filter",
              "value": "=[{\"field\":\"emails\",\"operator\":\"in\",\"value\":\"{{ $json.customer_email }}\"}]"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "8e9e52fa-654e-4b14-b72f-8c57b70744f7",
      "name": "IF Customer Exists",
      "type": "n8n-nodes-base.if",
      "position": [
        1040,
        32
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "85be8afd-6833-43ba-bb7b-305dd91e9a73",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.items.length }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "106b531c-143f-4de7-ba98-8ede691a0d01",
      "name": "PL Create Customer",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1248,
        128
      ],
      "parameters": {
        "url": "https://app.pennylane.com/api/external/v2/company_customers",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"name\": \"{{ $('Code Validate Payload').item.json.customer_name }}\",\n  \"emails\": [\"{{ $('Code Validate Payload').item.json.customer_email }}\"],\n  \"billing_address\": {\n    \"address\": \"{{ $('Code Validate Payload').item.json.customer_address }}\",\n    \"postal_code\": \"{{ $('Code Validate Payload').item.json.customer_postal_code }}\",\n    \"city\": \"{{ $('Code Validate Payload').item.json.customer_city }}\",\n    \"country_alpha2\": \"{{ $('Code Validate Payload').item.json.customer_country }}\"\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "49c0e376-9f63-4ded-8d0c-917cc7ddf652",
      "name": "Set Customer ID",
      "type": "n8n-nodes-base.set",
      "position": [
        1424,
        16
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "86d02b7a-27bd-4791-a4aa-02b7429dc7bd",
              "name": "=customer_id",
              "type": "string",
              "value": "={{ $json.id ?? $json.items?.[0]?.id }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "c33bd39f-5043-418c-88f9-0aaa8bc25c9d",
      "name": "PL Create Invoice",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1824,
        16
      ],
      "parameters": {
        "url": "https://app.pennylane.com/api/external/v2/customer_invoices",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify($json) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "964e6cc9-ff3c-49ab-bda0-ca842e6b380e",
      "name": "Code Build Invoice Payload",
      "type": "n8n-nodes-base.code",
      "position": [
        1648,
        16
      ],
      "parameters": {
        "jsCode": "// Refs: 'Set Customer ID', 'Code Validate Payload'\nconst data = $('Code Validate Payload').first().json;\nconst customerId = $('Set Customer ID').first().json.customer_id;\n\nconst invoiceLines = data.items.map(item => ({\n  label: item.label,\n  quantity: item.quantity,\n  unit: 'piece',\n  raw_currency_unit_price: String(item.unit_price.toFixed(2)),\n  vat_rate: item.vat_rate\n}));\n\nconst today = new Date().toISOString().split('T')[0];\n\nconst payload = {\n  customer_id: customerId,\n  date: today,\n  deadline: data.due_date,\n  currency: data.currency,\n  invoice_lines: invoiceLines,\n  draft: false\n};\n\nif (data.reference) {\n  payload.external_reference = data.reference;\n}\n\nreturn [{ json: payload }];"
      },
      "typeVersion": 2
    },
    {
      "id": "041e2680-0585-43e8-8df3-4a04b3c32fc3",
      "name": "IF Send Email",
      "type": "n8n-nodes-base.if",
      "position": [
        2064,
        16
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "de5a2cc8-def5-4777-8369-51caea43256f",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $('Code Validate Payload').item.json.send_email }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "797f431f-2ffd-42fc-afbc-f76b5806af67",
      "name": "Code Build Notification",
      "type": "n8n-nodes-base.code",
      "position": [
        2752,
        32
      ],
      "parameters": {
        "jsCode": "// Refs: 'PL Create Invoice', 'Code Validate Payload'\nconst invoice = $('PL Create Invoice').first().json;\nconst data = $('Code Validate Payload').first().json;\n\nconst message = [\n  `New invoice created in Pennylane`,\n  ``,\n  `Customer: ${data.customer_name}`,\n  `Invoice: ${invoice.invoice_number}`,\n  `Amount: ${invoice.currency_amount_before_tax} EUR HT`,\n  `Total TTC: ${invoice.currency_amount} EUR`,\n  `Due date: ${data.due_date}`,\n  `Status: ${invoice.status}`,\n  data.reference ? `Reference: ${data.reference}` : '',\n  ``,\n  `View: ${invoice.public_file_url || 'N/A'}`\n].filter(Boolean).join('\\n');\n\nreturn [{\n  json: {\n    message,\n    invoice_id: invoice.id,\n    invoice_number: invoice.invoice_number,\n    amount: invoice.currency_amount,\n    customer_name: data.customer_name,\n    public_url: invoice.public_file_url || null\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "d5f88019-04c7-43e7-a813-efbb52b954a5",
      "name": "SL Send Notification",
      "type": "n8n-nodes-base.slack",
      "position": [
        3296,
        -112
      ],
      "parameters": {
        "text": "={{ $json.message }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": ""
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "8d44a126-0a95-4283-ab89-2ebf6e40baa7",
      "name": "Set Output Response",
      "type": "n8n-nodes-base.set",
      "position": [
        3648,
        32
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "c5fe5a2e-f759-4afd-907f-eacb7251481b",
              "name": "success",
              "type": "boolean",
              "value": true
            },
            {
              "id": "03e80656-7f61-46cd-98d4-0e7daf6636d3",
              "name": "invoice_id",
              "type": "string",
              "value": "={{ $('Code Build Notification').item.json.invoice_id }}"
            },
            {
              "id": "0f54ae5d-87d0-473f-9076-3b17bc24ec0d",
              "name": "invoice_number",
              "type": "string",
              "value": "={{ $('Code Build Notification').item.json.invoice_number }}"
            },
            {
              "id": "878b0587-95ee-4b69-8853-f51c1c356dfa",
              "name": "amount",
              "type": "string",
              "value": "={{ $('Code Build Notification').item.json.amount }}"
            },
            {
              "id": "ef1c38e7-d845-4604-bb8f-908fcbbe4146",
              "name": "customer",
              "type": "string",
              "value": "={{ $('Code Build Notification').item.json.customer_name }}"
            },
            {
              "id": "93d69fa3-86ca-4f0b-8db3-94d7177c10cf",
              "name": "public_url",
              "type": "string",
              "value": "={{ $('Code Build Notification').item.json.public_url }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "f12591be-0ef5-4cc5-8232-a9058b77d8b6",
      "name": "Wait PDF Generation",
      "type": "n8n-nodes-base.wait",
      "position": [
        2288,
        -48
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "892471ed-1b8a-427c-a310-0f40ec49b632",
      "name": "PL Send Invoice Email",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2512,
        -48
      ],
      "parameters": {
        "url": "=https://app.pennylane.com/api/external/v2/customer_invoices/{{ $('PL Create Invoice').item.json.id }}/send_by_email",
        "method": "POST",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "b73e78af-3604-4d70-a583-f0074877a411",
      "name": "GM Send Notification",
      "type": "n8n-nodes-base.gmail",
      "position": [
        3216,
        176
      ],
      "parameters": {
        "sendTo": "={{ $('Code Validate Payload').item.json.notification_email }}",
        "message": "=<div style=\"font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;\">\n  <div style=\"background-color: #0f172a; padding: 24px; border-radius: 8px 8px 0 0;\">\n    <h1 style=\"color: #ffffff; margin: 0; font-size: 20px;\">New Invoice Created</h1>\n  </div>\n  <div style=\"background-color: #f8fafc; padding: 24px; border: 1px solid #e2e8f0;\">\n    <table style=\"width: 100%; border-collapse: collapse;\">\n      <tr>\n        <td style=\"padding: 8px 0; color: #64748b; font-size: 14px;\">Customer</td>\n        <td style=\"padding: 8px 0; color: #0f172a; font-size: 14px; font-weight: bold; text-align: right;\">{{ $('Code Build Notification').item.json.customer_name }}</td>\n      </tr>\n      <tr>\n        <td style=\"padding: 8px 0; color: #64748b; font-size: 14px;\">Invoice</td>\n        <td style=\"padding: 8px 0; color: #0f172a; font-size: 14px; font-weight: bold; text-align: right;\">{{ $('Code Build Notification').item.json.invoice_number }}</td>\n      </tr>\n      <tr>\n        <td style=\"padding: 8px 0; color: #64748b; font-size: 14px;\">Amount HT</td>\n        <td style=\"padding: 8px 0; color: #0f172a; font-size: 14px; font-weight: bold; text-align: right;\">{{ $('PL Create Invoice').item.json.currency_amount_before_tax }} EUR</td>\n      </tr>\n      <tr style=\"border-top: 2px solid #e2e8f0;\">\n        <td style=\"padding: 12px 0 8px; color: #64748b; font-size: 14px;\">Total TTC</td>\n        <td style=\"padding: 12px 0 8px; color: #0f172a; font-size: 18px; font-weight: bold; text-align: right;\">{{ $('Code Build Notification').item.json.amount }} EUR</td>\n      </tr>\n      <tr>\n        <td style=\"padding: 8px 0; color: #64748b; font-size: 14px;\">Due date</td>\n        <td style=\"padding: 8px 0; color: #0f172a; font-size: 14px; text-align: right;\">{{ $('Code Validate Payload').item.json.due_date }}</td>\n      </tr>\n      <tr>\n        <td style=\"padding: 8px 0; color: #64748b; font-size: 14px;\">Status</td>\n        <td style=\"padding: 8px 0; color: #0f172a; font-size: 14px; text-align: right;\">{{ $('PL Create Invoice').item.json.status }}</td>\n      </tr>\n    </table>\n  </div>\n  <div style=\"padding: 16px 24px; background-color: #ffffff; border: 1px solid #e2e8f0; border-top: none; border-radius: 0 0 8px 8px; text-align: center;\">\n    <a href=\"{{ $('Code Build Notification').item.json.public_url }}\" style=\"display: inline-block; background-color: #0f172a; color: #ffffff; text-decoration: none; padding: 10px 24px; border-radius: 6px; font-size: 14px; font-weight: bold;\">View Invoice PDF</a>\n  </div>\n  <p style=\"color: #94a3b8; font-size: 12px; text-align: center; margin-top: 16px;\">Sent automatically by n8n-pennylane-auto-invoicing</p>\n</div>",
        "options": {},
        "subject": "=[Pennylane] Invoice {{ $('Code Build Notification').item.json.invoice_number }} created for {{ $('Code Build Notification').item.json.customer_name }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "88c6cf59-4ad7-4872-a7b1-116590237115",
      "name": "IF Has Notification Email",
      "type": "n8n-nodes-base.if",
      "position": [
        2992,
        96
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "94e188dc-d883-4a77-aac1-06b5bed2dbff",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $('Code Validate Payload').item.json.notification_email }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "adf964cd-ccdd-44c7-aaa3-4b035df2fa44",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        192,
        -272
      ],
      "parameters": {
        "color": 5,
        "height": 624,
        "content": "## 1. Input\n\nReceives invoice data via POST webhook.\nAny CRM, form, or script can call this endpoint.\n\nSee `examples/` folder in the GitHub repo\nfor sample payloads."
      },
      "typeVersion": 1
    },
    {
      "id": "50f9b391-c5ba-4b8e-8738-687added6648",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        432,
        -272
      ],
      "parameters": {
        "color": 5,
        "width": 304,
        "height": 624,
        "content": "## 2. Validation\n\nChecks required fields:\n- customer_name\n- customer_email\n- items[] with label, quantity, unit_price\n\nApplies defaults:\n- country: FR\n- currency: EUR\n- vat_rate: FR_200\n- due_date: +30 days\n- payment_conditions: 30_days"
      },
      "typeVersion": 1
    },
    {
      "id": "6e1dd244-3c60-405c-ae59-f1dc8a60a63c",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        -272
      ],
      "parameters": {
        "color": 3,
        "width": 832,
        "height": 624,
        "content": "## 3. Customer lookup\n\nSearches Pennylane for an existing customer\nby email. Creates one if not found.\n\nEndpoint: GET /customers (filter by emails)\nEndpoint: POST /company_customers\n\nRequired billing_address fields:\naddress, postal_code, city, country_alpha2"
      },
      "typeVersion": 1
    },
    {
      "id": "4a4c4708-448f-4b1c-9a21-ba0bcdf1f6ca",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1568,
        -272
      ],
      "parameters": {
        "color": 3,
        "width": 432,
        "height": 624,
        "content": "## 4. Invoice creation\n\nBuilds the invoice payload with line items,\nVAT, and deadline, then sends it to Pennylane.\n\nEndpoint: POST /customer_invoices\n\nAmounts must be strings (e.g. \"1500.00\").\nVAT codes: FR_200 (20%), FR_100 (10%),\nFR_055 (5.5%), exempt (0%).\n\nSet draft: true to create without finalizing."
      },
      "typeVersion": 1
    },
    {
      "id": "53f73bb0-8e6f-4f4d-bf16-89af06cfa1bc",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2000,
        -272
      ],
      "parameters": {
        "color": 4,
        "width": 672,
        "height": 624,
        "content": "## 5. Email sending (optional)\n\nIf send_email is true in the payload,\nwaits 30s for PDF generation, then sends\nthe invoice to the customer via Pennylane.\n\nEndpoint: POST /customer_invoices/{id}/send_by_email\n\nA 409 means the PDF is not ready yet."
      },
      "typeVersion": 1
    },
    {
      "id": "83320de8-8149-4bc1-b58d-c20c20b7b549",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2672,
        -272
      ],
      "parameters": {
        "color": 4,
        "width": 800,
        "height": 624,
        "content": "## 6. Notifications\n\nSlack: always sends a summary to your channel.\nGmail: sends an HTML notification if\nnotification_email is provided in the payload.\n\nBoth are optional. Remove or replace\nwith your preferred channel (Telegram, etc.)."
      },
      "typeVersion": 1
    },
    {
      "id": "bfbe45e4-cacc-4784-a309-b378ed99a2ce",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3472,
        -272
      ],
      "parameters": {
        "color": 5,
        "width": 368,
        "height": 624,
        "content": "## 7. Webhook response\n\nReturns a JSON response to the caller with:\n- success: true/false\n- invoice_id\n- invoice_number\n- amount\n- customer\n- public_url (link to PDF)\n\nConfigure Error Workflow in Settings\nfor production error handling."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "callerPolicy": "workflowsFromSameOwner",
    "timeSavedMode": "fixed",
    "availableInMCP": true,
    "executionOrder": "v1",
    "timeSavedPerExecution": 5
  },
  "connections": {
    "IF Send Email": {
      "main": [
        [
          {
            "node": "Wait PDF Generation",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Code Build Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Customer ID": {
      "main": [
        [
          {
            "node": "Code Build Invoice Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PL Create Invoice": {
      "main": [
        [
          {
            "node": "IF Send Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Customer Exists": {
      "main": [
        [
          {
            "node": "Set Customer ID",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "PL Create Customer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PL Create Customer": {
      "main": [
        [
          {
            "node": "Set Customer ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PL Search Customer": {
      "main": [
        [
          {
            "node": "IF Customer Exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait PDF Generation": {
      "main": [
        [
          {
            "node": "PL Send Invoice Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GM Send Notification": {
      "main": [
        [
          {
            "node": "Set Output Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SL Send Notification": {
      "main": [
        [
          {
            "node": "Set Output Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code Validate Payload": {
      "main": [
        [
          {
            "node": "PL Search Customer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PL Send Invoice Email": {
      "main": [
        [
          {
            "node": "Code Build Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code Build Notification": {
      "main": [
        [
          {
            "node": "SL Send Notification",
            "type": "main",
            "index": 0
          },
          {
            "node": "IF Has Notification Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "WH Receive Invoice Data": {
      "main": [
        [
          {
            "node": "Code Validate Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Has Notification Email": {
      "main": [
        [
          {
            "node": "GM Send Notification",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set Output Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code Build Invoice Payload": {
      "main": [
        [
          {
            "node": "PL Create Invoice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}