Documentation
Integration overview
High-level architecture for the WooCommerce ↔ QuickBooks Online integration. For deployment-specific instructions, refer to the package shipped with your engagement.
1. Components
The integration ships as a single WordPress plugin that registers itself as a WooCommerce payment gateway. Inside, four subsystems coordinate the order lifecycle:
- • OAuth client — manages the QBO authorization flow, access token refresh, and token storage.
- • Invoice service — runs asynchronously via Action Scheduler when an order is placed.
- • Webhook receiver — handles inbound events from Intuit at
/wp-json/lumina-qbo/v1/webhook. - • Mapping table — persists the link between WooCommerce orders and QBO invoices for idempotent reconciliation.
2. OAuth flow
The integration uses Intuit's standard OAuth 2.0 authorization-code flow with PKCE-equivalent state validation:
# 1. Admin clicks "Connect to QuickBooks" GET https://appcenter.intuit.com/connect/oauth2 ?client_id=... &response_type=code &scope=com.intuit.quickbooks.accounting com.intuit.quickbooks.payment &redirect_uri=... &state=<random> # 2. Intuit redirects back with code + realm_id GET /oauth/callback?code=...&realmId=...&state=... # 3. Exchange code for tokens POST https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer grant_type=authorization_code code=... redirect_uri=...
Access tokens expire after 1 hour and are refreshed transparently before each API call. Refresh tokens rotate yearly.
3. Order lifecycle
Each customer order moves through three states, mapped onto WooCommerce's native order statuses:
| Trigger | WC Status | Action |
|---|---|---|
process_payment |
on-hold |
Schedule async invoice creation |
invoice_send |
on-hold |
Persist mapping, mark as sent |
webhook(Balance=0) |
completed |
Mark mapping as paid |
4. Webhook contract
Intuit signs each webhook payload with HMAC-SHA256 using the verifier token configured in your developer app. The integration validates the signature before processing:
// Pseudocode
expected = base64(hmac_sha256(verifier_token, raw_body))
if !timing_safe_eq(expected, request.intuit_signature):
return 401
Subscribed event types: Invoice, Payment. Each event triggers a fresh fetch of the entity to confirm balance state — we never trust the webhook payload's mutable fields directly.
5. Idempotency
Webhooks may be delivered more than once. To prevent duplicate state mutations, the handler acquires a transient lock keyed on invoice ID for the duration of processing, and checks the mapping table's status column before transitioning the WooCommerce order. Double-deliveries are silently no-op'd.
6. Error handling
Errors at any stage are persisted to the mapping table's last_error column and surfaced as WooCommerce order notes. The admin panel exposes a Resend QuickBooks invoice action for manual recovery.
Common failure modes:
- •
refresh_failed— refresh token revoked or expired (rotate via Connect button) - •
no_income_account— QBO chart of accounts has no Income type account - •
customer_create_failed— duplicate display name conflict (resolve in QBO)
Need deeper documentation?
Each engagement ships with a deployment guide tailored to the merchant's hosting environment, including SFTP paths, plugin activation steps, and a runbook for common operational tasks.
Request the deployment guide