← Guides
Integration How-Tos·9 min read·

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:

  1. Reads the deal's details: amount, line items, associated contact, close date
  2. Looks up or creates the corresponding contact in Xero
  3. Creates a Xero invoice using the deal's data
  4. 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.

What the native integration does, and where it stops

HubSpot publishes its own Xero integration, "Xero by HubSpot", and it is free on every HubSpot plan including the free one. Check it before building anything, because for a lot of businesses it is enough on its own.

What it does is keep contacts in step between the two systems. What it does not do is the thing this guide is about:

  • It syncs contacts between HubSpot and Xero, but it does not create an invoice when a deal moves stage
  • It does not build line items out of deal properties
  • It gives you no control over invoice formatting, due dates or approval logic
  • Mapping your own custom fields between the two systems needs Data Hub Starter, HubSpot's lowest paid data tier

So for contact syncing, use the native integration and save yourself the work. For an invoice that fires off a deal stage, you need something custom, and that is what the rest of this guide covers.

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: the route above uses the CRM Webhooks API, which is configured on a private app rather than on your portal, so it is not gated behind a particular Hub tier. Worth knowing, because the alternative route is: if you build this using a HubSpot workflow with a "trigger a webhook" action instead, that action requires Data Hub Professional or Enterprise. Data Hub is the current name for what used to be Operations Hub
  • 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:

  1. Create a test deal in HubSpot with clean data
  2. Move it to the trigger stage
  3. Verify the Xero invoice is created correctly: correct contact, correct amounts, correct dates
  4. Test the error handling by intentionally passing bad data and confirming you receive the error alert
  5. 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.

Connecting a CRM to accounting cleanly is a systems integration problem more than a Xero problem. Most of the difficulty sits in contact matching and error handling rather than in either product.

Need this built for your business?

Describe what you're working with and we'll come back with something specific, not a sales call.

Get your free audit