QuickBooks sync
The QuickBooks integration pulls customers, invoices, and payments from QuickBooks Online into concorbit. It is a one-way mirror from QB into concorbit, the QB-side row is the source of truth and concorbit's row is governed by QB until you decide otherwise.
This page describes how that sync ties into the PaymentLedger and how governance precedence works when an invoice is linked to both Autotask and QuickBooks.
What the sync does
When connected, the QuickBooks integration mirrors three entities:
| Entity | Direction | concorbit row |
|---|---|---|
| Customer | QB to concorbit | Linked to a concorbit Company (or Contact) via external_links. |
| Invoice | QB to concorbit | Mirrored as a concorbit Invoice with governance=quickbooks. |
| Payment | QB to concorbit | Mirrored as a payments row with payment_source=quickbooks. |
The sync is idempotent. Re-pulling an invoice or payment that has already been ingested upserts the existing row, it never duplicates. The upsert key is (payment_source, external_reference) for payments and the QB id mapped via external_links for invoices and customers.
Governance: QuickBooks owns QB-mirrored invoices
A governance=quickbooks invoice is owned by QB:
Status,
amount_paid, andpaid_atare set from QB's flags on every sync pull.concorbit's lifecycle (autopay, dunning, the £0 paid lifecycle, dispute freezes) does not apply.
Recording a payment, voiding, or refunding through concorbit's UI is refused. Do the action in QB and the next sync mirrors the result.
This protects the ledger from desync. The concorbit row is a view of QB's truth, not an independent source.
Precedence: AT wins over QB
When an invoice is linked to both Autotask and QuickBooks (which can happen on a co-billed tenant during migration), Autotask takes precedence:
AutotaskInvoiceSyncruns first and stampsgovernance=autotask.QuickBooksInvoiceSyncrecognises the AT-governed marker and refuses to re-stamp.The result: AT-governed lifecycle, QB acts as a read-only secondary mirror.
If you intend to move billing fully to concorbit for one of these customers, run the Cutover flip first to flip the AT side, then deal with the QB-side mirror as a separate decision.
Payment ledger writes
The QB payment sync uses PaymentLedgerService::upsert (not record), because QB allows edits to a payment line's amount or date after the first pull. The upsert:
Inserts a new ledger row on first sight, matched by
(payment_source='quickbooks', external_reference=<QB payment id>).On a later pull, updates the existing row's
amount,paid_at, orstatusif QB has changed them, and writes an explicitpayment_ledger.upsertaudit log row with the field delta.
The invoice's amount_paid recomputes from the ledger after every upsert, so the concorbit row stays in lock-step with QB's view of how much the customer has paid.
£0 invoices on QB
The £0 paid lifecycle (auto-promote to paid on save) is a concorbit-governed feature. On a governance=quickbooks invoice it does not fire, the status comes from QB's flags directly. If QB marks a £0 invoice paid, the concorbit row reflects that on the next pull.
When to use what
| Situation | What to do |
|---|---|
| Customer is fully on QB, you mirror for reporting | Leave them governance=quickbooks. Read-only in concorbit. |
| Customer is being migrated to concorbit-native billing | Do not bother with QB governance flips. Run Cutover when ready. |
| Customer is both AT-linked and QB-linked | AT wins. Plan the cutover via the AT path. QB stays read-only. |
| A QB invoice's data looks wrong in concorbit | Fix it in QB and re-pull. Never edit the concorbit row directly. |
Card-fee income item
If you charge a card surcharge, the fee collected on an externally-governed invoice is booked back to QuickBooks as a one-line sales receipt. That receipt needs to know which income item to book against, so you map one on the QuickBooks connection page (Settings, Integrations, QuickBooks, the "Card processing fee income item" picker).
The picker lists your synced QuickBooks items, narrowed to service and non-inventory types (a fee is income, not stock). If the list is empty, run a sync first to pull your items in.
Choose the item whose income account is where you track card fees. Its income account is where the surcharge revenue lands.
The page shows a warning while the surcharge is enabled but no item is mapped, because collected fees are recorded in concorbit but cannot be booked in QuickBooks until you set it.
Clearing the selection is always allowed, even if the previously mapped item has since been deactivated in QuickBooks.
This setting only affects the surcharge booking. The base payment is pushed against the QuickBooks invoice regardless.
Disconnect
Disconnecting QuickBooks deactivates the sync. Existing mirrored rows stay in concorbit, still marked governance=quickbooks, frozen at their last sync state. Reconnecting later resumes the mirror; rows that were edited in QB during the gap re-pull cleanly.
The concorbit UI does not flip a frozen QB-governed invoice's status to concorbit automatically. If you want to take ownership of an old QB-mirrored invoice (very rare), do it via an operator-side governance flip, never via the regular UI.