Génération de factures pour les clients en utilisant Jotform, Xero et Slack

Avancé

Ceci est uncontenant 20 nœuds.Utilise principalement des nœuds comme If, Code, Xero, Slack, Webhook. Automatisation de la génération et de l'envoi de factures par e-mail avec Jotform, Xero et GPT-4o-mini

Prérequis
  • Token Bot Slack ou URL Webhook
  • Point de terminaison HTTP Webhook (généré automatiquement par n8n)
  • Clé API OpenAI

Catégorie

-
Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "id": "X2u0Wnuo2Yp8dSaq",
  "meta": {
    "instanceId": "3549451ca835035557d5dc1c3d9e6ba924e7314534a74c901f66b91f9ef6023e",
    "templateCredsSetupCompleted": true
  },
  "name": "Generate Invoices for Customers with Jotform, Xero and Slack",
  "tags": [],
  "nodes": [
    {
      "id": "5153a36b-decc-4145-bfb5-903123d3ed32",
      "name": "Recevoir la soumission du formulaire",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -464,
        0
      ],
      "webhookId": "dac28968-ec17-41da-b720-c579c1a7169b",
      "parameters": {
        "path": "dac28968-ec17-41da-b720-c579c1a7169b",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "a4e41795-f814-4f53-ae06-c004d9f2fe61",
      "name": "Note adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -544,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 256,
        "height": 320,
        "content": "## Receive Submission\nReceives the product/service form submission from Jotform"
      },
      "typeVersion": 1
    },
    {
      "id": "5d0f264c-57ab-4aa8-93a9-4a45a2ffe060",
      "name": "Note adhésive 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        512,
        80
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 320,
        "content": "## Create Contact\nCreates a new contact"
      },
      "typeVersion": 1
    },
    {
      "id": "601c08b9-547d-4883-bdc0-c0e2725fb5c9",
      "name": "Note adhésive 5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        848,
        -96
      ],
      "parameters": {
        "color": 7,
        "width": 256,
        "height": 320,
        "content": "## Create The Invoice\nCreates a new invoice for that contact"
      },
      "typeVersion": 1
    },
    {
      "id": "87296102-7ff7-4a22-a451-40749a219450",
      "name": "Note adhésive 7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1328,
        -480
      ],
      "parameters": {
        "width": 736,
        "height": 992,
        "content": "## Generate Invoices for Customers with Jotform, Xero and Slack\nThis workflow automates the entire process of receiving a product/service order, checking or creating a customer in **Xero**, generating an invoice, emailing it, and notifying the sales team for example (via **Slack**)  — all triggered by a form submission (via **Jotform**).\n\n## How It Works\n### 1- Receive Submission\n* Triggered when a user submits a form.\n* Collects data like customer details, selected product/service, etc.\n\n### 2- Check If Customer Exists\n* Searches Xero to determine if the customer already exists.\n* ✅ **If Customer Exists:** **Update** customer details.\n* ❌ **If Customer Doesn’t Exist:** **Create** a new customer in Xero.\n\n### 3- Create The Invoice\n* Generates a new invoice for the customer using the item selected.\n\n### 4- Send The Invoice\n* Automatically sends the invoice via email to the customer.\n\n### 5- Notify The Team\n* Notifies the sales team for example via Slack about the new invoice.\n\n## Who Can Benefit from This Workflow?\n* **Freelancers**\n* **Service Providers**\n* **Consultants & Coaches**\n* **Small Businesses**\n* **E-commerce or Custom Product Sellers**\n\n## Requirements\n- Jotform webhook setup, more info [here](https://www.jotform.com/help/245-how-to-setup-a-webhook-with-jotform/)\n- Xero credentials, more info [here](https://docs.n8n.io/integrations/builtin/credentials/xero)\n- Make sure that products/services values in Jotform are exactly the same as your item `Code` in your Xero account\n- Email setup, update email node (`Send email`)\n- LLM model credentials\n- Slack credentials, more info [here](https://docs.n8n.io/integrations/builtin/credentials/slack)"
      },
      "typeVersion": 1
    },
    {
      "id": "bea06527-f4fb-4c06-acec-80e540753990",
      "name": "Note adhésive 8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 256,
        "height": 320,
        "content": "## Format Data\nFormats the data thus making it easier to be used in other nodes"
      },
      "typeVersion": 1
    },
    {
      "id": "6f8c1525-ee7e-4d10-a0c0-641abe512e47",
      "name": "Formater les données",
      "type": "n8n-nodes-base.code",
      "position": [
        -160,
        0
      ],
      "parameters": {
        "jsCode": "function extractAddressData(text) {\n  const regex = /Street Address:\\s*([^<]+)<br>Street Address Line 2:\\s*([^<]+)<br>City:\\s*([^<]+)<br>State \\/ Province:\\s*([^<]+)<br>Postal \\/ Zip Code:\\s*([^<]+)<br>Country:\\s*([^<]+)<br>/;\n  const matches = text.match(regex);\n  \n  if (matches) {\n    return {\n      line1: matches[1].trim(),\n      line2: matches[2].trim(),\n      city: matches[3].trim(),\n      stateProvince: matches[4].trim(),\n      postalZipCode: matches[5].trim(),\n      country: matches[6].trim()\n    };\n  }\n  \n  return {\n    line1: null,\n    line2: null,\n    city: null,\n    stateProvince: null,\n    postalZipCode: null,\n    country: null\n  }\n}\n\nreturn {\n  address: extractAddressData($input.first().json.body.billingAddress),\n  customer: {\n    name: $input.first().json.body.name,\n    email: $input.first().json.body.email,\n    phone: $input.first().json.body.phone\n  },\n  item: {\n    name: $input.first().json.body.itemName\n  }\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "57002967-0cc2-416a-9b2d-5e0d7425e173",
      "name": "Créer la facture",
      "type": "n8n-nodes-base.xero",
      "position": [
        928,
        16
      ],
      "parameters": {
        "type": "ACCREC",
        "contactId": "={{ $json.ContactID }}",
        "lineItemsUi": {
          "lineItemsValues": [
            {
              "taxType": "INPUT",
              "itemCode": "={{ $('Format data').item.json.item.name }}",
              "unitAmount": "10",
              "accountCode": "200"
            }
          ]
        },
        "organizationId": "bc9a44a6-eb14-4f81-b24c-ca676c506446",
        "additionalFields": {}
      },
      "credentials": {
        "xeroOAuth2Api": {
          "id": "HZnbTfrr5leqrLUQ",
          "name": "Xero account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "606e45ad-d5b6-4a96-ac41-d2fd73bad8d3",
      "name": "Agent IA",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1280,
        -352
      ],
      "parameters": {
        "text": "={{ $json }}",
        "options": {
          "systemMessage": "=You are an AI assistant that generates a professional invoice email that you get from an Xero response (newly created invoice), so you will recive an Xero invoice response and thus your job is to create a professional html email content because this html email content will be sent to the customer."
        },
        "promptType": "define"
      },
      "executeOnce": false,
      "typeVersion": 2.2
    },
    {
      "id": "486a7fee-acd9-46ad-bf2b-1bc815bfb2a4",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1280,
        -144
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "ns8LVe1zpSS3Kw9p",
          "name": "OpenAi account"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "da747ce1-ddcf-4c40-a78d-452d68cac37b",
      "name": "Note adhésive 19",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1168,
        -480
      ],
      "parameters": {
        "color": 7,
        "width": 592,
        "height": 480,
        "content": "## Send The Invoice\nSends the newly created invoice for that customer(via email)"
      },
      "typeVersion": 1
    },
    {
      "id": "0873e856-7c8a-46cf-b7d1-c7a75afb0c6a",
      "name": "Envoyer l'email",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        1552,
        -352
      ],
      "webhookId": "8f9ba8d7-7a97-4926-b640-8dc93c30eed8",
      "parameters": {
        "html": "={{ $json.output }}",
        "options": {},
        "subject": "=New Invoice",
        "toEmail": "={{ $('Create the invoice').item.json.Contact.EmailAddress }}",
        "fromEmail": "system@example.com"
      },
      "credentials": {
        "smtp": {
          "id": "awV8UBK3MYzosMxe",
          "name": "Mailtrap SMTP account"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "1af9a24d-7ac1-47b4-a17a-2774f01c860c",
      "name": "Note adhésive 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        64,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 320,
        "content": "## Check If Contact exists \nChecks if the contact exists in Xero or not"
      },
      "typeVersion": 1
    },
    {
      "id": "994373c3-4f87-48cc-a30e-d34b0b345f12",
      "name": "Vérifier si le client existe",
      "type": "n8n-nodes-base.xero",
      "position": [
        128,
        0
      ],
      "parameters": {
        "limit": 1,
        "options": {
          "where": "=EmailAddress=\"{{ $json.customer.email }}\""
        },
        "resource": "contact",
        "operation": "getAll",
        "organizationId": "bc9a44a6-eb14-4f81-b24c-ca676c506446"
      },
      "credentials": {
        "xeroOAuth2Api": {
          "id": "HZnbTfrr5leqrLUQ",
          "name": "Xero account"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "14c4b4df-ce15-4e52-a89e-5a92db87b86b",
      "name": "Si",
      "type": "n8n-nodes-base.if",
      "position": [
        304,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "bfa24559-7702-4ebf-909d-c5c2a60ad817",
              "operator": {
                "type": "object",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json }}",
              "rightValue": 0
            },
            {
              "id": "b4301cfe-a22a-490f-a72b-50d266bc1c5e",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.ContactID }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "b6eb0744-cb7e-4676-91d5-6272ceb21924",
      "name": "Créer un nouveau contact",
      "type": "n8n-nodes-base.xero",
      "position": [
        608,
        192
      ],
      "parameters": {
        "name": "={{ $('Format data').item.json.customer.name }}",
        "resource": "contact",
        "organizationId": "bc9a44a6-eb14-4f81-b24c-ca676c506446",
        "additionalFields": {
          "phonesUi": {
            "phonesValues": [
              {
                "phoneType": "MOBILE",
                "phoneNumber": "={{ $('Format data').item.json.customer.phone }}"
              }
            ]
          },
          "addressesUi": {
            "addressesValues": [
              {
                "city": "={{ $('Format data').item.json.address.city }}",
                "type": "STREET",
                "line1": "={{ $('Format data').item.json.address.line1 }}",
                "line2": "={{ $('Format data').item.json.address.line2 }}",
                "region": "={{ $('Format data').item.json.address.stateProvince }}",
                "country": "={{ $('Format data').item.json.address.country }}",
                "postalCode": "={{ $('Format data').item.json.address.postalZipCode }}"
              }
            ]
          },
          "emailAddress": "={{ $('Format data').item.json.customer.email }}"
        }
      },
      "credentials": {
        "xeroOAuth2Api": {
          "id": "HZnbTfrr5leqrLUQ",
          "name": "Xero account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c035f5c2-0822-4b73-b553-4a06c39bc867",
      "name": "Note adhésive 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        512,
        -304
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 320,
        "content": "## Update Contact\nUpdates the contact"
      },
      "typeVersion": 1
    },
    {
      "id": "bc245137-a2fa-4817-bf79-e6bd0bcd4688",
      "name": "Mettre à jour le contact",
      "type": "n8n-nodes-base.xero",
      "position": [
        608,
        -192
      ],
      "parameters": {
        "resource": "contact",
        "contactId": "={{ $json.ContactID }}",
        "operation": "update",
        "updateFields": {
          "name": "={{ $('Format data').item.json.customer.name }}",
          "phonesUi": {
            "phonesValues": [
              {
                "phoneType": "MOBILE",
                "phoneNumber": "={{ $('Format data').item.json.customer.phone }}"
              }
            ]
          }
        },
        "organizationId": "bc9a44a6-eb14-4f81-b24c-ca676c506446"
      },
      "credentials": {
        "xeroOAuth2Api": {
          "id": "HZnbTfrr5leqrLUQ",
          "name": "Xero account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ecf29c2f-7e91-41d1-a99b-8a2de86b7ce0",
      "name": "Note adhésive 6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1168,
        112
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 320,
        "content": "## Notify The Team\nNotifies the team (sales team for example) about the new invoice"
      },
      "typeVersion": 1
    },
    {
      "id": "09ccbef2-8aa7-4b19-8e8b-86d6aa647298",
      "name": "Notifier l'équipe",
      "type": "n8n-nodes-base.slack",
      "position": [
        1264,
        240
      ],
      "webhookId": "e19cadcc-f539-4184-8451-9923be34b8ca",
      "parameters": {
        "text": "=<!channel> A new invoice with the below details have bene created:\n*Invoice Number:* {{ $json.InvoiceNumber }}\n*Amount Due:* {{ $json.AmountDue }} ({{ $json.CurrencyCode }})\n*Status:* {{ $json.Status }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "#test"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "id": "mRsbuKKHsrN3Qgaj",
          "name": "Slack account"
        }
      },
      "typeVersion": 2.3
    }
  ],
  "active": false,
  "pinData": {
    "Receive form submission": [
      {
        "json": {
          "body": {
            "name": "Adrian Mathews",
            "email": "yoled82772@elygifts.com",
            "phone": "(116) 777-9916",
            "itemName": "Design",
            "billingAddress": "Street Address: Nulla quia debitis est quam facilis amet enim cupidatat officia autem consequatur qui quis dolorem<br>Street Address Line 2: Possimus perferendis ad veritatis quia animi<br>City: Voluptatibus eveniet harum unde dolor doloremque cumque dol<br>State / Province: Reprehenderit rerum voluptas magni ut minim ad deleniti eni<br>Postal / Zip Code: 17167<br>Country: Seychelles<br>"
          }
        }
      }
    ]
  },
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "f403ca7a-cd06-4122-ab76-c7cbc0f93d93",
  "connections": {
    "14c4b4df-ce15-4e52-a89e-5a92db87b86b": {
      "main": [
        [
          {
            "node": "bc245137-a2fa-4817-bf79-e6bd0bcd4688",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "b6eb0744-cb7e-4676-91d5-6272ceb21924",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "606e45ad-d5b6-4a96-ac41-d2fd73bad8d3": {
      "main": [
        [
          {
            "node": "0873e856-7c8a-46cf-b7d1-c7a75afb0c6a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6f8c1525-ee7e-4d10-a0c0-641abe512e47": {
      "main": [
        [
          {
            "node": "994373c3-4f87-48cc-a30e-d34b0b345f12",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bc245137-a2fa-4817-bf79-e6bd0bcd4688": {
      "main": [
        [
          {
            "node": "57002967-0cc2-416a-9b2d-5e0d7425e173",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "486a7fee-acd9-46ad-bf2b-1bc815bfb2a4": {
      "ai_languageModel": [
        [
          {
            "node": "606e45ad-d5b6-4a96-ac41-d2fd73bad8d3",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "b6eb0744-cb7e-4676-91d5-6272ceb21924": {
      "main": [
        [
          {
            "node": "57002967-0cc2-416a-9b2d-5e0d7425e173",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "57002967-0cc2-416a-9b2d-5e0d7425e173": {
      "main": [
        [
          {
            "node": "606e45ad-d5b6-4a96-ac41-d2fd73bad8d3",
            "type": "main",
            "index": 0
          },
          {
            "node": "09ccbef2-8aa7-4b19-8e8b-86d6aa647298",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5153a36b-decc-4145-bfb5-903123d3ed32": {
      "main": [
        [
          {
            "node": "6f8c1525-ee7e-4d10-a0c0-641abe512e47",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "994373c3-4f87-48cc-a30e-d34b0b345f12": {
      "main": [
        [
          {
            "node": "14c4b4df-ce15-4e52-a89e-5a92db87b86b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Avancé

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds20
Catégorie-
Types de nœuds9
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34