Help centre

How can we help?

Guides, FAQ, and integration walkthroughs. Search or browse by topic.

← All topics

Accounting Xero and QuickBooks

Accounting: Xero and QuickBooks

Push invoices, payments and contacts straight from the CRM into your accounting ledger. No CSV exports, no manual re-entry, no month-end panic. Same CRM, two separate integrations - pick whichever your accountant already uses.

Before you start

  • An active Xero or QuickBooks Online subscription. QuickBooks Desktop is not supported (different API).
  • Admin access to the accounting file. Xero Standard user role or QuickBooks Company Admin role are enough.
  • Your Chart of Accounts already set up in the accounting product. The CRM pushes invoices to your default Sales account; if you have not defined one, the sync will fail.
  • 15 minutes for whichever integration you choose.

Xero setup

Step X1: Create a Xero developer app

  1. Go to developer.xero.com and sign in with the same account you use for Xero.
  2. Click My apps in the top nav.
  3. Click New app.
  4. Fill in:
    • App name: Unavoidable CRM
    • Integration type: Web app
    • Company or application URL: your CRM URL (e.g. https://crm.example.com)
    • Redirect URI: the CRM shows you the exact URI to paste inline in the credentials form (Settings > Integrations > Accounting > Xero, click + Add credentials). It looks like https://crm.example.com/api/accounting.php?action=oauth_callback&provider=xero.
  5. Accept the terms and click Create app.

Step X2: Grab the credentials

  1. On the app detail page, copy the Client ID.
  2. Under Client secrets, click Generate a secret. Copy immediately - Xero shows it only once.

Step X3: Save credentials in the CRM

  1. In the CRM go to Settings > Integrations.
  2. In the Accounting integrations card, find the Xero panel.
  3. Click + Add credentials.
  4. Paste Client ID and Client Secret.
  5. Click Save and connect. The CRM stores the credentials and immediately redirects you to Xero's OAuth authorisation.

Step X4: Authorise the connection

  1. On Xero's screen, select the organisation (Xero file) you want the CRM to write to. Do not pick "Demo Company" unless you are testing.
  2. Review the requested permissions: Accounting - Contacts and Invoices (read and write). Click Allow access.
  3. You are redirected back to the CRM with a Connected pill next to Xero showing the organisation name.

QuickBooks setup

Step Q1: Create an Intuit developer app

  1. Go to developer.intuit.com and sign in with your Intuit account (same email as QuickBooks).
  2. Top-right menu > My apps.
  3. Click Create an app.
  4. Choose QuickBooks Online and Payments.
  5. App name: Unavoidable CRM. Click Create app.

Step Q2: Add scopes

  1. On the app dashboard, left nav: Development > Keys and OAuth.
  2. Under Scopes, tick com.intuit.quickbooks.accounting. Do not tick Payments unless you also want to route card transactions through QB Payments (advanced).

Step Q3: Configure redirect URI

  1. Still on Keys and OAuth, scroll to Redirect URIs.
  2. Click Add URI.
  3. Paste the exact URI shown inline in the CRM's Settings > Integrations > QuickBooks credentials form: https://crm.example.com/api/accounting.php?action=oauth_callback&provider=quickbooks.
  4. Save.

Step Q4: Copy the credentials

  1. Under Development > Keys and OAuth > Development Settings, copy Client ID and Client Secret.
  2. You are using development keys. Once you are live, move the app to Production keys - separate values.

Step Q5: Save credentials in the CRM

  1. In the CRM go to Settings > Integrations > Accounting integrations > QuickBooks.
  2. Click + Add credentials.
  3. Paste Client ID and Client Secret.
  4. Click Save and connect.

Step Q6: Authorise

  1. Intuit's screen asks you to pick a QuickBooks company. If you have several (subscription, or accountant with many clients), pick the right one carefully - the connection binds to that company.
  2. Click Connect.
  3. Redirected back to the CRM with Connected status.

What syncs

ObjectDirectionTrigger
InvoicesCRM → accountingClick "Push to Xero/QB" on any invoice
PaymentsCRM → accountingFires automatically when Stripe or GoCardless webhook marks invoice as paid
ContactsCRM → accountingCreated just-in-time when the first invoice is pushed for that contact
Chart of AccountsAccounting → CRMPulled on connection so the CRM can show your account list when configuring line items
Tax ratesAccounting → CRMSame as above

Payments push automatically only if the invoice has already been pushed. Otherwise the payment record has nothing to reconcile against. Do not manually push payments; let the webhook handle it.

How to test it works

  1. Create a test invoice for 1 GBP in the CRM.
  2. Click Push to Xero (or QuickBooks).
  3. Within 5 seconds, refresh the invoices list in Xero/QB. The invoice should appear as Draft with the correct customer and amount.
  4. Mark it paid in the CRM (or actually pay it via Stripe test mode).
  5. The invoice status in Xero/QB should update to Paid within 10 seconds of the payment webhook.

Common problems

OAuth returns "invalid_redirect_uri"
The redirect URI in the accounting app does not exactly match what the CRM sends. Copy the URI from the CRM's inline hint (Settings > Integrations > Xero or QB > + Add credentials) and paste verbatim.
Push invoice returns "Contact not found"
The CRM tries to create the contact just-in-time but the contact in the CRM has no email address. Both Xero and QB require an email to create a contact. Fill in the email, then re-push.
Push invoice returns "Account code required"
Your invoice has line items with no account mapping. Either set a default sales account under Settings > Accounting mapping, or manually pick an account per line item.
"Token expired" then breaks all subsequent syncs
OAuth refresh cycle failed. Disconnect and reconnect. Xero refresh tokens last 60 days; QB tokens last 100 days. If your CRM was offline for that long, the refresh is invalid and you must re-authorise.
Same invoice appears twice in QB after re-push
QB does not deduplicate on external ID by default. The CRM stores the QB invoice ID after first push; if you delete it in QB and then push again, you get a fresh one. Reset by clearing the invoice's accounting_external_id in the CRM before re-pushing.
Xero shows "connection expired" and re-auth loops back to expired
Your Xero user role does not have the Standard Accounting permission needed to grant Accounting scope. Get an admin to change your role, then reconnect.

What this unlocks in the CRM

Month end takes minutes not days. Your accountant sees clean, categorised invoices in Xero/QB as they happen, not in a Friday afternoon batch. VAT returns are automatic because tax rates match. And when Stripe pays, GoCardless pays or someone hands you cash, the reconciled payment flows through to the ledger without you touching it.

Still stuck?
Email us and we’ll come back within one business day.
info@unavoidablecrm.com