AutomationFlowsData & Sheets › Automate Quickbooks Invoicing & Customer Creation From Airtable Sales Orders

Automate Quickbooks Invoicing & Customer Creation From Airtable Sales Orders

ByIntuz @intuz on n8n.io

It intelligently syncs confirmed sales orders from your Airtable base to QuickBooks, automatically creating new customers if they don't exist before generating a perfectly matched invoice. It then logs all invoice details back into Airtable, creating a flawless, end-to-end…

Webhook trigger★★★★★ complexity35 nodesAirtableQuickBooksHTTP Request
Data & Sheets Trigger: Webhook Nodes: 35 Complexity: ★★★★★ Added:

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

This workflow follows the Airtable → 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
{
  "id": "bBQjdycmZkCpFBuf",
  "name": "Automate QuickBooks Invoicing & Customer Creation from Airtable Sales Orders",
  "tags": [],
  "nodes": [
    {
      "id": "db74e2e3-bc33-4277-89de-1b62bce61d6c",
      "name": "Get Customer Details",
      "type": "n8n-nodes-base.airtable",
      "position": [
        304,
        432
      ],
      "parameters": {
        "id": "={{ $json['(Q) Customer'][0] }}",
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appFsCGQkVElarpyF",
          "cachedResultUrl": "https://airtable.com/appFsCGQkVElarpyF",
          "cachedResultName": "(Intuz) Operations Hub (Sample) (Copy)"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblhOxgN7qzl8UVTi",
          "cachedResultUrl": "https://airtable.com/appFsCGQkVElarpyF/tblhOxgN7qzl8UVTi",
          "cachedResultName": "Customers"
        },
        "options": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "ec49c44f-54fe-4f02-860f-2f492e46be18",
      "name": "QuickBooks - Find Customer",
      "type": "n8n-nodes-base.quickbooks",
      "position": [
        656,
        432
      ],
      "parameters": {
        "filters": {
          "query": "=WHERE DisplayName = '{{ $json[\"(Q) Customer Name\"] }}'"
        },
        "operation": "getAll"
      },
      "typeVersion": 1
    },
    {
      "id": "5299c75c-d158-42eb-b9a6-16291eb83efd",
      "name": "Create a customer",
      "type": "n8n-nodes-base.quickbooks",
      "position": [
        1136,
        304
      ],
      "parameters": {
        "operation": "create",
        "displayName": "={{ $('Get Customer Details').item.json['(Q) Customer Name'] }}",
        "additionalFields": {
          "BillAddr": {
            "details": {
              "City": "={{ $('Get Customer Details').item.json['(Q) Bill City'] }}",
              "Line1": "={{ $('Get Customer Details').item.json['(Q) Bill Line1'] }}",
              "PostalCode": "={{ $('Get Customer Details').item.json['(Q) Bill PostalCode'] }}",
              "CountrySubDivisionCode": "={{ $('Get Customer Details').item.json['(Q) Bill Country'] }}"
            }
          },
          "PrimaryPhone": "={{ $('Get Customer Details').item.json['(Q) Phone Number'] }}",
          "PrimaryEmailAddr": "={{ $('Get Customer Details').item.json['(Q) Email Address'] }}"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f83c8c16-ac6e-4f02-8db9-83befb18abf0",
      "name": "Get Products",
      "type": "n8n-nodes-base.airtable",
      "position": [
        1600,
        368
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appFsCGQkVElarpyF",
          "cachedResultUrl": "https://airtable.com/appFsCGQkVElarpyF",
          "cachedResultName": "(Intuz) Operations Hub (Sample) (Copy)"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblZHt0JDc6U6HvEI",
          "cachedResultUrl": "https://airtable.com/appFsCGQkVElarpyF/tblZHt0JDc6U6HvEI",
          "cachedResultName": "Order Lines"
        },
        "options": {},
        "operation": "search",
        "filterByFormula": "={Sales Order} = \"{{ $('Get Airtable Orders Records').item.json['Sales Order ID'] }}\""
      },
      "typeVersion": 2.1
    },
    {
      "id": "dba10e50-b393-43d7-91ec-eac513be2ab7",
      "name": "Append Customers",
      "type": "n8n-nodes-base.merge",
      "position": [
        1424,
        784
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "e56db207-580e-4ac9-affc-ed490d0674bb",
      "name": "Parse in HTTP",
      "type": "n8n-nodes-base.code",
      "position": [
        2416,
        352
      ],
      "parameters": {
        "jsCode": "const out = [];\n\nfor (const input of $input.all()) {\n  const data = input.json;\n\n  // Map terms string to QuickBooks SalesTermRef value\n  let termValue;\n  if (data.terms) {\n    const match = data.terms.match(/\\d+/); // extract number from \"Net 7\"\n    if (match) {\n      termValue = match[0]; // e.g., \"7\"\n    }\n  }\n\n  // Build QuickBooks Line array\n  const Line = (data.products || []).map(p => ({\n    DetailType: \"SalesItemLineDetail\",\n    Amount: p.amount,\n    Description: p.description || \"\",\n    SalesItemLineDetail: {\n      ItemRef: {\n        value: p.qbItemId || p.itemId, // Must be QuickBooks Item ID\n        name: p.itemName\n      },\n      Qty: p.qty || 1,\n      UnitPrice: p.rate || 0\n    }\n  }));\n\n  // \u2705 Add discount line if discount exists\n  if (data.discount) {\n    Line.push({\n      DetailType: \"DiscountLineDetail\",\n      Amount: 0, // QuickBooks will calculate based on percentage\n      DiscountLineDetail: {\n        PercentBased: true,\n        DiscountPercent: data.discount // only percent from previous output\n      }\n    });\n  }\n\n  // Invoice payload\n  const invoicePayload = {\n    CustomerRef: { value: String(data.customerId) },\n    TxnDate: data.invoiceDate,\n    DueDate: data.dueDate,\n    PrivateNote: data.salesOrder,\n    BillEmail: data.customerEmail\n      ? { Address: data.customerEmail }\n      : undefined,\n    //SalesTermRef: termValue ? { value: termValue } : undefined,\n    Line\n  };\n\n  out.push({ json: { customer: invoicePayload } });\n}\n\nreturn out;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "10f6d569-a928-41f8-a768-2c6646a4072d",
      "name": "Search Product ID",
      "type": "n8n-nodes-base.airtable",
      "position": [
        1872,
        368
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appFsCGQkVElarpyF",
          "cachedResultUrl": "https://airtable.com/appFsCGQkVElarpyF",
          "cachedResultName": "(Intuz) Operations Hub (Sample) (Copy)"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tbluYcq0Zkka8uI8c",
          "cachedResultUrl": "https://airtable.com/appFsCGQkVElarpyF/tbluYcq0Zkka8uI8c",
          "cachedResultName": "Product & Service"
        },
        "options": {},
        "operation": "search",
        "filterByFormula": "={(Q) Product/Service Name}= \"{{ $json['(Q) Item Name (A)'][0] }}\""
      },
      "typeVersion": 2.1
    },
    {
      "id": "d4090bb0-4d0a-430d-8a9e-bee8860fc136",
      "name": "Create Invoice URL",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2992,
        496
      ],
      "parameters": {
        "url": "https://sandbox-quickbooks.api.intuit.com/v3/company/9341455145770046/invoice?minorversion=75",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify($json.customer) }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "quickBooksOAuth2Api"
      },
      "retryOnFail": true,
      "typeVersion": 4.2
    },
    {
      "id": "9b6f19f2-ac4c-4baa-af6b-730b18cb2186",
      "name": "Loop Over Items1",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        2720,
        480
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "dac5c7fa-a488-4f97-b8f0-aa8a56ca23ec",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -448,
        448
      ],
      "parameters": {
        "path": "321f46d5-66da-49f5-a8d1-6b61e4a7321f",
        "options": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "d8e97ca6-608d-456b-af0c-01563c747444",
      "name": "If Invoice not Created",
      "type": "n8n-nodes-base.if",
      "position": [
        112,
        752
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "6412d0e3-1fe5-423c-a0bb-29ef90240843",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json[\"Synced to QBO (A)\"] }}",
              "rightValue": "FALSE"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "05c1e7bc-bc42-415a-8052-50a852ccf19a",
      "name": "IF - Customer doesn't Exists?",
      "type": "n8n-nodes-base.if",
      "position": [
        992,
        784
      ],
      "parameters": {
        "conditions": {
          "number": [
            {
              "value1": "={{ $json.Id }}",
              "operation": "isEmpty"
            }
          ]
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "da33b092-a29d-4e07-8992-251c2e8d5cdd",
      "name": "Create Invoice record",
      "type": "n8n-nodes-base.airtable",
      "position": [
        3280,
        496
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appFsCGQkVElarpyF",
          "cachedResultUrl": "https://airtable.com/appFsCGQkVElarpyF",
          "cachedResultName": "(Intuz) Operations Hub (Sample) (Copy)"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblXEKsfxMDVhFMcg",
          "cachedResultUrl": "https://airtable.com/appFsCGQkVElarpyF/tblXEKsfxMDVhFMcg",
          "cachedResultName": "Invoices & Payments"
        },
        "columns": {
          "value": {
            "Customer": "={{ $json.Invoice.CustomerRef.name }}",
            "Due Date": "={{ new Date($json.Invoice.DueDate).toISOString() }}",
            "Tax Code": "={{ $json.Invoice.Line[1].SalesItemLineDetail.TaxCodeRef.value }}",
            "Amount Paid": 0,
            "Invoice Date": "={{ new Date($json.Invoice.TxnDate).toISOString() }}",
            "Invoice Amount": "={{ $json.Invoice.TotalAmt }}",
            "Invoice Number": "={{ $json.Invoice.DocNumber }}",
            "Payment Status": "Unpaid",
            "Outstanding Balance": "={{ $json.Invoice.Balance }}"
          },
          "schema": [
            {
              "id": "Invoice Number",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Invoice Number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Order",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Order",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Customer",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Customer",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Invoice Date",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Invoice Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Due Date",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Due Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Invoice Amount",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Invoice Amount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Amount Paid",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Amount Paid",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Outstanding Balance",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Outstanding Balance",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Payment Status",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "Unpaid",
                  "value": "Unpaid"
                },
                {
                  "name": "Partially Paid",
                  "value": "Partially Paid"
                },
                {
                  "name": "Paid",
                  "value": "Paid"
                },
                {
                  "name": "Overdue",
                  "value": "Overdue"
                }
              ],
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Payment Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Payment Date",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Payment Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Payment Method",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "Bank Transfer",
                  "value": "Bank Transfer"
                },
                {
                  "name": "Credit Card",
                  "value": "Credit Card"
                },
                {
                  "name": "Cheque",
                  "value": "Cheque"
                },
                {
                  "name": "Cash",
                  "value": "Cash"
                },
                {
                  "name": "Other",
                  "value": "Other"
                }
              ],
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Payment Method",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Invoice Document",
              "type": "array",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Invoice Document",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notes",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Notes",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Created By",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Created By",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date Created",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Date Created",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Last Modified",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Last Modified",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tax Code",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Tax Code",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Order Gross Margin",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Order Gross Margin",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Order Total Purchases",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Order Total Purchases",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Order Total Labour",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Order Total Labour",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Customer Industry",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Customer Industry",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Customer Type",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Customer Type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Order Status",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Order Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Days Overdue",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Days Overdue",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Payment Completion %",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Payment Completion %",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Outstanding Balance Check",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Outstanding Balance Check",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Invoice Summary (AI)",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Invoice Summary (AI)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Payment Risk Assessment (AI)",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Payment Risk Assessment (AI)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "create"
      },
      "typeVersion": 2.1
    },
    {
      "id": "85f4579d-008c-469c-bfa0-085e17e33b80",
      "name": "Update Order record",
      "type": "n8n-nodes-base.airtable",
      "position": [
        3568,
        496
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appFsCGQkVElarpyF",
          "cachedResultUrl": "https://airtable.com/appFsCGQkVElarpyF",
          "cachedResultName": "(Intuz) Operations Hub (Sample) (Copy)"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tbluRdjyw8xiWgJht",
          "cachedResultUrl": "https://airtable.com/appFsCGQkVElarpyF/tbluRdjyw8xiWgJht",
          "cachedResultName": "Confirmed Orders"
        },
        "columns": {
          "value": {
            "Sales Order ID": "={{ $('Create Invoice URL').item.json.Invoice.PrivateNote }}",
            "(Q) QBO Invoice Id": "={{ $('Create Invoice URL').item.json.Invoice.Id }}",
            "(Q) QBO Invoice Number": "={{ $('Create Invoice URL').item.json.Invoice.DocNumber }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true
            },
            {
              "id": "Sales Order ID",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Sales Order ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) Customer",
              "type": "array",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "(Q) Customer",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Order Date",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Order Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Pick Up",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Pick Up",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Delivery Date",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Delivery Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(A) Days Left",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "(A) Days Left",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Order Status",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "Confirmed",
                  "value": "Confirmed"
                },
                {
                  "name": "In Progress",
                  "value": "In Progress"
                },
                {
                  "name": "Completed",
                  "value": "Completed"
                },
                {
                  "name": "Cancelled",
                  "value": "Cancelled"
                }
              ],
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Order Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Order Type",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "Residential",
                  "value": "Residential"
                },
                {
                  "name": "Commercial",
                  "value": "Commercial"
                },
                {
                  "name": "Contractor",
                  "value": "Contractor"
                },
                {
                  "name": "Other",
                  "value": "Other"
                }
              ],
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Order Type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Subtotal (A)",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Subtotal (A)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Purchases Total (A)",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Purchases Total (A)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) Terms",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "Due on Receipt",
                  "value": "Due on Receipt"
                },
                {
                  "name": "Net 7",
                  "value": "Net 7"
                },
                {
                  "name": "Net 14",
                  "value": "Net 14"
                },
                {
                  "name": "Net 30",
                  "value": "Net 30"
                },
                {
                  "name": "Net 45",
                  "value": "Net 45"
                },
                {
                  "name": "Net 60",
                  "value": "Net 60"
                }
              ],
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "(Q) Terms",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) Invoice Date",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "(Q) Invoice Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) Due Date (A)",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "(Q) Due Date (A)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Order Lines",
              "type": "array",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Order Lines",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Public Holidays (Synced)",
              "type": "array",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Public Holidays (Synced)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) QBO Customer Id",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "(Q) QBO Customer Id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) QBO Invoice Number",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "(Q) QBO Invoice Number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) QBO Invoice Id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "(Q) QBO Invoice Id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notes (Internal)",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Notes (Internal)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Purchases",
              "type": "array",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Purchases",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Labour Tasks",
              "type": "array",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Labour Tasks",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Issues & Feedback",
              "type": "array",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Issues & Feedback",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Synced to QBO (A)",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Synced to QBO (A)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SLA Breach (A)",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "SLA Breach (A)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Job Tasks",
              "type": "array",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Job Tasks",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Labour Charges",
              "type": "array",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Labour Charges",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total Labour Charges (A)",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Total Labour Charges (A)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "True Days Left",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "True Days Left",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Days Remaining (A)",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Days Remaining (A)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Holiday Weight Sum",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Holiday Weight Sum",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Holiday Count",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Holiday Count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Sales Order ID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update"
      },
      "typeVersion": 2.1
    },
    {
      "id": "8b60a7d0-ecf8-4f7f-8c59-e40be0441b49",
      "name": "Update Customer Record",
      "type": "n8n-nodes-base.airtable",
      "position": [
        3872,
        496
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appFsCGQkVElarpyF",
          "cachedResultUrl": "https://airtable.com/appFsCGQkVElarpyF",
          "cachedResultName": "(Intuz) Operations Hub (Sample) (Copy)"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblhOxgN7qzl8UVTi",
          "cachedResultUrl": "https://airtable.com/appFsCGQkVElarpyF/tblhOxgN7qzl8UVTi",
          "cachedResultName": "Customers"
        },
        "columns": {
          "value": {
            "(Q) Customer Name": "={{ $('Create Invoice URL').item.json.Invoice.CustomerRef.name }}",
            "(Q) QBO Customer Id": "={{ $('Create Invoice URL').item.json.Invoice.CustomerRef.value }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true
            },
            {
              "id": "(Q) Customer Name",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "(Q) Customer Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) Phone Number",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "(Q) Phone Number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Customer ID",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Customer ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) Bill Line1",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "(Q) Bill Line1",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) Bill City",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "(Q) Bill City",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) Bill PostalCode",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "(Q) Bill PostalCode",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Customer Type",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "Individual",
                  "value": "Individual"
                },
                {
                  "name": "Business",
                  "value": "Business"
                },
                {
                  "name": "Other",
                  "value": "Other"
                }
              ],
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Customer Type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Synced to QBO (A)",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Synced to QBO (A)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Customer Number ",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Customer Number ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) QBO Customer Id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "(Q) QBO Customer Id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Last Modified",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Last Modified",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) Last Sync Attempt",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "(Q) Last Sync Attempt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) Sync Error",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "(Q) Sync Error",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Full Billing Address (A)",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Full Billing Address (A)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) Email Address",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "(Q) Email Address",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contact Person",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Contact Person",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notes (Internal)",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Notes (Internal)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Confirmed Orders",
              "type": "array",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Confirmed Orders",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "(Q) Bill Country",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "SG",
                  "value": "SG"
                },
                {
                  "name": "MY",
                  "value": "MY"
                },
                {
                  "name": "Other",
                  "value": "Other"
                },
                {
                  "name": "Singapore",
                  "value": "Singapore"
                }
              ],
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "(Q) Bill Country",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Auto Number (raw)",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "Auto Number (raw)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "(Q) Customer Name"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update"
      },
      "typeVersion": 2.1
    },
    {
      "id": "d459f712-afa2-48f2-b321-c8137508ee61",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -544,
        224
      ],
      "parameters": {
        "width": 294,
        "height": 416,
        "content": "## Purpose: Entry point. \n\n-Triggered automatically when a Sales Order is confirmed in Airtable.\n\n-Ensure your webhook URL is added in Airtable\u2019s automation as a \u201cPOST request\u201d when order status = Confirmed."
      },
      "typeVersion": 1
    },
    {
      "id": "f50402f8-8b25-4573-b67f-89827dabbd1a",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -192,
        224
      ],
      "parameters": {
        "width": 310,
        "height": 416,
        "content": "## Get Orders Records\n\n--Fetch details of the confirmed Sales Order using the record ID received from webhook.\n\n--Must have \u201cSales Order ID\u201d field populated for linkage with Products and Customer."
      },
      "typeVersion": 1
    },
    {
      "id": "09a7dae1-3f7f-4b5f-87ed-dd7a5d0f7b0f",
      "name": "Get Airtable Orders Records",
      "type": "n8n-nodes-base.airtable",
      "position": [
        -80,
        448
      ],
      "parameters": {
        "id": "={{$json[\"query\"][\"recordId\"]}}",
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appFsCGQkVElarpyF",
          "cachedResultUrl": "https://airtable.com/appFsCGQkVElarpyF",
          "cachedResultName": "(Intuz) Operations Hub (Sample) (Copy)"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tbluRdjyw8xiWgJht",
          "cachedResultUrl": "https://airtable.com/appFsCGQkVElarpyF/tbluRdjyw8xiWgJht",
          "cachedResultName": "Confirmed Orders"
        },
        "options": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "83c2470f-4811-468d-bf32-802c7f19b397",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        16,
        688
      ],
      "parameters": {
        "width": 310,
        "height": 432,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Invoice record check\n\n--Skip records that already have a QuickBooks invoice created.\n\n--Checks if \u201cSynced to QBO (A)\u201d field in Airtable = FALSE.\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b5ef9066-d96b-4e04-92d6-388f6616795b",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        192,
        224
      ],
      "parameters": {
        "width": 294,
        "height": 416,
        "content": "## Get Customer Details\n\n--Retrieve customer info linked to this order.\n\n--Customer record must have fields like (Q) Customer Name, (Q) Email Address, etc.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "56e27b01-813d-45d5-8c2d-83d512350867",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        224
      ],
      "parameters": {
        "width": 278,
        "height": 416,
        "content": "## QuickBooks - Find Customer\n\n--Search customer in QuickBooks using DisplayName.\n\n--Ensures no duplicate customer creation in QBO.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "58bad121-7a39-4259-997e-47970f90f4d9",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        896,
        704
      ],
      "parameters": {
        "width": 310,
        "height": 432,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Customer doesn\u2019t Exist?\n\n--Checks if customer was found in QBO.\n\n\n--True (Yes): Go to \u201cCreate a customer.\u201d\n\n--False (No): Continue to next step.\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7b1b9432-76b1-47fb-9126-c93666dbbff4",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1040,
        112
      ],
      "parameters": {
        "width": 278,
        "height": 352,
        "content": "## Create a Customer\n\n--Creates new customer in QuickBooks if not found.\n\n--Pulls data from Airtable Customer table.\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ab0b82c5-c617-4b3e-b85c-be8c6cd1b293",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        704
      ],
      "parameters": {
        "width": 326,
        "height": 432,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Append Customers (Merge)\n\n--Combine both existing and newly created QBO customers for further mapping.\n\n\n--Merges both paths before processing invoices.\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "0cefbcce-7473-456b-96d5-7af70e22f66f",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1536,
        144
      ],
      "parameters": {
        "width": 230,
        "height": 368,
        "content": "## Get Products\n\n--Fetch order line items from \u201cOrder Lines\u201d table.\n\n--Linked to Sales Order ID from \u201cConfirmed Orders.\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f664dd69-7b76-4aea-b61c-ad03d36dec13",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1792,
        144
      ],
      "parameters": {
        "width": 230,
        "height": 368,
        "content": "## Search Product ID\n\n--Finds QBO Product/Service ID for each product line.\n\n--Uses \u201c(Q) Product/Service Name\u201d to match Airtable & QuickBooks.\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "35215682-456e-47e1-93ea-67d96ea4fda2",
      "name": "Data Preparation",
      "type": "n8n-nodes-base.code",
      "position": [
        2144,
        368
      ],
      "parameters": {
        "jsCode": "// Input nodes\nconst salesOrders   = $items(\"Get Airtable Orders Records\");        // Sales Order data\nconst customers     = $items(\"Get Customer Details\");  // Customer details from Airtable\nconst products      = $items(\"Get Products\");          // Product line items\nconst qbCustomers   = $items(\"Append Customers\");      // QuickBooks customers\nconst searchProducts = $items(\"Search Product ID\");    // Product ID lookup data\n\nconst result = [];\n\n// Helper: find QuickBooks customer object by name\nfunction getQuickBooksCustomer(name) {\n  return qbCustomers.find(c => c.json.DisplayName === name);\n}\n\n// Helper: find Product ID by product/service name\nfunction getQuickBooksProductId(name) {\n  const match = searchProducts.find(p => p.json[\"(Q) Product/Service Name\"] === name);\n  return match ? match.json[\"(Q) Product ID\"] : null;\n}\n\nfor (const so of salesOrders) {\n  const soData = so.json;\n\n  // Ensure customer exists\n  if (!soData[\"(Q) Customer\"] || !Array.isArray(soData[\"(Q) Customer\"]) || soData[\"(Q) Customer\"].length === 0) {\n    continue;\n  }\n\n  const customerIdFromSO = soData[\"(Q) Customer\"][0];   // Airtable record id\n  const matchedCustomer = customers.find(c => c.json.id === customerIdFromSO);\n\n  if (matchedCustomer) {\n    const customerName = matchedCustomer.json[\"(Q) Customer Name\"];\n    const qbCustomer = getQuickBooksCustomer(customerName);\n\n    const quickBooksId = qbCustomer ? qbCustomer.json.Id : null;\n    const customerEmail = qbCustomer?.json?.PrimaryEmailAddr?.Address || null; // \u2705 fetch email\n\n    // Find all products linked to this sales order\n    const productMatches = products.filter(p =>\n      p.json[\"Sales Order ID (A)\"] &&\n      p.json[\"Sales Order ID (A)\"].includes(soData[\"Sales Order ID\"])\n    );\n\n    const productDetails = productMatches.map(p => {\n      const productName = (p.json[\"(Q) Item Name (A)\"] && p.json[\"(Q) Item Name (A)\"][0]) || \"Unknown\";\n      return {\n        itemId: getQuickBooksProductId(productName),\n        itemName: productName,\n        qty: p.json[\"(Q) Qty\"] || 0,\n        rate: p.json[\"(Q) Rate\"] || 0,\n        amount: p.json[\"(Q) Amount (A)\"] || 0,\n        description: (p.json[\"(Q) Description\"] && p.json[\"(Q) Description\"][0]) || \"\"\n      };\n    });\n\n    result.push({\n      customerId: quickBooksId,\n      customerName: customerName,\n      customerEmail: customerEmail, // \u2705 include email here\n      salesOrder: soData[\"Sales Order ID\"],\n      invoiceDate: soData[\"(Q) Invoice Date\"],\n      terms: soData[\"(Q) Terms\"],\n      dueDate: soData[\"(Q) Due Date (A)\"],\n      products: productDetails,\n      discount: soData[\"(Q) Discount\"]\n    });\n  }\n}\n\n// Return as items for n8n\nreturn result.map(r => ({ json: r }));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "b9766711-fec2-45e0-a99f-4b5a748a2f91",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2080,
        96
      ],
      "parameters": {
        "width": 214,
        "height": 416,
        "content": "## Data Preparation\n\n--Core logic \u2014 combines orders, customers, and products to prepare structured invoice payload.\n\n--Handles mapping of IDs, email, and discount logic.\n\n-- Modify this if your Airtable schema changes.\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "179a4831-1293-4cfb-8fc9-40f9eab92ead",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2352,
        96
      ],
      "parameters": {
        "width": 214,
        "height": 416,
        "content": "## Parse in HTTP\n\n--Converts JS objects into QuickBooks-compatible invoice JSON format.\n\n--Validate the payload before posting to QuickBooks.\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "217fef97-8eb0-463a-b914-82d043de353a",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2656,
        240
      ],
      "parameters": {
        "width": 214,
        "height": 384,
        "content": "## Split in Batches\n\n--Iterates through all prepared invoices to send one-by-one to QuickBooks API.\n\n--Keep batch size = 1 for better control and error handling.\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "21ebba18-8bc2-456e-b856-75c9351ff269",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2928,
        192
      ],
      "parameters": {
        "width": 230,
        "height": 464,
        "content": "## Create Invoice URL (QuickBooks API - HTTP)\n\n--Creates the invoice in QuickBooks Sandbox via HTTP POST.\n\n--Ensure Sandbox Company ID & version number (minorversion=75) are correct.\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "356e57c9-8749-44e3-9200-b2b68f1df2b5",
      "name": "Sticky Note14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3200,
        224
      ],
      "parameters": {
        "width": 230,
        "height": 432,
        "content": "## Create Invoice Record\n\n--Logs created invoice details into \u201cInvoices & Payments\u201d table in Airtable.\n\n--Automatically captures Invoice Number, Amount, Due Date, etc.\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a831625c-2a53-4b29-a03f-de8773778ee1",
      "name": "Sticky Note15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3504,
        224
      ],
      "parameters": {
        "width": 230,
        "height": 432,
        "content": "## Update Order Record\n\n--Updates \u201cConfirmed Orders\u201d table with QBO Invoice ID and Number.\n\n--Keeps Airtable and QuickBooks in sync.\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7dfe52a2-7690-4351-b7d8-85b67d200dbe",
      "name": "Sticky Note16",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3808,
        224
      ],
      "parameters": {
        "width": 230,
        "height": 432,
        "content": "## Update Customer Record\n\n--Updates existing Airtable Customer record with QBO Customer ID.\n\n--Ensures future syncs don\u2019t recreate existing customers.\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "74257ded-c395-4861-8140-4d3d63ddaf0d",
      "name": "Sticky Note17",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1184,
        128
      ],
      "parameters": {
        "width": 464,
        "height": 288,
        "content": "## Airtable Structure Requirements\n\n* [Airtable Streucture Requirement](https://drive.google.com/drive/folders/1dE4sXikesaTpLE-Pc-VU3mqg0fMZ8EDU)"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "a65334dc-af68-429c-960c-fff711cf5fe5",
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Get Airtable Orders Records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Products": {
      "main": [
        [
          {
            "node": "Search Product ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse in HTTP": {
      "main": [
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append Customers": {
      "main": [
        [
          {
            "node": "Get Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Data Preparation": {
      "main": [
        [
          {
            "node": "Parse in HTTP",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items1": {
      "main": [
        [],
        [
          {
            "node": "Create Invoice URL",
            "type": "main",
            "index": 0
          }
    
Pro

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

About this workflow

It intelligently syncs confirmed sales orders from your Airtable base to QuickBooks, automatically creating new customers if they don't exist before generating a perfectly matched invoice. It then logs all invoice details back into Airtable, creating a flawless, end-to-end…

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

More Data & Sheets workflows → · Browse all categories →

Related workflows

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

Data & Sheets

This premium n8n workflow harnesses the power of DataForSEO's API combined with Airtable's relational database capabilities to transform your keyword research process, providing deeper insights for co

HTTP Request, Airtable
Data & Sheets

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Airtable, HTTP Request, Google Drive +1
Data & Sheets

This workflow automates the entire lifecycle of a service-based client, combining four distinct business flows into a single view: Intake Leads: Receives a webhook from your form builder, validates th

Airtable, Notion, Google Calendar +3
Data & Sheets

Who is this for? Business who manually prep/route DocuSign envelopes and want zero-touch contract signing from form submission.

Airtable, HTTP Request
Data & Sheets

Stop manually copy-pasting client data into Word templates. This workflow automates the entire invoicing process, handling complex line items, VAT calculations, PDF generation, and CRM syncing in unde

Airtable, Google Drive, HTTP Request