ml-connector
Zoho BooksZuora

Zoho Books and Zuora integration

Zoho Books records your sales, purchases, and GL activity. Zuora manages recurring subscriptions and order-to-cash billing. Connecting the two ensures your invoice records flow from Zoho Books into Zuora's subscription and billing workflows without manual handoff. New invoices in Zoho Books become Zuora orders and subscription adjustments, mapped to the right customer accounts. Both systems stay aligned on what has been invoiced, what is outstanding, and what revenue has been recognized.

How Zoho Books works

Zoho Books is a cloud-based accounting platform for small and mid-sized businesses handling invoicing, bills, purchase orders, expenses, and multi-currency accounting. It exposes Contacts, Invoices, Bills, Purchase Orders, Chart of Accounts, Journals, and Items through a region-specific REST API. Every call requires OAuth2 Authorization Code flow tokens and an organization ID query parameter; access tokens expire after 1 hour and must be refreshed. Zoho Books supports outgoing webhooks so it can push invoice and bill events to your server, and also offers polling via list endpoints with offset-based pagination. Rate limits are 100 requests per minute with daily limits varying by plan; concurrent call limits range from 5 on Free plans to 10 on paid plans.

How Zuora works

Zuora is a subscription billing and revenue management platform for SaaS and recurring-revenue businesses. It handles product catalogs, subscriptions, invoicing, payments, and revenue recognition through REST APIs. Zuora authenticates with OAuth2 client credentials, with tokens expiring after 1 hour and reused across requests. Zuora exposes Accounts, Subscriptions, Invoices, Payments, Orders, and Products; each customer tenant has a unique base URL that must be captured during setup. Zuora supports Callout Notifications (webhooks) for billing events like Invoice Posted and Subscription Renewed, with HMAC-SHA256 signature verification and configurable retry behavior. Rate limits are 50,000 requests per minute in production, with cursor-based pagination and a 25-second webhook timeout.

What moves between them

Invoices flow from Zoho Books into Zuora. When a new invoice is created in Zoho Books, ml-connector reads it and creates or amends a Zuora order tied to the corresponding Zuora Account, mapped from the Zoho contact. Line items map to Zuora products and subscription amendments. This flow runs either on a schedule (e.g., hourly or daily) or triggered by Zoho Books webhooks when an invoice is created or updated. Credit memos and bill adjustments in Zoho Books can trigger Zuora credit memo or debit memo creation if the Zuora tenant has Invoice Settlement enabled. The connector reads Zuora invoices back to Zoho Books on a daily basis to keep GL accounts and receivables current.

How ml-connector handles it

ml-connector bridges two distinct OAuth2 grant types: Zoho Books uses Authorization Code flow with a user-delegated refresh token valid indefinitely (max 20 per user), while Zuora uses client credentials. The connector maintains separate credential sets for each customer's Zoho and Zuora tenants. On the Zoho side, it resolves the customer's region from the OAuth token response (api_domain field) and routes all calls to the correct regional base URL (US, EU, India, Australia, Japan, Canada, China, or Saudi Arabia); it also resolves the organization_id on first auth and caches it. Zoho access tokens expire after 1 hour and are proactively refreshed at 55 minutes to avoid mid-request failures. On the Zuora side, the connector captures the tenant-specific base URL during setup and uses client-credentials tokens valid for 1 hour, also proactively refreshed. Invoices map as follows: Zoho contact -> Zuora Account (via email match or manual mapping); Zoho invoice line items -> Zuora order line items; Zoho currency_id -> Zuora billing currency (currency must already exist in Zuora). Both systems rate-limit (Zoho: 100 req/min; Zuora: 50,000 req/min), and ml-connector respects concurrent call caps (5-10 for Zoho, 40 for Zuora). The connector can receive Zoho webhooks on invoice.created and invoice.updated if webhooks are enabled, avoiding daily polling overhead. Zuora webhooks are configured for order.created or subscription.amended events to sync billing state back to Zoho GL. All records carry a full audit trail and can be replayed if a mapping fails.

A real-world example

A mid-market SaaS company runs Zoho Books to manage vendor invoices, customer invoices, and GL accounting, and uses Zuora for subscription management and recurring billing. Before the integration, the finance team exported weekly invoices from Zoho Books and manually created orders and subscriptions in Zuora, then chased discrepancies between what Zuora billed and what Zoho recorded. With Zoho Books and Zuora connected, each new customer invoice flows into Zuora as an order, amendments trigger subscription updates, and Zuora's billing state syncs back to Zoho GL at day-end close. The manual invoice-to-order handoff is eliminated, and revenue is recognized consistently across both systems.

What you can do

  • Push new and amended invoices from Zoho Books into Zuora as orders and subscription changes, mapped to the correct Zuora accounts.
  • Map Zoho Books contacts to Zuora accounts by email or custom field, with fallback to manual mapping for name-based matches.
  • Bridge Zoho Books OAuth2 user-delegated tokens and Zuora OAuth2 client credentials, handling regional URL routing for Zoho and tenant-specific URLs for Zuora.
  • Receive Zoho Books invoice webhooks when enabled, avoiding daily polling and syncing invoices to Zuora in real time.
  • Sync Zuora billing and subscription state back to Zoho Books GL accounts and receivables with full audit trail and error replay on every record.

Questions

Why does Zoho Books need regional base URL routing and Zuora needs tenant-specific URLs?
Zoho Books operates across eight regions (US, EU, India, Australia, Japan, Canada, China, Saudi Arabia) and returns its api_domain field in the OAuth token response; ml-connector must route all API calls to the correct region or authentication fails. Zuora is multi-tenant and issues a unique base URL per customer (e.g., rest.zuora.com, rest.eu.zuora.com); the tenant URL must be captured during initial setup and used for all subsequent calls.
How does ml-connector handle the two different OAuth2 flows?
Zoho Books uses Authorization Code flow where the user grants access via Zoho login and the connector stores a refresh token that remains valid indefinitely (max 20 per user). Zuora uses client credentials (client_id and client_secret only). ml-connector maintains separate credential sets for each customer, refreshes Zoho tokens proactively at 55 minutes, and refreshes Zuora tokens on the same cadence since both have 1-hour expiry.
Can Zoho Books webhooks replace daily polling?
Yes. If your Zoho Books instance supports outgoing webhooks (configured via Settings > Automation > Webhooks), ml-connector can register endpoints for invoice.created and invoice.updated events. This eliminates daily polling overhead and syncs invoices to Zuora in near-real time. Webhook history is available via the Zoho Books API for audit and replay.

Related integrations

Connect Zoho Books and Zuora

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

Get started