Odoo and Zuora integration
Odoo runs your core accounting, inventory, and operations. Zuora handles subscription billing and recurring revenue. Connecting them keeps your accounts receivable and revenue records aligned without re-keying. New Zuora invoices automatically post into Odoo's general ledger mapped to the correct revenue accounts and customer records, and subscription status changes flow back into Odoo so your product and customer hierarchies stay in sync. ml-connector bridges the different authentication models on each side and moves the data on a schedule you control.
What moves between them
The main flow is Zuora into Odoo. After each billing cycle, ml-connector reads Zuora invoices and posts them into Odoo's general ledger as account moves, mapped to the matching Odoo revenue accounts. Subscription events (new, amended, cancelled) are polled from Zuora and reflected in Odoo product and customer records so that billing changes are visible in operations and finance planning. Customer accounts and contact information flow from Zuora into Odoo's partner master so that AR reconciliation is cleaner and customer service teams see consistent data.
How ml-connector handles it
ml-connector stores both credential sets encrypted: Odoo's API key and username for XML-RPC or JSON-2, and Zuora's client_id and client_secret for OAuth2. It manages the OAuth2 token lifecycle, refreshing the Zuora bearer token before expiry and before each request batch. On the Odoo side it polls the account.move model with a write_date filter using a high-water-mark timestamp from the prior run, sorting by write_date to ensure consistent ordering. When reading from Zuora, it uses cursor-based pagination (page size 40) to enumerate invoices, subscriptions, and accounts, building a map of Zuora invoice IDs to Odoo account move references. Invoice line items from Zuora map to Odoo account move lines, with the revenue recognition account taken from the Zuora product's chart-of-accounts setting and allocated across payment terms if the invoice is on a subscription plan. Subscription cancellations and amendments are captured from Zuora's subscription object state and timestamped against the polling window so no changes are lost between runs. Rate limit handling on Zuora is built in: ml-connector monitors the rate limit response headers (50,000 requests per minute on production) and backs off if approaching the boundary. Every record carries a full audit trail with the source Zuora ID and Odoo record reference, enabling replay if a downstream call fails.
A real-world example
A mid-sized SaaS company runs Odoo for accounting, inventory, and customer management, and Zuora for subscription billing across three product tiers and two geographies. Before the integration, the finance team exported invoices from Zuora every billing cycle and manually entered revenue into Odoo by hand, mapping line items to the correct revenue account for each product tier and geography, then spent hours reconciling between the two systems when invoice counts did not match. With Odoo and Zuora connected, each month's invoice batch flows into Odoo automatically, allocated to the correct revenue account and cost center per subscription tier and region, and subscription amendments are reflected in Odoo the same day. Month-end close starts with AR and revenue accounts already reconciled, and the manual entry step is gone.
What you can do
- Post Zuora invoices into Odoo's general ledger as account moves, allocated to the correct revenue accounts based on subscription product and term.
- Keep Odoo customer records and contact information aligned with Zuora accounts and billing contacts.
- Reflect subscription amendments and cancellations from Zuora in Odoo's product and customer hierarchies.
- Authenticate Zuora with OAuth2 Client Credentials and manage token refresh, and Odoo with API key and username.
- Poll Zuora's invoice and subscription streams on a schedule tied to your billing cycle, with high-water-mark pagination and a full audit trail on every record.
Questions
- Which direction does data move between Odoo and Zuora?
- The main flow is Zuora into Odoo. Invoices, subscription events, and customer accounts flow from Zuora into Odoo's accounting records and customer master. Odoo's customer and product data can also flow into Zuora to keep the product catalog and customer hierarchies aligned, but invoices and revenue recognition remain read in the Zuora-to-Odoo direction.
- How does ml-connector handle Zuora's OAuth2 token and Odoo's API key authentication?
- ml-connector stores both credential sets encrypted at rest. For Zuora, it manages the OAuth2 Client Credentials grant, obtaining a bearer token and refreshing it before expiry and before each request batch. For Odoo, it pairs the API key with the username login and passes them to the authenticate() call in XML-RPC or as a Bearer token header in JSON-2. Each credential type is handled according to its platform's requirements, so neither system sees the other's credentials.
- How does the integration handle Zuora's webhook payloads if it polls Odoo instead of waiting for webhooks?
- ml-connector uses polling for both systems: it polls Zuora's REST API endpoints for invoices, subscriptions, and accounts on a schedule tied to your billing cycle, using cursor-based pagination and a high-water-mark timestamp to capture changes since the last run. Zuora's webhook events are optional; if webhooks are enabled on your Zuora tenant, they provide near-real-time notification of invoice postings and subscription changes, but polling ensures no invoice or amendment is missed if a webhook is delayed or lost.
Related integrations
More Odoo integrations
Other systems that connect to Zuora
Connect Odoo and Zuora
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started