AutomationFlowsEmail & Gmail › Create and Send Pennylane Invoices From Webhook Data with Slack and Gmail Alerts

Create and Send Pennylane Invoices From Webhook Data with Slack and Gmail Alerts

ByGauthier Huguenin @gauthier-huguenin on n8n.io

SMEs and freelancers using Pennylane (the leading French accounting platform) who want to automate invoice creation from their CRM, forms, or any business tool.

Webhook trigger★★★★☆ complexity24 nodesHTTP RequestSlackGmail
Email & Gmail Trigger: Webhook Nodes: 24 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #15186 — we link there as the canonical source.

This workflow follows the Gmail → 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 →

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

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

SMEs and freelancers using Pennylane (the leading French accounting platform) who want to automate invoice creation from their CRM, forms, or any business tool.

Source: https://n8n.io/workflows/15186/ — original creator credit. Request a take-down →

More Email & Gmail workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Email & Gmail

Suspicious_login_detection. Uses postgres, httpRequest, noOp, html. Webhook trigger; 43 nodes.

Postgres, HTTP Request, Gmail +1
Email & Gmail

This n8n workflow is designed for security monitoring and incident response when suspicious login events are detected. It can be initiated either manually from within the n8n UI for testing or automat

Postgres, HTTP Request, Gmail +1
Email & Gmail

Receive inventory movements via webhook, validate data, update stock levels, and trigger automatic alerts when products need reordering.

HTTP Request, Slack, Gmail +1
Email & Gmail

Wait. Uses httpRequest, itemLists, slack, gmail. Webhook trigger; 29 nodes.

HTTP Request, Item Lists, Slack +2
Email & Gmail

Receive support tickets via webhook, categorize by priority, track SLA deadlines, notify your team on Slack, and send confirmation emails to customers.

HTTP Request, Slack, Gmail +1