Auto-draft Xero invoices from HubSpot Closed Won deals
When a HubSpot deal closes won, this agent drafts the matching Xero invoice, syncs the customer, and posts a confirmation in Slack.
Build me an agent workflow that automates Xero invoicing whenever a HubSpot deal closes won. It fills the gap left by Xero retiring its built-in HubSpot integration in March 2026.
Trigger: a HubSpot webhook subscribed to deal property changes that fires when a deal moves into a Closed Won stage. The webhook payload provides the HubSpot deal ID.
When triggered, the agent should:
1) Pull the deal context from HubSpot. Call HubSpot Get Deal on the deal ID, requesting amount, dealname, dealstage, hubspot_owner_id, the line items association, the primary company association, and the primary contact association. Then call HubSpot Get Company on the associated company to read name, domain, and billing address fields, and HubSpot Get Contact on the primary contact to read firstname, lastname, email, and phone.
2) Find or create the matching Xero contact. Call Xero List Contacts with a where filter on the company name (and fall back to the primary contact email if no company name is available). If no match is found, call Xero Create Contacts to create a new contact using the company name as Name, the primary contact's first and last name as FirstName and LastName, the email as EmailAddress, the phone as a Phones entry, and the billing address as the POBOX or STREET address. Capture the resulting Xero ContactID. If a match is found, reuse its ContactID.
3) Draft the sales invoice with Xero Create Invoices. Set Type to ACCREC, set Contact to the Xero ContactID from step 2, and build LineItems. If the HubSpot deal has line items, map each one to a Xero LineItem (Description from the product name, Quantity, UnitAmount from the unit price, and an AccountCode that defaults to the configured sales account, e.g. 200). If the deal has no line items, create a single LineItem using the deal amount as UnitAmount with Quantity 1 and a Description derived from the deal name. Set DueDate based on the Xero contact's PaymentTerms (fall back to net 30 from today if no terms are set). Use Status DRAFT by default. If the deal amount is below a configurable auto-approve threshold (default off), use Status AUTHORISED instead so the invoice is finalised automatically.
4) Post a confirmation to Slack. Call Slack Bot Send a Message to a configurable sales channel (default #sales). Include the Xero invoice number, the customer name, the amount in the deal currency, the HubSpot deal owner, a link to the invoice in Xero (https://go.xero.com/app/invoicing/invoice/<InvoiceID>), and whether the invoice is in DRAFT or AUTHORISED status.
5) Write the Xero invoice ID back to HubSpot. Call HubSpot Update Deal on the original deal to set a configurable custom property (default property name xero_invoice_id) to the Xero InvoiceID. If the property does not exist yet, surface a setup instruction rather than failing silently.
Be idempotent. Before creating anything, read the xero_invoice_id property on the deal. If it is already populated, skip the create steps and re-post the existing invoice to Slack so duplicate webhook deliveries do not produce duplicate Xero invoices or contacts.
Configuration knobs the workflow should expose: the sales Slack channel, the Xero default sales account code, the auto-approve threshold and currency, the HubSpot custom property name used to store the Xero invoice ID, and the default payment terms used when the Xero contact has none.
Additional information
What does this prompt do?
- Listens for deals moving to Closed Won in HubSpot and kicks off the second the stage flips.
- Looks up or creates the matching customer in Xero from the deal's company and primary contact, so your accounting records stay clean.
- Drafts a sales invoice in Xero with the deal's line items and amount, ready for a quick human review before it goes out.
- Posts a confirmation in Slack with the invoice number, amount, customer, and a link, and writes the Xero invoice ID back onto the HubSpot deal.
What do I need to use this?
- A HubSpot account with a Closed Won stage on your sales pipeline
- A Xero account where you can create contacts and invoices
- A Slack workspace and a channel for sales confirmations
- A custom property on the HubSpot deal to store the Xero invoice ID (optional, the agent can create one)
How can I customize it?
- Set an auto-approve threshold so small deals skip the draft step and go straight to authorised in Xero.
- Change which Slack channel receives the confirmation and tweak the message format.
- Map specific HubSpot products or deal properties to specific Xero account codes and tracking categories.
Frequently asked questions
Does this replace the old built-in Xero to HubSpot integration?
Does it create the customer in Xero if they do not exist yet?
Can I keep invoices in draft for human review?
What happens if the HubSpot deal has no line items attached?
Will the same deal create duplicate invoices if the webhook fires twice?
Stop hand-keying invoices for every deal you win.
Connect HubSpot, Xero, and Slack once, and Geni drafts the invoice the moment a deal closes.