Ledgerline Payments

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