All insights

Engineering

Two-way QuickBooks sync without drift: how FleetForge keeps the books aligned

Most accounting integrations quietly fall out of step. Here's the architecture that keeps FleetForge and QuickBooks Online telling the same story.

Avi Technologies · · 5 min read

Almost every business system claims to “integrate with QuickBooks”. In practice that often means a nightly export, a CSV someone uploads on Fridays, or a one-way push that works until the day it doesn’t. Then month-end arrives, the numbers in the two systems disagree, and someone spends a day finding out why.

That gap has a name: drift. When we built the QuickBooks Online integration for FleetForge, avoiding drift was the design goal. Here’s how it works.

Decide who owns the truth

The root cause of most drift is that both systems think they’re in charge. Someone edits an invoice in QuickBooks, someone else edits it in the operations system, and now there are two versions with no rule for which one wins.

FleetForge settles it up front: FleetForge is the source of truth; QuickBooks is a mirror. Leases, invoices, credit notes, payments, bills and journal entries are created in FleetForge, where the operational detail lives (the unit, the lease, the mileage reading), and pushed to QuickBooks.

There are exactly three documented exceptions, each for a good reason:

ExceptionDirectionWhy
Online paymentsQuickBooks → FleetForge (webhook)Customers pay on QuickBooks’ secure payment page, so the money lands there first
Bank transactionsQuickBooks → FleetForge (daily pull, read-only)The bank feed lives in QuickBooks; FleetForge mirrors it for reference
Reference dataOne-time mapping at set-upAccounts, tax codes and items are matched once, then kept

Everything else flows one way. With a single owner per record, the “which version is right?” question disappears for nearly every case.

One owner per record. Most sync problems are really ownership problems.

Push after commit, never before

A subtle source of drift is timing. Suppose the system sends an invoice to QuickBooks, then a later validation step fails and the local save is rolled back. QuickBooks now holds an invoice FleetForge doesn’t.

FleetForge never pushes until its own database transaction has committed. If the local save fails, nothing is queued. If the QuickBooks push fails afterwards, FleetForge is still internally consistent, the mirror is just behind, and the retry and drift systems catch it up.

Make every push safe to repeat

Networks fail at awkward moments. A request can reach QuickBooks and create an invoice, then lose the response on the way back. Retry naively and you have a duplicate.

FleetForge makes every push idempotent, so running it twice has the same effect as running it once:

  • Mapping tables record which QuickBooks record each FleetForge record corresponds to. Before pushing, the worker checks the map. No mapping means a create; an existing mapping means an update to that exact record.
  • Request IDs: every create carries a deterministic request ID, so if a response is lost and the push is re-sent, QuickBooks recognises it and replays the original result instead of creating a second copy.
  • SyncTokens: QuickBooks versions every record. If someone edited a record directly in QuickBooks, an update arrives with a stale token. FleetForge re-reads the current version, retries once, and if that still fails, flags it for a human rather than overwriting their change.

Queue what can wait, sync what can’t

Not every push needs to happen while someone’s watching. FleetForge uses two modes:

  • Immediate: for actions where a person expects confirmation, such as sending an invoice, recording a manual payment or voiding something.
  • Queued: for background work like monthly invoice runs, depreciation and recurring journal entries. These go into a sync queue and a worker processes them shortly after.

The queue isn’t a black box. Operators can see it, retry items, and inspect what was sent and what came back. Errors are sorted by type, because they need different handling:

  1. Expired authentication: refresh the token and retry automatically.
  2. Stale record: re-read the latest version and retry once.
  3. Rate limiting or a temporary outage: back off and try again later.
  4. Validation errors: don’t retry; tell a person what’s wrong.

QuickBooks connections also expire if they sit unused, so a scheduled job refreshes the connection well before the deadline and raises a critical alert if that refresh ever fails.

Payments come back on their own

When a customer pays an invoice online, QuickBooks sends FleetForge a webhook. FleetForge verifies the signature, finds the matching invoice through the mapping table, records the payment, posts the journal entry (cash in, receivable down) and clears the invoice. The handler is idempotent too, so a redelivered webhook can’t record the same payment twice.

Nobody re-keys anything. The invoice simply shows as paid.

Then check anyway: drift detection

Even with all of that, things can diverge: a manual edit in QuickBooks, a record created there by habit, a bug nobody’s found yet. So FleetForge doesn’t assume alignment; it measures it.

Every night, a drift check compares the two systems across invoices, payments, bills, bill payments, credit memos, journal entries, customers and vendors, looking for:

  • records in FleetForge that never reached QuickBooks,
  • records in QuickBooks that FleetForge doesn’t know about,
  • amounts that differ beyond a set tolerance.

The tolerances are deliberately tight:

RecordAllowed difference
Invoices$0.05 (tax rounding)
Payments$0.01
Customers and vendorsNone

Anything outside tolerance appears on a drift dashboard, and an operator can resync it, accept it with a reason, or suppress it. There’s also a side-by-side compare screen showing the FleetForge and QuickBooks versions of a record together. When a drift clears on a later run, it resolves itself.

Why not just keep everything in QuickBooks?

QuickBooks is excellent at accounting. It doesn’t know which trailer was on which lease, what the odometer read on the 1st, or why March’s invoice included a mileage credit. Keeping the operational system as the source of truth means every number in the books links back to the real-world event behind it. That’s a far stronger position at audit time, and accountants can keep working in the tool they know.

What this means for you

If your operations software and your accounting software disagree every month, the fix isn’t more reconciliation. It’s an integration built around ownership, safe retries and continuous checking. That’s how we build them, whether it’s QuickBooks or another system you depend on.

Want your systems to agree with each other for once? Let’s talk.

Related work Mainland Truck & Trailer · Northland Equipment The operating system for a truck, trailer and equipment leasing business.

Have something your business needs built?

Tell us about the process, the spreadsheet or the website that’s holding you back. We’ll come back with a plan, a timeline and a price.