AutomationFlowsFinance › Client Billing Detail Collection & Invoice Generation with Gmail and Quickbooks

Client Billing Detail Collection & Invoice Generation with Gmail and Quickbooks

ByRosh Ragel @roshragel on n8n.io

This workflow allows you to quickly generate and send invoices by collecting missing billing details from clients through an automated form and email sequence. It integrates Gmail and QuickBooks Online to handle the full billing flow: from request to invoice, reducing manual…

Event trigger★★★★☆ complexity15 nodesQuickBooksForm TriggerGmail
Finance Trigger: Event Nodes: 15 Complexity: ★★★★☆ Added:

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

This workflow follows the Form Trigger → Gmail 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
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "2133d58e-bd7c-4c7a-806a-71f2f10bd400",
      "name": "Add Client to QBO",
      "type": "n8n-nodes-base.quickbooks",
      "onError": "continueRegularOutput",
      "position": [
        1280,
        300
      ],
      "parameters": {
        "operation": "create",
        "displayName": "={{ $json.data['Company Name'] ? $json.data['Company Name'] : $json.data['First Name'] + \" \" + $json.data['Last Name'] }}",
        "additionalFields": {
          "BillAddr": {
            "details": {
              "City": "={{ $json.data.City }}",
              "Line1": "={{ $json.data['Street Address'] }}",
              "PostalCode": "={{ $json.data['Zip / Postal Code'] }}",
              "CountrySubDivisionCode": "={{ $json.data['State / Province'] }}"
            }
          },
          "GivenName": "={{ $json.data['First Name'] }}",
          "FamilyName": "={{ $json.data['Last Name'] }}",
          "CompanyName": "={{ $json.data['Company Name'] }}",
          "PrimaryPhone": "={{ $json.data['Phone Number'] }}",
          "PrimaryEmailAddr": "={{ $('Enter Client Details').item.json['What is the client\\'s email?'] }}"
        }
      },
      "credentials": {
        "quickBooksOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "20b9b6cd-1edf-47ac-89e5-bc9234f81863",
      "name": "Find Existing Customer",
      "type": "n8n-nodes-base.quickbooks",
      "position": [
        1540,
        300
      ],
      "parameters": {
        "limit": 1,
        "filters": {
          "query": "=WHERE DisplayName = '{{ $('Ask Client for Billing Info').item.json.data['Company Name'] ? $('Ask Client for Billing Info').item.json.data['Company Name'] : $('Ask Client for Billing Info').item.json.data['First Name'] + \" \" + $('Ask Client for Billing Info').item.json.data['Last Name'] }}'"
        },
        "operation": "getAll"
      },
      "credentials": {
        "quickBooksOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "59da9e15-0c9f-4515-8913-75a6a227ee19",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "width": 660,
        "height": 1520,
        "content": "## Ask Client for Billing Details and Automatically Generate an Invoice in QuickBooks\n\n## What It Does\nThis workflow allows you to quickly generate and send invoices by collecting missing billing details from clients through an automated form and email sequence. It integrates Gmail and QuickBooks Online to handle the full billing flow: from request to invoice, reducing manual data entry and time wasted switching between apps.\n\nPerfect for freelancers, service providers, or teams that want to streamline invoicing without going back and forth with clients.\n\n## Prerequisites\n- Gmail OAuth2 credential  \n- QuickBooks Online OAuth2 credential\n\n## How It Works\n1. **Trigger:** Manually start the workflow by filling out a form with the client\u2019s email, invoice amount, description, and product.\n2. **Send Request Email:** A pre-written email is sent to the client asking them to provide their billing details.\n3. **Collect Info:** The client submits their billing name and address via a hosted form.\n4. **Add/Find Client in QuickBooks:** If the client doesn't exist, a new record is created; otherwise, the existing client is used.\n5. **Generate Invoice:** A QuickBooks invoice is created using the submitted info and selected product.\n6. **Send Invoice:** The invoice is automatically emailed to the client using QuickBooks' native interface.\n\n## Example Use Cases\n- Freelancers requesting billing info before sending an invoice  \n- Small businesses invoicing new clients without manual QuickBooks entry  \n- Sales or ops teams who want to request billing info via email with just a few clicks  \n- Automating follow-up for new customer onboarding or service requests\n\n## Setup Instructions\n- Connect your Gmail and QuickBooks credentials  \n- Add your products to the dropdown list in the `Enter Client Details` node  \n  \u26a0\ufe0f Make sure the product names **exactly match** the items in QuickBooks  \n- Select the tax code in the `Create A New Invoice` node\n- Customize the email message in the `Send Invoice Request` Gmail node to reflect your brand voice\n\n## How to Use\n- Copy the public URL from the `Enter Client Details` node (this way you don't have to trigger the workflow manually inside n8n) \n- Each time you need to invoice a client, open the form and fill in:\n  - Client\u2019s email  \n  - Product/service name  \n  - Invoice amount and description  \n- The client receives an email prompting them to fill in their billing info  \n- Once submitted, the system creates and sends a QuickBooks invoice automatically\n\n## Customization Options\n- Add support for multiple line items  \n- Automatically send reminder emails if the form isn't completed within a day  \n- Add internal logging (Google Sheets, Airtable, etc.) for sent/paid invoices\n\n## Why It's Useful\nThis workflow removes friction from your billing process. Instead of chasing clients for info and copying data into QuickBooks, you send one email and automation does the rest. It saves time, reduces errors, and makes invoicing feel seamless \u2014 while still keeping you in control."
      },
      "typeVersion": 1
    },
    {
      "id": "5100a4f0-9357-46ce-925c-e778537d8596",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        700,
        120
      ],
      "parameters": {
        "color": 7,
        "height": 360,
        "content": "## Enter Client Info\n- **Tip:** Save the production URL in this node to use it outside n8n.\n- Fill out this form to start the workflow\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d1781318-a495-4002-9a01-635826825d22",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        120
      ],
      "parameters": {
        "color": 7,
        "height": 360,
        "content": "## Ask Client for Info\nSends an email from your official Gmail account, asking the client for their billing info"
      },
      "typeVersion": 1
    },
    {
      "id": "50502c72-0921-468c-a483-e861d6f40b64",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1220,
        120
      ],
      "parameters": {
        "color": 7,
        "height": 360,
        "content": "## Add Client to QBO\nTries to add a new customer to QuickBooks"
      },
      "typeVersion": 1
    },
    {
      "id": "d45d96d0-848f-4d9a-8c53-ce7ba5256eee",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1480,
        120
      ],
      "parameters": {
        "color": 7,
        "height": 360,
        "content": "## Find Existing Customer\nSearches your QuickBooks account for a customer with the same display name"
      },
      "typeVersion": 1
    },
    {
      "id": "6e5fba54-007f-4010-bda6-77db06f243db",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        500
      ],
      "parameters": {
        "color": 7,
        "height": 380,
        "content": "## Create A New Invoice\nBuilds a draft invoice in QBO using the client info and line item details (amount + description) from the n8n form.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "771d0b92-7ddd-42de-88e5-7d55518126e4",
      "name": "Enter Client Details",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        760,
        300
      ],
      "parameters": {
        "options": {
          "appendAttribution": true
        },
        "formTitle": "Enter Client Details",
        "formFields": {
          "values": [
            {
              "fieldLabel": "What is the client's first name?",
              "requiredField": true
            },
            {
              "fieldLabel": "What is the client's email?",
              "requiredField": true
            },
            {
              "fieldType": "dropdown",
              "fieldLabel": "Product",
              "fieldOptions": {
                "values": [
                  {
                    "option": "Item A"
                  },
                  {
                    "option": "Misc"
                  }
                ]
              },
              "requiredField": true
            },
            {
              "fieldType": "textarea",
              "fieldLabel": "Description of what is being sold",
              "requiredField": true
            },
            {
              "fieldType": "number",
              "fieldLabel": "Amount (before taxes)",
              "requiredField": true
            },
            {
              "fieldType": "date",
              "fieldLabel": "Invoice Due Date",
              "requiredField": true
            }
          ]
        },
        "formDescription": "Please enter the client's details so we can contact them for their billing info."
      },
      "typeVersion": 2.2
    },
    {
      "id": "059a40f3-d1e7-49dc-bdc5-7ca694abfda9",
      "name": "Ask Client for Billing Info",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1020,
        300
      ],
      "parameters": {
        "sendTo": "={{ $json['What is the client\\'s email?'] }}",
        "message": "=Hello {{ $json['First Name'] || 'Customer' }},\n\nCompany A is requesting your billing information in order to create an invoice and finalize your order.\n\n**Description:** {{ $json['Description of what is being sold'] }}  \n**Amount (before tax):** ${{ $json['Amount (before taxes)'] }}\n\nPlease fill in the form below so we can complete your invoice.\n\nThanks,  \nCompany A",
        "options": {},
        "subject": "Billing Details Required",
        "operation": "sendAndWait",
        "formFields": {
          "values": [
            {
              "fieldLabel": "First Name",
              "requiredField": true
            },
            {
              "fieldLabel": "Last Name",
              "requiredField": true
            },
            {
              "fieldLabel": "Company Name"
            },
            {
              "fieldLabel": "Street Address",
              "requiredField": true
            },
            {
              "fieldLabel": "City",
              "requiredField": true
            },
            {
              "fieldLabel": "State / Province",
              "requiredField": true
            },
            {
              "fieldLabel": "Zip / Postal Code",
              "requiredField": true
            },
            {
              "fieldLabel": "Phone Number"
            }
          ]
        },
        "responseType": "customForm"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "cb1cf1c9-451f-4569-ac4e-8b79e2553007",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1220,
        500
      ],
      "parameters": {
        "color": 7,
        "height": 380,
        "content": "## Send Invoice to Client\nSends the Finished Invoice to the Client\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f3bdf106-ca87-45ce-8b39-5ba6fbd7e5e1",
      "name": "Get The Selected Product",
      "type": "n8n-nodes-base.quickbooks",
      "position": [
        740,
        700
      ],
      "parameters": {
        "limit": 1,
        "filters": {
          "query": "=WHERE name = '{{ $('Enter Client Details').item.json.Product }}'"
        },
        "resource": "item",
        "operation": "getAll"
      },
      "credentials": {
        "quickBooksOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "554069d5-19b2-4d58-9dc1-f815e9db1214",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        700,
        500
      ],
      "parameters": {
        "color": 7,
        "height": 380,
        "content": "## Get Selected Product\nGets the product you selected from the form via QuickBooks\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1e9df5ae-6742-41ea-adad-6484d35e6186",
      "name": "Create A New Invoice",
      "type": "n8n-nodes-base.quickbooks",
      "position": [
        1020,
        700
      ],
      "parameters": {
        "Line": [
          {
            "Amount": "={{ $('Enter Client Details').item.json['Amount (before taxes)'] }}",
            "itemId": "={{ $json.Id }}",
            "DetailType": "SalesItemLineDetail",
            "TaxCodeRef": "5",
            "Description": "={{ $('Enter Client Details').item.json['Description of what is being sold'] }}"
          }
        ],
        "resource": "invoice",
        "operation": "create",
        "CustomerRef": "={{ $('Find Existing Customer').item.json.Id ? $('Find Existing Customer').item.json.Id : $('Add Client to QBO').item.json.Id }}",
        "additionalFields": {
          "DueDate": "={{ $('Enter Client Details').item.json['Invoice Due Date'] }}",
          "BillEmail": "={{ $('Enter Client Details').item.json['What is the client\\'s email?'] }}"
        }
      },
      "credentials": {
        "quickBooksOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "168a75d0-9fd3-486d-9676-a8a64cce394c",
      "name": "Send the Invoice",
      "type": "n8n-nodes-base.quickbooks",
      "position": [
        1280,
        700
      ],
      "parameters": {
        "email": "={{ $('Enter Client Details').item.json['What is the client\\'s email?'] }}",
        "resource": "invoice",
        "invoiceId": "={{ $json.Id }}",
        "operation": "send"
      },
      "credentials": {
        "quickBooksOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Add Client to QBO": {
      "main": [
        [
          {
            "node": "Find Existing Customer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create A New Invoice": {
      "main": [
        [
          {
            "node": "Send the Invoice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Enter Client Details": {
      "main": [
        [
          {
            "node": "Ask Client for Billing Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find Existing Customer": {
      "main": [
        [
          {
            "node": "Get The Selected Product",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get The Selected Product": {
      "main": [
        [
          {
            "node": "Create A New Invoice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ask Client for Billing Info": {
      "main": [
        [
          {
            "node": "Add Client to QBO",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

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

About this workflow

This workflow allows you to quickly generate and send invoices by collecting missing billing details from clients through an automated form and email sequence. It integrates Gmail and QuickBooks Online to handle the full billing flow: from request to invoice, reducing manual…

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

More Finance workflows → · Browse all categories →

Related workflows

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

Finance

Automatically processes vendor invoices received by email, creates QuickBooks bills with full details, and attaches the original PDF. Small/medium businesses using QuickBooks Online Bookkeepers proces

Gmail Trigger, Information Extractor, OpenAI Chat +3
Finance

This is the ultimate sales-to-cash automation. When a deal in Airtable is marked "Approved for Invoicing," this workflow intelligently syncs customer data across QuickBooks and Stripe (creating them i

Airtable Trigger, Stripe, QuickBooks +2
Finance

How It Works Trigger: Watches for new emails in Gmail with PDF/image attachments. OCR: Sends the attachment to OCR.space API (https://ocr.space/OCRAPI) to extract invoice text. Parsing: Extracts key f

Gmail Trigger, Google Sheets, Slack +3
Finance

Automated Stripe Payment to QuickBooks Sales Receipt

HTTP Request, Stripe, Stripe Trigger +1
Finance

Upload the same invoice in different qualities (original PDF, scanned copy, phone photo, compressed JPEG, etc.) and instantly see how accurately each field was extracted. The workflow compares every e

Form Trigger, @Easybits/N8N Nodes Extractor, Form