- Customer✓
- Line items✓
- Total✓
The HubSpot to QuickBooks integration takes an hour to set up, and the first invoices look fine in QuickBooks. Customer is there, line items are there, the amounts add up. Four weeks later a client asks why they never received an invoice. It has been sitting in QuickBooks for four weeks, with no recipient.
We solved exactly this for a B2B consultancy in North America that sells its retainers through HubSpot and bills in QuickBooks Online. The client stays unnamed here. The pattern is common enough to be worth a closer look.
The short version
- The native sync turns contacts into customers and HubSpot invoices into QuickBooks invoices. It does not transfer companies.
- The billing email on the QuickBooks invoice stays empty. Without it, QuickBooks cannot send the invoice.
- There are three ways to handle it: type it in by hand, a Zapier or Make scenario, or a workflow of your own. We chose the third, with n8n, without switching off the native sync.
What the native sync transfers
HubSpot’s QuickBooks app connects two data models that do not line up. HubSpot thinks in contacts, companies and deals. QuickBooks thinks in customers and documents. The sync translates contacts into customers and HubSpot invoices into QuickBooks invoices. The company you actually bill in B2B has no place in that translation.
- ✓Customer
- ✓Line items and amounts
- ✓Document number
- Billing email (BillEmail)
For a customer with one contact person this barely shows. As soon as several contacts belong to the same company it gets messy, because QuickBooks requires a unique display name per customer. In our case, though, a different field was the decisive one.
The gap: the billing email
A QuickBooks invoice has a field for the recipient address, called BillEmail in the API. The sync from HubSpot does not fill it. The invoice is created, has a customer, line items and a document number, but no address QuickBooks could send it to. In the interface you only notice once someone clicks Send.
For a one-off invoice you add the address and grumble for a moment. For a consultancy with monthly retainers it happens every month, for every client. That is exactly where automation pays off.
Three ways, and what they cost
Native app plus manual work. Free and set up in an hour. The gap stays, and someone has to close it every month. For a handful of invoices a month that is fine.
Zapier or Make. A scenario that polls for new QuickBooks invoices and adds the address is built in an afternoon. You pay per run, and the fallback logic gets unwieldy quickly in these tools.
A workflow of your own. Full control over time windows, retries and what exactly gets written. This used to mean custom development with maintenance. With n8n you get almost the same control without maintaining code, and without a fee per run.
Our decision: the native sync stays, because it transfers customers, line items and document numbers reliably. A workflow next to it closes the one gap.
What the workflow looks like
The workflow runs in n8n on the client’s side and does the same thing every 15 minutes:
- Every 15 minutes
- QuickBooks: load invoices from the last 30 minutes
- Billing email empty?Only these invoices continue
- Get the email from the QuickBooks customer
- Otherwise: find the HubSpot invoice by document number, use the contact emailFallback when the customer record has no email
- Write the billing emailOnly this field, only when an address was found
- Optional: send the invoice from QuickBooksActive only after the test run
The 30-minute window deliberately overlaps the 15-minute schedule. If one run fails, the next one catches up. Writing happens as a sparse update, so only the one field. Everything else on the invoice stays untouched.
The fallback through HubSpot is the part that makes it complete. If the QuickBooks customer has no email on file, the workflow finds the HubSpot invoice with the same document number, goes to the associated contact and uses that address. If there is nothing there either, it writes nothing. Writing an empty address would be worse than doing nothing at all.
Sending the invoice automatically is a separate step in the workflow and stays off at first. Only once the right addresses have been landing on the right invoices for a few weeks does it get switched on.
What to watch out for if you build this yourself
- Sandbox first. QuickBooks has one, use it. Switching to production should end up being two values in the configuration: the base URL and the company ID.
- Document number as the key. The DocNumber is the most reliable join between a HubSpot invoice and a QuickBooks invoice.
- Never write empty. Every step that writes something needs a filter in front of it that checks whether there is anything to write.
- Switch sending separately. That an address is correct and that an invoice goes out are two decisions.
- Pin the API version. QuickBooks changes field behavior between minor versions. A fixed value saves surprises.
What becomes possible afterwards
Once the workflow is in place, the road from HubSpot to QuickBooks is open. Recurring invoices for retainers can be created through the API, straight from the won deal, with an interval and a start date. That is the next step for this client.
When it is worth it
If you create a handful of invoices a month from HubSpot in QuickBooks, add the address by hand. From around twenty, or with any recurring billing model, the manual work costs more than the workflow. And it is the kind of work someone eventually forgets.
An integration like this one is one step in a larger project. How we run the whole project, from deciding every field to training the team, is in HubSpot implementation: how it works, step by step.