How to Automatically Create a Xero Invoice When a HubSpot Deal Closes
When a deal closes in HubSpot, someone has to open Xero and create an invoice. That step is manual, it introduces delays, and it's occasionally forgotten when things are busy. The connection between a closed deal and a sent invoice can be automated — and for businesses processing more than a handful of deals per month, it's worth doing.
This guide explains how the HubSpot-to-Xero invoice integration works, what data it uses, and what's needed to build it.
What the automation does
When a deal in HubSpot is moved to the "Closed Won" stage (or any stage you define as the billing trigger), the integration:
- Reads the deal's details — amount, line items, associated contact, close date
- Looks up or creates the corresponding contact in Xero
- Creates a Xero invoice using the deal's data
- Optionally sends the invoice to the client directly, or leaves it as a draft for review
The result: from the moment a salesperson marks a deal as won in HubSpot, the invoice exists in Xero without any additional manual work.
Why HubSpot doesn't do this natively
HubSpot has a Xero integration in its App Marketplace. It's worth checking before building something custom — but it has limitations that lead most businesses to need a custom build:
- The native integration syncs contacts between HubSpot and Xero but doesn't automate invoice creation from deal stage changes
- It doesn't handle complex line items derived from deal properties
- It has limited control over invoice formatting, due dates, or approval logic
- It requires HubSpot Pro tier or above
For simple contact syncing, the native integration is useful. For invoice automation triggered by deal stage, a custom workflow via n8n gives you full control.
How the integration is built
The integration uses n8n as middleware between HubSpot and Xero. If you haven't connected n8n to Xero before, the n8n and Xero integration guide covers the API setup.
Step 1 — Trigger: deal stage change in HubSpot
HubSpot supports webhooks for CRM property changes. You configure HubSpot to send a webhook when the dealstage property on a deal changes to your "Closed Won" stage ID.
In n8n, a Webhook node receives this payload. The payload includes the deal ID, which you use in the next step.
Step 2 — Fetch full deal details
The webhook payload contains the deal ID but not all the deal's properties. Use HubSpot's API (n8n has a native HubSpot node) to fetch the full deal record including:
- Deal name
- Amount
- Close date
- Associated contact and company IDs
- Any custom properties you use for line items, payment terms, or reference numbers
Step 3 — Fetch associated contact details
Use the contact ID to fetch the contact's name, email, and any billing address fields. This is what populates the Xero contact on the invoice.
Step 4 — Look up or create the Xero contact
Use the Xero API to search for an existing contact matching the HubSpot contact's email or company name. If found, use that contact's Xero ID. If not found, create a new Xero contact from the HubSpot data.
This prevents duplicate contacts in Xero — a common problem when automations create new records blindly.
Step 5 — Create the Xero invoice
Using the Xero API's invoice creation endpoint, build the invoice with:
- Contact — the Xero contact ID from step 4
- Invoice date — the deal close date (or today's date)
- Due date — calculated from your payment terms (e.g. close date + 30 days)
- Reference — the HubSpot deal name or deal ID
- Line items — from deal properties (see below)
- Status — DRAFT (for review before sending) or AUTHORISED (to send immediately)
Step 6 — Error handling
Add error notification so that if any step fails — HubSpot API unavailable, Xero rejects the invoice data, contact creation fails — you receive an alert immediately. A Slack message or email from n8n is sufficient. Without this, failed invoices are invisible until someone notices they're missing.
The line item challenge
The most complex part of this integration is line items. A Xero invoice needs itemised lines (description, quantity, unit price, tax rate). Where that data comes from in HubSpot depends on how you structure your CRM.
Simple case — single-line invoice: If your deals have a single amount and description, the invoice has one line: the deal name as description and the deal amount. This is straightforward.
HubSpot Products: HubSpot has a Products library and allows deals to include associated line items from that library. If you're using HubSpot products, the integration can fetch those line items and map them directly to Xero invoice lines. This is the cleanest setup.
Custom deal properties: If line items are stored as custom properties on the deal (a common workaround when teams don't use HubSpot Products), the integration can read those properties and build the Xero lines accordingly. More custom logic required.
No structured line items: If deals just have a total amount and no line item breakdown, the invoice will have a single line. That's fine for simple services businesses.
Before building, decide which approach fits your HubSpot setup.
Invoice as draft vs. send immediately
Whether the automation sends the invoice automatically or leaves it as a draft depends on your confidence in the data quality and the nature of the business.
Send immediately: Works when deals have clean, complete data — correct amounts, correct contacts, correct descriptions. Good for standardised service offerings.
Draft first: Better when deals sometimes have incomplete data, when invoices need review before going to clients, or when senior oversight of invoicing is required. The integration creates the draft in Xero, someone reviews it, and manually sends it. Saves the manual creation step while preserving human review.
A middle option: set a short delay (e.g. 2 hours) between invoice creation and sending. The automation creates the invoice, waits, then sends it unless someone has manually cancelled it in that window.
What you'll need
- HubSpot — any tier with webhook support (Professional and above for CRM webhooks; some workarounds exist for lower tiers using scheduled polling instead)
- Xero — any paid plan with API access
- n8n — self-hosted or cloud
- Xero OAuth 2.0 credentials — set up in the Xero developer portal
- A defined trigger — decide which deal stage triggers the invoice (usually "Closed Won," but sometimes a later stage like "Contract Signed")
Testing before going live
Before activating the integration in production:
- Create a test deal in HubSpot with clean data
- Move it to the trigger stage
- Verify the Xero invoice is created correctly — correct contact, correct amounts, correct dates
- Test the error handling by intentionally passing bad data and confirming you receive the error alert
- Test with a deal where the contact doesn't yet exist in Xero
Running through edge cases in testing is worth the time. Discovered issues in testing are a few minutes of work. Discovered issues in production (when real client invoices are wrong or missing) are expensive.
Some links in this guide are affiliate links. If you sign up through them, Gainly may earn a commission — at no cost to you. We only recommend tools we'd recommend regardless.
Need this built for your business?
Describe what you're working with and I'll come back with something specific — not a sales call.
Tell me what you're dealing with →