Sage Intacct and Zuora integration
Sage Intacct runs your financial accounting and general ledger. Zuora runs your subscription billing. Connecting the two keeps your revenue accounting in sync with actual subscription invoices and payments. Journal entries from each Zuora invoice and payment flow into Sage Intacct's GL automatically, posted to the correct GL accounts and cost centers. You avoid manual invoice re-entry and month-end revenue reconciliation becomes a verification step instead of a data-gathering task.
What moves between them
The integration reads Zuora invoices and payments and posts the corresponding journal entries into Sage Intacct's general ledger. When Zuora creates an invoice, ml-connector extracts the revenue by subscription product line, maps each line to the corresponding GL account in Intacct, and posts the debit and credit entries to Intacct. Likewise, when Zuora records an electronic payment, ml-connector posts the cash entry to the corresponding GL accounts in Intacct. Reference data flows both directions: GL accounts and dimensions (cost centers, departments) are synced from Sage Intacct to Zuora so every invoice line posts to an account that exists. Zuora webhooks trigger reads of new invoices and payments; Sage Intacct is polled on a schedule since it does not support webhooks.
How ml-connector handles it
ml-connector maintains separate authentication sessions for each system. For Sage Intacct, it calls the getAPISession operation with the partner credentials and user credentials, caches the resulting sessionid, and reuses it until the 50-minute expiry; the session is automatically refreshed on the next request if it has lapsed. For Zuora, it calls the OAuth2 token endpoint with client credentials, caches the bearer token, and refreshes when the one-hour expiry approaches. All Intacct operations serialize through the XML gateway endpoint, so ml-connector batches Zuora invoice and payment records into groups and submits them in separate gateway calls; it parses each response for errormessage tags and retries with exponential backoff if the Intacct API returns a transient error. Zuora webhooks notify ml-connector when new invoices and electronic payments arrive; ml-connector calls back to Zuora to fetch the full invoice or payment record, maps each line item to the GL account and dimension in Sage Intacct, and then posts the journal entry. GL account and cost center lookups are validated before posting so mismatched accounts do not create errors. Because Sage Intacct accepts a uniqueid flag in the XML request for idempotent retries, ml-connector stamps each journal entry with a unique ID derived from the Zuora invoice or payment ID so duplicate posts are server-deduplicated if a write is retried. All records carry a full audit trail and can be replayed if a Zuora callback or Intacct post fails partway through.
A real-world example
A SaaS company with multiple product lines runs Zuora for subscription billing and Sage Intacct for financial accounting. Before the integration, the accounting team received Zuora invoice reports each day, manually categorized the revenue by product line and customer segment, and entered the journal entries into Sage Intacct by hand, a process that took several hours per day and was prone to miscoding and delays. With Zuora and Sage Intacct connected, each invoice posts to Intacct automatically the moment it is issued in Zuora, along with the correct GL account and cost center from the product catalog. Payments flow the same way. Revenue is always current in the GL, month-end close can happen earlier, and the manual re-keying step is eliminated.
What you can do
- Post Zuora invoices and payments as journal entries into Sage Intacct's general ledger, mapped to the correct GL accounts and cost centers.
- Sync GL accounts and dimensions from Sage Intacct to Zuora so every invoice line posts to a valid account.
- Manage session-based authentication for Sage Intacct with automatic token refresh and OAuth2 credentials for Zuora.
- Receive Zuora invoice and payment notifications via webhooks and poll Sage Intacct on a schedule since Intacct does not support webhooks.
- Provide idempotent journal entry posting with deduplication and a full audit trail for every record.
Questions
- Which direction does data move between Sage Intacct and Zuora?
- The main flow is Zuora into Sage Intacct. Invoices and payments from Zuora become journal entries in Intacct's general ledger. Reference data such as GL accounts and cost centers flows both directions so every Zuora invoice line posts to a valid Intacct account.
- Why does the integration poll Sage Intacct if Zuora supports webhooks?
- Zuora can push invoice and payment events via Callout Notifications, so ml-connector receives real-time notification when new invoices and electronic payments are posted. Sage Intacct does not support webhooks, so ml-connector polls Intacct on a schedule to read GL accounts and dimensions for validation and to confirm that posted journal entries have been recorded.
- How does ml-connector handle Sage Intacct's 50-minute session expiry and Zuora's multi-region base URLs?
- For Sage Intacct, ml-connector calls getAPISession once, caches the sessionid, and automatically refreshes it on the next API call if the 50-minute window has elapsed. For Zuora, ml-connector accepts the customer's multi-region base URL during setup and routes all REST calls through the correct regional endpoint. OAuth2 tokens are refreshed when they approach expiry so authentication never fails in the middle of a sync.
Related integrations
More Sage Intacct integrations
Other systems that connect to Zuora
Connect Sage Intacct and Zuora
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started