Xero Setup for BillingOne
This runbook walks you through connecting Xero, preparing your catalog and clients, and pushing your first generated invoice. Follow the steps in order — each later step depends on the ones before it.
Primary path: Use the in-app setup wizard on the billing dashboard or Settings → Integrations. The wizard guides OAuth, contact sync, client mapping, and catalog import in one flow.
Navigation: BillingOne → Dashboard (setup checklist) or Settings → Integrations
Before You Start
You will need:
- A Xero organisation with customer contacts, items, and revenue accounts already configured
- Admin or Finance access in BillingOne (integration connect requires appropriate permissions)
- PanelOne clients that correspond to your billable customers
Tip: Keep using your existing Xero organisation. BillingOne generates new invoices and pushes them to Xero — historical invoices stay in Xero and are not duplicated.
Step 1: Connect Xero (in-app wizard)
- Open BillingOne → Dashboard and expand the Xero setup checklist, or go to Settings → Integrations.
- Find Xero under Billing Integrations and click Configure (or Connect in the setup wizard).
- Complete the OAuth authorization flow — you will be redirected to Xero to grant access.
- When you return to BillingOne, confirm Xero shows as Connected.
The wizard uses a platform-owned OAuth app by default. You do not register a developer app or redirect URI unless you choose Bring your own app (BYO).
BYO OAuth (optional)
Only if you bring your own Xero, QuickBooks, or WorkflowMax developer app. Select Bring your own app on the welcome step of the setup wizard, or in Settings → Integrations → Configure for that provider. Copy the redirect URI shown there — the same URI (with a copy button) appears in the accounting setup wizard.
-
Create a developer app at Xero Developer, the Intuit Developer Portal, or your WorkflowMax developer console.
-
Register the production redirect URI in the vendor console. Copy the redirect URI shown there; for reference, production is:
Provider Redirect URI Xero https://api.panelone.dev/functions/v1/xero-oauth-callbackQuickBooks https://api.panelone.dev/functions/v1/quickbooks-oauth-callbackWorkflowMax https://api.panelone.dev/functions/v1/workflowmax-oauth-callback -
Save Client ID and Client Secret in BYO mode, then complete OAuth.
If you set up your own app before July 2026, it may still list an old *.supabase.co address. Replace that address with the production URI in the table above.
Once connected, BillingOne can sync invoice snapshots, import your Xero catalog, and push generated invoices back to Xero.
Step 2: Sync Xero Contacts
- On the Integrations tab, open Client Mappings (or click Map Xero contacts to clients on the Xero card).
- Click Sync contacts from Xero to pull customer contacts into BillingOne.
- Wait for the sync to finish — you should see a count of contacts imported.
Contacts are cached locally so you can map them without returning to Xero for every client.
Step 3: Map Clients to Xero Contacts
Every PanelOne client that receives a pushed invoice must be linked to a Xero contact.
- In the Map Xero contacts to clients dialog, review the suggested matches (exact name matches are applied automatically).
- For unmatched or fuzzy matches, select the correct PanelOne client from the dropdown.
- Click Save mappings.
You can also set xero_contact_id on individual clients from Clients → Edit client → Billing integration mappings, but the bulk mapping dialog is faster for initial onboarding.
Push failure hint —
missing_xero_contact: If a push fails with this hint, the invoice's client has no Xero contact mapping. Return to Client Mappings and link that client before pushing again.
Step 4: Import the Catalog from Xero
- Open BillingOne → Catalog (sidebar).
- Click Import from Xero in the page header.
- Wait for the sync — BillingOne imports Xero items, accounts, and tax rates, then upserts catalog rows.
Import the catalog before building contract templates so line items resolve to the correct Xero item codes and GL accounts at invoice time.
For CSV or manual catalog rows (items not yet in Xero), see CSV Imports.
Step 5: Review Catalog GL Codes and Tax
After import, spot-check catalog rows before you attach them to contracts:
- On the Catalog page, open a row to edit (or review synced rows in the table).
- Confirm the default revenue account (GL code) is set — synced Xero items inherit account mappings where available.
- Confirm the Xero tax code (
xero_tax_type) is correct for each sellable item. - Fix any gaps on CSV or manual rows — they do not inherit Xero metadata until you assign account and tax codes.
Push failure hint —
missing_account_code: If a push fails with this hint, BillingOne could not resolve a Xero sales/revenue account code for one or more lines. Re-import the Xero catalog (which syncs accounts), assign a default revenue account on affected catalog rows, or ensure your Xero organisation has at least one REVENUE/SALES account with a code.
Step 6: Add CSV or Manual Catalog Items (Optional)
Use this when you sell items in BillingOne that are not yet in Xero:
- On Catalog, click Import CSV or New catalog item.
- CSV rows become
source: csv; manual rows becomesource: manual. - Assign revenue account and tax codes on each row before using them on contracts.
See CSV Imports for column formats and headerless positional layout.
Step 7: Create Contract Templates
- Go to Contracts → Templates.
- Create a template that mirrors your standard agreement structure (e.g. per-device managed services, platform fee, labour block).
- Attach catalog items to template lines so generated invoices inherit correct codes and pricing.
- Save the template for reuse across clients.
Templates speed up onboarding when you rebuild agreements client-by-client or import from a PSA export.
Step 8: Configure Invoice Settings
- Open Settings → Integrations → Invoice Settings.
- Review and save:
| Setting | What it controls |
|---|---|
| Billing period | Monthly, quarterly, or annual generate cycle |
| Generate on day | Day of month for scheduled generation |
| Auto-generate | Whether invoices are created on schedule |
| Include service contracts | Pull recurring contract lines into generated invoices |
| Include subscriptions / device counts | Pax8 and metered sources |
| Auto-push to Xero | Push to Xero automatically after generation |
| Invoice prefix | Reference prefix for new invoice numbers |
| Invoice notes | Default footer text (payment terms, thank-you message, etc.) |
Enable Auto-push to Xero only after you have validated a manual push for at least one pilot client.
Step 9: First Generate and Push
- Confirm active service contracts exist for pilot clients (with catalog-linked lines where possible).
- Open Generated invoices.
- Run a manual generate for the current period (or wait for auto-generate if enabled).
- Open a draft invoice and review line descriptions, quantities, tax, and totals.
- Issue the invoice, then click Push to Xero (unless auto-push is already enabled).
- Confirm the invoice appears in Xero with the expected contact, account codes, and tax types.
Compare the first BillingOne invoice against your last manual Xero invoice for each pilot client before rolling out to your full client base.
Troubleshooting
OAuth connect fails immediately
| Symptom | Likely cause | Fix |
|---|---|---|
| "Platform not configured" / 503 | The platform-owned Xero or QuickBooks app is not available | Use Bring your own app, save your credentials, and copy the redirect URI shown there in Settings → Integrations, or contact PartnerOne support |
| BYO credentials missing | BYO mode selected but Client ID/Secret not saved | Save BYO credentials on the integration and copy the redirect URI shown there in the wizard |
| Redirect error from Xero/Intuit | Redirect URI mismatch | For BYO only: copy the redirect URI shown there in Settings → Integrations → Configure (production values are in the table above). The default platform app needs no URI setup |
Returns with xero_oauth=error | State expired or invalid | Restart connect from Settings → Integrations; complete OAuth within 10 minutes |
| Multiple Xero tenants | Org has several Xero companies | Select the correct tenant when prompted after OAuth |
Setup checklist stuck
| Symptom | Fix |
|---|---|
| "Contacts synced" incomplete | Run Sync contacts from Xero on Settings → Integrations → Client Mappings |
| "Clients mapped" incomplete | Map contacts in the client mapping dialog or set xero_contact_id per client |
| "Catalog imported" incomplete | Open Catalog → Import from Xero |
Push failures
| Hint | Meaning | Fix |
|---|---|---|
missing_xero_contact | Client is not mapped to a Xero contact | Settings → Integrations → Client Mappings — link the client |
missing_account_code | No revenue account code on invoice lines | Re-run Import from Xero on Catalog; set default revenue account on catalog rows |
already_linked | Invoice was pushed before | Normal — use force re-push only when intentionally replacing a Xero draft |
QuickBooks Online (Parallel Path)
BillingOne supports QuickBooks Online as an alternative accounting provider. The onboarding flow is the same shape:
- Connect QuickBooks instead of (or alongside) Xero in Settings → Integrations (use the in-app wizard)
- Sync and map QBO customers to PanelOne clients
- Import from QuickBooks on the Catalog page
- Review QBO tax codes and revenue accounts on catalog rows
- Enable Auto-push to QBO in Invoice Settings
- Generate and Push to QuickBooks from Generated invoices
Only one accounting provider drives catalog sync UI at a time (whichever is connected/preferred). Do not connect both unless you understand which provider BillingOne uses for catalog and push on your organisation.
Next Steps
- CSV Imports — Catalog and Gorelo contract CSV formats
- Settings — All billing integrations and account options
- Invoices — Tracking synced and generated invoices