Developer notes
Technical reference for developers who customize QuickBooks Online Sync.
Add-on identity
Section titled “Add-on identity”| Item | Value |
|---|---|
| Add-on id | kv_quickbooks |
| Function prefix | fn_kv_quickbooks_ |
| Language variables | kv_quickbooks.* |
| CSS scope | .kv-quickbooks |
| PHP namespace | Tygh\Addons\KvQuickbooks |
| Preset | accounting (generated by kv new --kind integration) |
Structure
Section titled “Structure”| Class | Role |
|---|---|
Client\BaseClient |
HTTP (cURL, TLS verification, timeouts), JSON, Retry-After, error mapping, masked logging |
Client\Api |
OAuth 2.0 (authorization code, rolling refresh token under a database lock) and the Accounting API v3 calls |
Client |
Client per company, the connection test |
Sync |
Customer, item, invoice / sales receipt, payment, credit memo / refund receipt sync; line and tax building; the map table |
Accounts, Secret |
Credentials (test and live) sealed with AES-256-GCM; one account per store owner or per vendor |
Config, Access |
Settings, owner mode, who may see and manage what |
Queue, Jobs, JobException |
Job queue: back-off 5 min / 15 min / 1 h / 3 h / 12 h, per-job isolation, overlap lock; handlers in Jobs::handle(), recurring work in Jobs::schedule() |
Log |
Event log with masking, filters, CSV, retention |
Database tables
Section titled “Database tables”| Table | Purpose |
|---|---|
?:kv_quickbooks_accounts |
Credentials per company (secrets sealed), last connection check, token cache, realm id, mapping |
?:kv_quickbooks_log |
Log |
?:kv_quickbooks_jobs |
Queue |
?:kv_quickbooks_map |
What was sent to QuickBooks (QuickBooks ids, payload hash) |
Hooks used
Section titled “Hooks used”PHP hook change_order_status_post (queues the invoice, payment and refund jobs). Template hooks: only the License card in the add-on settings. Nothing is printed on the storefront, so full page cache and Varnish are unaffected.
Test the HTTP layer without QuickBooks
Section titled “Test the HTTP layer without QuickBooks”The base URL can be overridden for tests in config.local.php (development only):
$config['kv_quickbooks_base_url'] = 'http://127.0.0.1:11947';node tests/mock-server/server.js 11947 starts a local stand-in of the Intuit OAuth service and the Accounting API; node tests/e2e/e2e.mjs runs the end-to-end test (real orders, OAuth flow, refunds, sales receipt mode, non-US tax) against it; php tests/unit.php runs the unit tests. The mock proves the add-on against its own reading of the API, not against the real service.
Template overrides
Section titled “Template overrides”Admin templates live in design/backend/templates/addons/kv_quickbooks/. Do not edit them in a store; they are replaced on update.
- API sources: Intuit’s published OAuth client (github.com/intuit/oauth-jsclient: endpoints, Basic authentication,
realmId) and the data classes of Intuit’s official QuickBooks V3 PHP SDK (entity and field names). developer.intuit.com renders only in a browser app, so the rate limit (500 requests a minute per company), the access token lifetime (1 hour), the refresh token lifetime (100 days, rolling), theminorversionandrequestidparameters and the Fault codes (6240 duplicate name, 6140 duplicate document number, 5010 stale SyncToken) come from Intuit’s developer documentation as published at the time of writing: check them against developer.intuit.com before a release. - Entities:
Customer(found byPrimaryEmailAddrwith the query language; updates are sparse and need theSyncToken),Item(found by name; created asServicewith anIncomeAccountRef),Invoice+Payment(Line.LinkedTxn),SalesReceipt,CreditMemo(applied with a zero-totalPaymentthat links the invoice and the credit memo),RefundReceipt(DepositToAccountRefis the account the money leaves). - Tax: US companies (
CompanyInfo.Country) getTaxCodeRefTAX/NON per line andTxnTaxDetail.TotalTaxfrom the order; other countries get tax code ids andGlobalTaxCalculationTaxInclusive / TaxExcluded. - Refresh tokens roll.
Accounts::locked()serialises the refresh withGET_LOCK, and a second process re-reads the account after the lock, so cron and an admin click never use the same token twice. - Request ids (max 50 characters):
kv-inv-<order>-<hash>,kv-sr-<order>-<hash>,kv-pay-<order>,kv-cm-<order>,kv-rr-<order>,kv-al-<order>,kv-cu-<hash>-<id>,kv-item-<hash>. - Map table entities: customer, invoice (the invoice or sales receipt), payment, credit (credit memo or refund receipt), refund (the application or the refund), item.
- CS-Cart stores taxes either per line (
appliesP_) or per order (subtotal calculation); Sync::allocate()handles both.