ml-connector
QuickBooks OnlineZoho CRM

QuickBooks Online and Zoho CRM integration

QuickBooks Online handles accounting, invoicing, and vendor management for SMBs. Zoho CRM manages the sales pipeline and customer relationships. When you connect the two, customer and vendor records flow from your accounting system into your CRM automatically, so your sales team always works from current accounting data. New customers entered in QuickBooks Online appear in Zoho CRM for deal tracking, and vendor records sync for procurement visibility. ml-connector handles the OAuth 2.0 refresh on both sides and manages Zoho's time-limited webhook channels so your integration stays live without manual intervention.

How QuickBooks Online works

QuickBooks Online exposes customers, vendors, employees, invoices, bills, accounts, departments, and journal entries through the QuickBooks Online Accounting API v3 with a REST + SQL-like query language. Authentication is OAuth 2.0 Authorization Code flow with realm_id captured from the OAuth callback, and access tokens expire in 1 hour while refresh tokens rotate every 24-26 hours. The system supports webhooks for Create/Update/Delete/Merge/Void events on entities like Customer, Vendor, Invoice, Bill, Account, and JournalEntry, though webhook payloads contain only entity ID and name so the full record must be fetched via GET. A CDC endpoint is also available at /v3/company/{realmId}/cdc with 30-day history for polling. All updates require exact object representation with SyncToken for concurrency control, and Vendor, Customer, or Account entities cannot be hard-deleted, only marked inactive.

How Zoho CRM works

Zoho CRM manages accounts, contacts, vendors, invoices, purchase orders, sales orders, and products through a region-specific REST API at https://www.zohoapis.{region}/crm/v8. Authentication uses OAuth 2.0 with Authorization Code flow or Client Credentials, and the token response includes an api_domain field that must be used as the base URL for subsequent requests. The system supports webhooks through channels that are created with a channel_id and token for verification, but channels expire approximately every 24 hours and must be renewed via PATCH before they lapse. Webhook notifications contain only record IDs, so full payloads are fetched via GET requests. Access tokens are valid for 1 hour and require refresh. Invoices, Purchase Orders, Sales Orders, Quotes, Vendors, and Products are available only in Professional edition and above.

What moves between them

Customer records flow from QuickBooks Online into Zoho CRM via webhook or polling, synced at creation and update. Vendor records move the same direction so procurement visibility aligns with accounting. QuickBooks Online customer names, email, and billing address map to Zoho Account name, email, and address fields. Vendor records map to Zoho Vendor module where available in the customer's edition. The sync is unidirectional: QuickBooks Online is the system of truth for customer and vendor master data.

How ml-connector handles it

ml-connector stores OAuth credentials encrypted and refreshes access tokens automatically when either system returns 401. On the QuickBooks Online side, it accepts the realm_id from the customer's OAuth callback and subscribes to webhooks for Customer, Vendor, Invoice, and Bill entities. When a webhook fires, ml-connector fetches the full record with its current SyncToken to avoid concurrency conflicts. On the Zoho CRM side, ml-connector creates a webhook channel and monitors its expiry, renewing it via PATCH before the ~24-hour window closes. Because Zoho webhook notifications contain only record IDs, ml-connector fetches full payloads from Zoho via GET. QuickBooks Online's 1-hour access token requires refresh before every call after the first; Zoho's refresh token is stored encrypted and refreshed when the access token expires. ml-connector also checks the region-specific api_domain from Zoho's token response and uses it as the base URL for all subsequent requests. The integration backs off on rate limits returned by either system and retries with exponential jitter.

A real-world example

A mid-market B2B services firm runs QuickBooks Online for accounting and invoicing, and uses Zoho CRM for opportunity tracking and customer management. Before the integration, every new customer entered in QuickBooks Online was manually re-created in Zoho CRM, and the CRM would drift out of sync when customer addresses or phone numbers were updated in accounting. Sales reps lost visibility into which customers had outstanding bills or were on credit hold, because they had to check QuickBooks Online separately. With QuickBooks Online and Zoho CRM connected, new customers flow into the CRM automatically on creation, updates sync within minutes of a webhook firing, and the sales team always sees current customer data without manual re-entry.

What you can do

  • Sync customer records from QuickBooks Online to Zoho CRM with automatic field mapping for names, email, and addresses.
  • Keep vendor master data current in Zoho CRM as changes in QuickBooks Online flow through webhooks.
  • Manage OAuth 2.0 token refresh on both systems, handling expiry and rotation automatically.
  • Renew Zoho webhook channels before they expire so the integration stays live without manual intervention.
  • Back off and retry when either system returns rate limits, with full audit trails on every sync.

Questions

Which direction does data flow between QuickBooks Online and Zoho CRM?
Customer and vendor records flow from QuickBooks Online into Zoho CRM. QuickBooks Online is the system of truth for customer and vendor master data. The sync is unidirectional because Zoho CRM is primarily a sales and relationship tool rather than an accounting source.
How does ml-connector handle OAuth 2.0 refresh on both systems?
ml-connector stores OAuth credentials encrypted and refreshes the QuickBooks Online access token before every call after the first, because tokens expire in 1 hour. On the Zoho CRM side, it refreshes the access token when it expires and uses the api_domain from the token response as the base URL for subsequent requests. Both refresh tokens are stored encrypted and rotated automatically.
How does Zoho webhook channel expiry work and how does ml-connector handle it?
Zoho webhook channels expire approximately every 24 hours and must be renewed via PATCH before they lapse, or notifications stop arriving. ml-connector monitors channel expiry, renews channels proactively before the window closes, and checks the renewal response to confirm the new expiry window. If channel renewal fails, the integration logs the error and surfaces it via alerts so the customer can intervene.

Related integrations

Connect QuickBooks Online and Zoho CRM

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started