Génération et livraison automatiques de factures pour les commandes JotForm

Intermédiaire

Ceci est uncontenant 14 nœuds.Utilise principalement des nœuds comme Code, Gmail, GoogleDrive, HttpRequest, JotFormTrigger. Génération de factures à partir de JotForm, conversion en PDF, sauvegarde sur Google Drive et envoi par e-mail

Prérequis
  • Compte Google et informations d'identification Gmail API
  • Informations d'identification Google Drive API
  • Peut nécessiter les informations d'identification d'authentification de l'API cible

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": "Rrs4ZCaJZKAZIHKG",
  "meta": {
    "instanceId": "277842713620d9f5554de3b1518b865a152c8c4db680008bd8aec536fc18b4a8"
  },
  "name": "Automated Invoice Generation & Delivery for JotForm Orders",
  "tags": [
    {
      "id": "CWardZYJBmejoyC4",
      "name": "under review",
      "createdAt": "2025-10-09T18:43:37.031Z",
      "updatedAt": "2025-10-09T18:43:37.031Z"
    }
  ],
  "nodes": [
    {
      "id": "99ab3063-af31-4701-890f-67b42ed901f6",
      "name": "Formater les données de facture",
      "type": "n8n-nodes-base.code",
      "position": [
        -160,
        496
      ],
      "parameters": {
        "jsCode": "// Extract and format order data for invoice\nconst orderData = $input.first().json.body;\n\n// Calculate totals\nconst lineItems = orderData.line_items.map(item => ({\n  name: item.name,\n  quantity: item.quantity,\n  price: parseFloat(item.price),\n  total: parseFloat(item.price) * item.quantity,\n  sku: item.sku || 'N/A'\n}));\n\nconst subtotal = lineItems.reduce((sum, item) => sum + item.total, 0);\nconst taxAmount = parseFloat(orderData.total_tax || 0);\nconst shippingAmount = parseFloat(orderData.shipping_lines?.[0]?.price || 0);\nconst total = parseFloat(orderData.total_price);\n\n// Format invoice data\nconst invoiceData = {\n  // Order info\n  orderNumber: orderData.order_number,\n  orderDate: new Date(orderData.created_at).toLocaleDateString(),\n  \n  // Customer info\n  customer: {\n    name: `${orderData.customer.first_name} ${orderData.customer.last_name}`,\n    email: orderData.customer.email,\n    phone: orderData.customer.phone || 'N/A'\n  },\n  \n  // Billing address\n  billingAddress: orderData.billing_address ? {\n    address1: orderData.billing_address.address1,\n    address2: orderData.billing_address.address2 || '',\n    city: orderData.billing_address.city,\n    province: orderData.billing_address.province,\n    zip: orderData.billing_address.zip,\n    country: orderData.billing_address.country\n  } : null,\n  \n  // Shipping address\n  shippingAddress: orderData.shipping_address ? {\n    address1: orderData.shipping_address.address1,\n    address2: orderData.shipping_address.address2 || '',\n    city: orderData.shipping_address.city,\n    province: orderData.shipping_address.province,\n    zip: orderData.shipping_address.zip,\n    country: orderData.shipping_address.country\n  } : null,\n  \n  // Line items\n  items: lineItems,\n  \n  // Totals\n  subtotal: subtotal.toFixed(2),\n  tax: taxAmount.toFixed(2),\n  shipping: shippingAmount.toFixed(2),\n  total: total.toFixed(2),\n  currency: orderData.currency,\n  \n  // Additional info\n  paymentMethod: orderData.payment_gateway_names?.[0] || 'Online Payment',\n  notes: orderData.note || ''\n};\n\nreturn { invoiceData };"
      },
      "typeVersion": 2
    },
    {
      "id": "0bfdcf22-ecc4-4fb1-b9a7-5ee86079feb1",
      "name": "Générer une facture HTML",
      "type": "n8n-nodes-base.code",
      "position": [
        144,
        496
      ],
      "parameters": {
        "jsCode": "// Generate professional invoice HTML\nconst data = $input.first().json.invoiceData;\n\nconst html = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Invoice #${data.orderNumber}</title>\n    <style>\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n        \n        body {\n            font-family: 'Arial', sans-serif;\n            line-height: 1.6;\n            color: #333;\n            background: #f8f9fa;\n        }\n        \n        .container {\n            max-width: 800px;\n            margin: 0 auto;\n            background: white;\n            padding: 40px;\n            box-shadow: 0 0 20px rgba(0,0,0,0.1);\n        }\n        \n        .header {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            margin-bottom: 40px;\n            padding-bottom: 20px;\n            border-bottom: 3px solid #007bff;\n        }\n        \n        .company-info {\n            flex: 1;\n        }\n        \n        .company-name {\n            font-size: 28px;\n            font-weight: bold;\n            color: #007bff;\n            margin-bottom: 5px;\n        }\n        \n        .invoice-info {\n            text-align: right;\n        }\n        \n        .invoice-title {\n            font-size: 36px;\n            font-weight: bold;\n            color: #333;\n            margin-bottom: 10px;\n        }\n        \n        .invoice-number {\n            font-size: 18px;\n            color: #666;\n        }\n        \n        .details-section {\n            display: flex;\n            justify-content: space-between;\n            margin-bottom: 40px;\n            gap: 40px;\n        }\n        \n        .detail-box {\n            flex: 1;\n            padding: 20px;\n            background: #f8f9fa;\n            border-radius: 8px;\n        }\n        \n        .detail-title {\n            font-weight: bold;\n            margin-bottom: 15px;\n            color: #007bff;\n            font-size: 16px;\n        }\n        \n        .detail-content {\n            color: #555;\n        }\n        \n        .items-table {\n            width: 100%;\n            border-collapse: collapse;\n            margin-bottom: 30px;\n        }\n        \n        .items-table th,\n        .items-table td {\n            padding: 15px;\n            text-align: left;\n            border-bottom: 1px solid #ddd;\n        }\n        \n        .items-table th {\n            background-color: #007bff;\n            color: white;\n            font-weight: bold;\n            text-transform: uppercase;\n            font-size: 14px;\n        }\n        \n        .items-table tr:hover {\n            background-color: #f5f5f5;\n        }\n        \n        .text-right {\n            text-align: right;\n        }\n        \n        .totals-section {\n            margin-left: auto;\n            width: 300px;\n        }\n        \n        .totals-table {\n            width: 100%;\n            border-collapse: collapse;\n        }\n        \n        .totals-table td {\n            padding: 10px 0;\n            border-bottom: 1px solid #eee;\n        }\n        \n        .total-row {\n            font-weight: bold;\n            font-size: 18px;\n            border-top: 2px solid #007bff;\n            color: #007bff;\n        }\n        \n        .footer {\n            margin-top: 50px;\n            padding-top: 20px;\n            border-top: 1px solid #ddd;\n            text-align: center;\n            color: #666;\n            font-size: 14px;\n        }\n        \n        .thank-you {\n            font-size: 18px;\n            color: #007bff;\n            margin-bottom: 10px;\n        }\n    </style>\n</head>\n<body>\n    <div class=\"container\">\n        <div class=\"header\">\n            <div class=\"company-info\">\n                <div class=\"company-name\">Your Company Name</div>\n                <div>123 Business Street</div>\n                <div>City, State 12345</div>\n                <div>Phone: (555) 123-4567</div>\n                <div>Email: info@yourcompany.com</div>\n            </div>\n            <div class=\"invoice-info\">\n                <div class=\"invoice-title\">INVOICE</div>\n                <div class=\"invoice-number\">#${data.orderNumber}</div>\n                <div style=\"margin-top: 10px;\">Date: ${data.orderDate}</div>\n            </div>\n        </div>\n        \n        <div class=\"details-section\">\n            <div class=\"detail-box\">\n                <div class=\"detail-title\">Bill To:</div>\n                <div class=\"detail-content\">\n                    <strong>${data.customer.name}</strong><br>\n                    ${data.customer.email}<br>\n                    ${data.customer.phone}<br><br>\n                    ${data.billingAddress ? `\n                        ${data.billingAddress.address1}<br>\n                        ${data.billingAddress.address2 ? data.billingAddress.address2 + '<br>' : ''}\n                        ${data.billingAddress.city}, ${data.billingAddress.province} ${data.billingAddress.zip}<br>\n                        ${data.billingAddress.country}\n                    ` : ''}\n                </div>\n            </div>\n            \n            ${data.shippingAddress ? `\n            <div class=\"detail-box\">\n                <div class=\"detail-title\">Ship To:</div>\n                <div class=\"detail-content\">\n                    ${data.shippingAddress.address1}<br>\n                    ${data.shippingAddress.address2 ? data.shippingAddress.address2 + '<br>' : ''}\n                    ${data.shippingAddress.city}, ${data.shippingAddress.province} ${data.shippingAddress.zip}<br>\n                    ${data.shippingAddress.country}\n                </div>\n            </div>\n            ` : ''}\n            \n            <div class=\"detail-box\">\n                <div class=\"detail-title\">Payment Info:</div>\n                <div class=\"detail-content\">\n                    <strong>Method:</strong> ${data.paymentMethod}<br>\n                    <strong>Currency:</strong> ${data.currency}<br>\n                    <strong>Status:</strong> Paid\n                </div>\n            </div>\n        </div>\n        \n        <table class=\"items-table\">\n            <thead>\n                <tr>\n                    <th>Item</th>\n                    <th>SKU</th>\n                    <th>Qty</th>\n                    <th>Price</th>\n                    <th>Total</th>\n                </tr>\n            </thead>\n            <tbody>\n                ${data.items.map(item => `\n                <tr>\n                    <td><strong>${item.name}</strong></td>\n                    <td>${item.sku}</td>\n                    <td>${item.quantity}</td>\n                    <td>$${item.price.toFixed(2)}</td>\n                    <td class=\"text-right\">$${item.total.toFixed(2)}</td>\n                </tr>\n                `).join('')}\n            </tbody>\n        </table>\n        \n        <div class=\"totals-section\">\n            <table class=\"totals-table\">\n                <tr>\n                    <td>Subtotal:</td>\n                    <td class=\"text-right\">$${data.subtotal}</td>\n                </tr>\n                ${parseFloat(data.shipping) > 0 ? `\n                <tr>\n                    <td>Shipping:</td>\n                    <td class=\"text-right\">$${data.shipping}</td>\n                </tr>\n                ` : ''}\n                ${parseFloat(data.tax) > 0 ? `\n                <tr>\n                    <td>Tax:</td>\n                    <td class=\"text-right\">$${data.tax}</td>\n                </tr>\n                ` : ''}\n                <tr class=\"total-row\">\n                    <td><strong>Total:</strong></td>\n                    <td class=\"text-right\"><strong>$${data.total}</strong></td>\n                </tr>\n            </table>\n        </div>\n        \n        ${data.notes ? `\n        <div style=\"margin-top: 30px; padding: 20px; background: #f8f9fa; border-radius: 8px;\">\n            <strong>Notes:</strong><br>\n            ${data.notes}\n        </div>\n        ` : ''}\n        \n        <div class=\"footer\">\n            <div class=\"thank-you\">Thank you for your business!</div>\n            <div>This invoice was generated automatically on ${new Date().toLocaleDateString()}</div>\n            <div style=\"margin-top: 10px;\">For questions about this invoice, please contact us at info@yourcompany.com</div>\n        </div>\n    </div>\n</body>\n</html>\n`;\n\nreturn { html };"
      },
      "typeVersion": 2
    },
    {
      "id": "9cedf436-1a03-4fb6-910d-086b6dca81b5",
      "name": "Enregistrer sur Google Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1056,
        288
      ],
      "parameters": {
        "name": "=Invoice - {{ $('Shopify Order Webhook').item.json.body.id }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "1A2B3C4D5E6F7G8H9I0J",
          "cachedResultName": "Invoices"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "cfc5e050-ca7f-4197-aec2-efea24529538",
      "name": "Envoyer au client par email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1056,
        592
      ],
      "webhookId": "fd101041-8325-4589-a347-d966678a2883",
      "parameters": {
        "sendTo": "={{ $('Shopify Order Webhook').item.json.body.customer.email }}",
        "message": "=<!DOCTYPE html> <html lang=\"en\"> <head>     <meta charset=\"UTF-8\">     <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">     <title>Invoice for Order #{{ $('Shopify Order Webhook').item.json.body.order_number }}</title>     <style>         body {             font-family: Arial, sans-serif;             line-height: 1.6;             color: #333;             max-width: 600px;             margin: 0 auto;             padding: 20px;         }                  .header {             text-align: center;             margin-bottom: 30px;             padding-bottom: 20px;             border-bottom: 2px solid #007bff;         }                  .company-name {             font-size: 24px;             font-weight: bold;             color: #007bff;             margin-bottom: 5px;         }                  .attachment-notice {             background: #f8f9fa;             padding: 15px;             border-left: 4px solid #28a745;             margin: 20px 0;         }                  .footer {             margin-top: 40px;             padding-top: 20px;             border-top: 1px solid #ddd;             color: #666;             font-size: 14px;         }     </style> </head> <body>     <div class=\"header\">         <div class=\"company-name\">Company Name</div>     </div>          <p>Dear {{ $('Shopify Order Webhook').item.json.body.customer.first_name }},</p>          <p>Thank you for your recent order! Your payment has been successfully processed.</p>          <div class=\"attachment-notice\">         <strong>📎 Invoice Attached</strong><br>         Please find your invoice attached to this email for order #{{ $('Shopify Order Webhook').item.json.body.order_number }}.     </div>          <p>We're now preparing your order for shipment. You'll receive a tracking notification once your order is on its way.</p>          <p>If you have any questions about your order, please don't hesitate to contact us at support@pdfmunk.com.</p>          <p>Thank you for choosing Company Name!</p>          <p>Best regards,<br>     The Company Name Team</p>          <div class=\"footer\">         <p>This is an automated email regarding your order. Please save the attached invoice for your records.</p>        </div> </body> </html>",
        "options": {
          "attachmentsUi": {
            "attachmentsBinary": [
              {}
            ]
          }
        },
        "subject": "=Invoice for your Order#  {{ $('Shopify Order Webhook').item.json.body.order_number }}"
      },
      "typeVersion": 2.1
    },
    {
      "id": "8162eb8b-938d-4361-b54d-e745984ba8b1",
      "name": "Générer une facture PDF",
      "type": "n8n-nodes-htmlcsstopdf.htmlcsstopdf",
      "position": [
        512,
        496
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "23581c69-fd48-49a9-abe8-8f3efb1bcc9e",
      "name": "Télécharger le fichier PDF",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        800,
        496
      ],
      "parameters": {
        "url": "={{ $json.pdf_url }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "6ff41885-733c-4e38-b16b-3e9f3adae96b",
      "name": "Note adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -592,
        288
      ],
      "parameters": {
        "color": 4,
        "width": 288,
        "height": 368,
        "content": "## Webhook from Jotform\nSetup this webhook URL to receive order information from Jotform\n\n**JotForm account**\n\n[Sign up for Jotform for free](https://www.jotform.com/?partner=mediajade)"
      },
      "typeVersion": 1
    },
    {
      "id": "5ddc5e49-007b-4a46-a41a-e7f5a50c2679",
      "name": "Note adhésive1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        384
      ],
      "parameters": {
        "color": 4,
        "height": 272,
        "content": "## Create HTML\nGenerate custom HTML for the invoice"
      },
      "typeVersion": 1
    },
    {
      "id": "989e9a89-dcd8-42fb-9fa6-c20916ef42f5",
      "name": "Note adhésive2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        384
      ],
      "parameters": {
        "color": 4,
        "width": 352,
        "height": 272,
        "content": "## Generate PDF\n* Convert HTML to PDF Invoice\n* Get your API Key from [PDFMunk](https://pdfmunk.com)"
      },
      "typeVersion": 1
    },
    {
      "id": "8aeeed1b-3c2f-44de-a330-2547f2d1a3bd",
      "name": "Note adhésive3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -224,
        384
      ],
      "parameters": {
        "color": 4,
        "height": 272,
        "content": "## Format Data\nPrepare Line Item data for next step"
      },
      "typeVersion": 1
    },
    {
      "id": "db3b1636-c5c8-4212-8cfa-8a1d4e21410e",
      "name": "Note adhésive4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        576
      ],
      "parameters": {
        "color": 4,
        "width": 304,
        "height": 288,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n## Email Invoice\nSend Invoice PDF Email to the Customer"
      },
      "typeVersion": 1
    },
    {
      "id": "6d92f3cf-4574-44af-b88a-e309974f809b",
      "name": "Note adhésive5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        192
      ],
      "parameters": {
        "color": 4,
        "width": 304,
        "height": 288,
        "content": "## Save Invoice PDF\nStore Invoice PDF to Google Drive"
      },
      "typeVersion": 1
    },
    {
      "id": "bfc8cada-2bd0-485f-a9b5-4d1701474374",
      "name": "Note adhésive8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "color": 6,
        "width": 544,
        "height": 288,
        "content": "## 🎯 What This Template Does\n\nTransform your Jotform order fulfillment with complete invoice automation. When a customer places an order, this workflow automatically:\n\n✅ Receives order data from Jotform Trigger\n✅ Generates professional HTML invoice with your branding\n✅ Converts to PDF using HTML to PDF conversion\n✅ Saves invoice to Google Drive for record-keeping\n✅ Emails PDF invoice to customer automatically"
      },
      "typeVersion": 1
    },
    {
      "id": "000cdfd3-ae0d-4716-9ca9-ef155ff6c3ec",
      "name": "Déclencheur JotForm",
      "type": "n8n-nodes-base.jotFormTrigger",
      "position": [
        -512,
        496
      ],
      "webhookId": "d222ca8c-80f7-4504-bf39-6b2e5ec87316",
      "parameters": {
        "form": "252815424602048"
      },
      "credentials": {
        "jotFormApi": {
          "id": "cOSh16Q5l4e0EB1A",
          "name": "Jotform jitesh@mediajade.com"
        }
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "4eaaebd6-4d7c-4c24-bde6-4553f7978a77",
  "connections": {
    "000cdfd3-ae0d-4716-9ca9-ef155ff6c3ec": {
      "main": [
        [
          {
            "node": "99ab3063-af31-4701-890f-67b42ed901f6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "23581c69-fd48-49a9-abe8-8f3efb1bcc9e": {
      "main": [
        [
          {
            "node": "cfc5e050-ca7f-4197-aec2-efea24529538",
            "type": "main",
            "index": 0
          },
          {
            "node": "9cedf436-1a03-4fb6-910d-086b6dca81b5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "cfc5e050-ca7f-4197-aec2-efea24529538": {
      "main": [
        []
      ]
    },
    "99ab3063-af31-4701-890f-67b42ed901f6": {
      "main": [
        [
          {
            "node": "0bfdcf22-ecc4-4fb1-b9a7-5ee86079feb1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8162eb8b-938d-4361-b54d-e745984ba8b1": {
      "main": [
        [
          {
            "node": "23581c69-fd48-49a9-abe8-8f3efb1bcc9e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9cedf436-1a03-4fb6-910d-086b6dca81b5": {
      "main": [
        []
      ]
    },
    "0bfdcf22-ecc4-4fb1-b9a7-5ee86079feb1": {
      "main": [
        [
          {
            "node": "8162eb8b-938d-4361-b54d-e745984ba8b1",
            "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é ?

Intermédiaire

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é
Intermédiaire
Nombre de nœuds14
Catégorie-
Types de nœuds7
Description de la difficulté

Adapté aux utilisateurs expérimentés, avec des workflows de complexité moyenne contenant 6-15 nœuds

Auteur
Jitesh Dugar

Jitesh Dugar

@jiteshdugar

AI Automation Specialist - OpenAI, CRM & Automation Expert with a solid understanding of various tools that include Zapier, Make, Zoho CRM, Hubspot, Google Sheets, Airtable, Pipedrive, Google Analytics, and more.

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34