Downloads
Download the n8n workflow (JSON)
hubspot-deals-to-quickbooks-invoices-n8n.json · n8n workflow · 22 steps · starts with Check Every Hour · uses HubSpot, Slack, Quickbooks · 36 KB
Import into n8n: Create Workflow, then the menu, then Import from File.
How to import it into n8n
- In n8n, create a new workflow.
- Open the ⋯ menu at the top right and choose Import from File, then pick the downloaded .json. (Or open the file, copy everything and paste it on the canvas.)
- Open each node with a warning and connect your own account: the file carries no passwords or keys.
- Run it once with Test workflow, check the result, then switch it to Active.
What this workflow does
Stop retyping won deals into QuickBooks. Every hour this workflow picks up HubSpot deals that moved to Closed Won, creates a matching QuickBooks Online invoice with every line item, and writes the invoice number back to the deal so it can never be billed twice. Small invoices are emailed to the client straight away; big ones wait in Slack for a finance check.
- Check Every Hour starts the run. Workflow Configuration holds every value you can change.
- Find Won Deals Without Invoice searches HubSpot for deals in your won stage whose
quickbooks_invoice_numberproperty is still empty, newest first. Keep New Deals With Amount drops deals that closed beforestartFromCloseDateor have no amount, and Loop Over Deals handles them one at a time. - Get Deal Contacts and Line Items reads the deal with its associated contact and line item IDs. Get Deal Contact loads the contact. If Contact Has Email? fails, Flag Deal as Missing Contact writes
MISSING-CONTACTon the deal (so it isn't retried every hour) and Ask Sales to Add a Contact posts to Slack. - Get Line Item Details loads name, quantity, price, amount, SKU and description of each line item. Find Customer by Email looks the contact up in QuickBooks; Customer Already in QuickBooks? reuses that customer or Create QuickBooks Customer creates one with company, name, phone and billing address.
- Build Invoice turns every HubSpot line item into a QuickBooks invoice line (deal amount as one line if there are none), sets the due date from
paymentTermsDaysand adds your memo. Create QuickBooks Invoice creates it and Save Invoice Number on Deal writes the number back to HubSpot. - Send Invoice Automatically? checks
autoSendInvoicesandautoSendLimit. Small invoices go out through Email Invoice to Customer and Post Invoice Sent to Slack confirms it. Bigger ones go to Ask Finance to Review Invoice with a link to the invoice in QuickBooks. - If any HubSpot or QuickBooks step fails, Alert Finance About Failed Deal posts the deal, the failed step and the error to Slack, and the loop moves on to the next deal.
Who it is for
Agencies, SaaS companies, consultants, wholesalers and any B2B team that sells in HubSpot and bills in QuickBooks Online. Useful for founders who do their own billing and for finance teams who are tired of chasing sales for invoice details.
What you need
- n8n (Cloud or self-hosted)
- HubSpot account (free CRM works; line items need Sales Hub Starter or the free products library)
- QuickBooks Online account and an Intuit developer app for the OAuth2 credential
- Slack workspace
- n8n (cloud or self-hosted)
The workflow, step by step
Step 1 · Find won deals
Every hour, gets won deals with no invoice number that closed after startFromCloseDate and have an amount, then handles them one by one.
- Check Every Hour (Schedule)
- Workflow Configuration (Set)
- Find Won Deals Without Invoice (HubSpot)
- Keep New Deals With Amount (Filter)
- Loop Over Deals (Loop Over Items)
Step 2 · Contact check
Reads the deal with its contact and line item IDs, then checks the contact has an email.
- Get Deal Contacts and Line Items (HTTP Request)
- Get Deal Contact (HubSpot)
- Contact Has Email? (IF)
Step 3 · QuickBooks customer
Gets the line item details, then finds the customer by email or creates a new one.
- Get Line Item Details (HTTP Request)
- Find Customer by Email (QuickBooks)
- Customer Already in QuickBooks? (IF)
- Create QuickBooks Customer (QuickBooks)
Step 4 · Create invoice
One invoice line per HubSpot line item. The invoice number is saved on the deal so it is never billed twice.
- Build Invoice (Code)
- Create QuickBooks Invoice (HTTP Request)
- Save Invoice Number on Deal (HubSpot)
Step 5 · Send or review
Small invoices are emailed by QuickBooks right away. Bigger ones go to Slack for finance to check first.
- Send Invoice Automatically? (IF)
- Email Invoice to Customer (QuickBooks)
- Ask Finance to Review Invoice (Slack)
- Post Invoice Sent to Slack (Slack)
Step 6 · Missing contact
No email on the contact: the deal is marked MISSING-CONTACT so it is not retried every hour, and sales is asked in Slack to fix it.
- Flag Deal as Missing Contact (HubSpot)
- Ask Sales to Add a Contact (Slack)
Step 7 · Failure alert
Any failed step posts the deal, the step and the error to Slack, then the next deal is handled.
- Alert Finance About Failed Deal (Slack)
Setup
- Download the JSON below and import it in n8n (Create workflow > ⋯ > Import from File).
- In HubSpot, create a private app (Settings > Integrations > Private apps) with the scopes
crm.objects.deals.read,crm.objects.deals.write,crm.objects.contacts.readandcrm.objects.line_items.read. Add its token in n8n as a HubSpot App Token credential and select it on the four HubSpot nodes and the two HubSpot HTTP Request nodes. - In HubSpot, add a deal property: Settings > Properties > Deal properties > Create, type "Single-line text", internal name
quickbooks_invoice_number. - Add a QuickBooks Online OAuth2 credential (Intuit developer app, sandbox or production) and select it on the three QuickBooks nodes and on Create QuickBooks Invoice.
- Add a Slack credential and invite the bot to your finance channel.
- Open Workflow Configuration and set:
-
wonDealStage: internal ID of your won stage (closedwonin the default pipeline) -startFromCloseDate: only deals closed on or after this date are invoiced; set it to today -hubspotPortalId: your HubSpot account ID, used for deal links -quickbooksCompanyId: your QuickBooks company ID (realm ID) -quickbooksApiUrlandquickbooksAppUrl:https://quickbooks.api.intuit.comandhttps://app.qbo.intuit.comfor live,https://sandbox-quickbooks.api.intuit.comandhttps://app.sandbox.qbo.intuit.comfor sandbox -defaultItemId: the QuickBooks product/service ID used on every line (for example your "Services" item) -paymentTermsDays,autoSendInvoices,autoSendLimit,slackChannel,invoiceMemo - Test in a QuickBooks sandbox (see Test data), then activate.
How to customise
- The sample Slack messages and invoice memo are a starting point, not a fixed format. Rewrite them for your business.
- Post Invoice Sent to Slack, Ask Finance to Review Invoice, Ask Sales to Add a Contact, Alert Finance About Failed Deal: message text
- Build Invoice: line mapping and due date
- Check Every Hour: schedule
autoSendLimit: review threshold- Map products to QuickBooks items: in Build Invoice, replace
config.defaultItemIdwith a lookup onp.hs_skuso each product lands on its own QuickBooks item and income account. - Tax: add
TxnTaxDetailor aTaxCodeRefper line in Build Invoice if your QuickBooks company uses automated sales tax or GST. - Use another pipeline: change
wonDealStage, or add a second filter onpipelinein Find Won Deals Without Invoice. - Review everything: set
autoSendInvoicesto false and every invoice waits for finance. - Email instead of Slack: swap the four Slack nodes for Gmail or Outlook nodes.
Why there is no AI step
Invoices are money documents: the customer, the amounts and the due date must match HubSpot exactly, every time. A language model adds cost and a small chance of a wrong number without adding anything a few lines of mapping can't do. The "smart" parts here (find-or-create, the never-bill-twice lock, the review threshold) are plain rules you can read and audit.
Guardrails
- First run: Every won deal without an invoice number that closed on or after startFromCloseDate gets invoiced. Set that date to today before you activate.
Troubleshooting
- Credential errors after import: imported workflows never include credentials. Open each node marked red and select your own account.
- Nothing runs on its own: test runs only fire once. Activate the workflow so the trigger keeps running.
- Odd times or dates: set your timezone in Workflow Settings.
Want the members-only resources too?
A free account unlocks them all, including the ones shared in DMs.

