An OAuth start route that mints a CSRF state row, a callback that validates it, exchanges the code, stores encrypted tokens plus the company id, and captures the company name. Sandbox and production differ only in which credentials and API host are used — the same code serves both, with the API minor version pinned deliberately.
Also called: connect QuickBooks · QBO · accounting integration · realm id
- 1Start creates a state row recording the account, user, return path and environment.
- 2The user approves at Intuit and is redirected back with a code, the state and a company id.
- 3The state is validated for existence and expiry, then consumed.
- 4Tokens are exchanged and stored encrypted on the account row with the company id.
- 5Company info is fetched to capture the company name (best-effort), and the user is returned to where they started with a success or error flag.
The module documents the environment design: 'Sandbox/production switched by QB_ENVIRONMENT env var. Same code, different hosts + different Client ID/Secret per env. No code change between sandbox and production deploys.' The version pin has its own reason: 'Without this, Intuit silently picks the oldest published version and may break behavior on the next release.' The optional Projects scope is gated because 'Intuit returns invalid_scope and blocks the ENTIRE connect if the Intuit app doesn't have the Projects API enabled.'
- Invoices had to be re-entered into accounting by hand.
- An unpinned API version could break silently on a vendor release.
- Requesting an unavailable scope blocked the entire connection.
See it on your own jobs
Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.
or keep browsing features →