ml-connector
VismaZuora

Visma and Zuora integration

Zuora runs subscription billing and revenue recognition. Visma.net runs accounting and general ledger. Connecting the two keeps your revenue records and your ledger synchronized. Customer invoices and payment receipts flow from Zuora into Visma.net's general ledger so month-end close starts with billing reconciled and revenue accounts posted. ml-connector handles the different OAuth flows, the multi-region Zuora endpoint, and maps billing entities to your Visma.net chart of accounts.

How Visma works

Zuora is a subscription billing platform that exposes customer accounts, subscriptions, invoices, payments, refunds, credit memos, and products through a REST API that requires OAuth 2.0 client credentials. The tenant base URL differs by region (rest.zuora.com, rest.eu.zuora.com, etc), so the endpoint must be captured per customer. Zuora pushes billing events via webhook callouts when subscriptions are renewed, invoices posted, or payments received. The webhook payload is minimal and requires a callback to fetch the full record. Payment webhooks fire only for electronic payments, not external or manual entries. Webhook retries are configurable, and Zuora enforces a 25-second callout timeout.

How Zuora works

Visma.net ERP is a cloud-based accounting system covering financial management, AP, AR, purchasing, inventory, and project accounting. It exposes supplier and customer entities, invoices, payments, accounts, dimensions, and journal transactions via REST over OAuth 2.0. The OAuth token is obtained via Visma Connect using client credentials and a tenant_id. All API calls require an ipp-company-id header. Visma offers one-time webhook delivery plus delta polling via lastModifiedDateTime on list endpoints. Webhook enablement is required at the company level. ETag-based optimistic locking is required for PUT operations on financial records.

What moves between them

The main flow is Zuora into Visma.net. When a customer subscription is created or amended in Zuora, ml-connector syncs the account and subscription to Visma as a customer and related dimension record. When Zuora generates an invoice, it flows into Visma as a customer invoice, mapped to the correct revenue account and customer dimension. Payment receipts from Zuora post into Visma as customer payments, reducing the outstanding receivable. Refunds and credit memos in Zuora create offsetting entries in Visma. All records are read from Zuora on a daily or weekly schedule tied to your billing cycle, not in real time, to batch processing and reduce API calls.

How ml-connector handles it

ml-connector stores both OAuth credential sets encrypted and manages token refresh independently for each system, since token lifetimes and grant flows differ. On the Zuora side, it discovers and respects the customer-specific base URL at runtime (e.g., rest.eu.zuora.com for EU tenants) and only processes electronic payment notifications, skipping manual payments. It fetches the full record payload for each webhook event since Zuora callouts send only the object ID. On the Visma side, it obtains tokens via Visma Connect, includes the ipp-company-id header on all calls, and uses ETag-based optimistic locking for any financial record updates. Customer accounts and subscriptions in Zuora are mapped to Visma customer and dimension records so revenue accounts land on the correct dimension. Invoice amounts are split by revenue stream if needed and posted to the correct GL accounts. Rate limit backoff is applied on both sides, and every record carries a full audit trail so failed posts can be retried without duplication.

A real-world example

A SaaS company with annual and monthly subscription tiers runs Zuora for billing and Visma.net for accounting across operations in Scandinavia. Before the integration, the accounting team manually exported subscription reports from Zuora at month-end and re-entered each customer invoice and payment into Visma by hand, which was error-prone and delayed closing. With Zuora and Visma.net connected, each subscription change and invoice flows into Visma automatically, posted to the correct customer and revenue account. Month-end close now starts with customer invoices and AR fully synchronized, and the manual re-entry step is eliminated.

What you can do

  • Sync Zuora subscription events and customer data into Visma.net as customer records and dimension entries.
  • Post Zuora invoices into Visma.net's general ledger, mapped to the correct revenue accounts and customer dimensions.
  • Record Zuora payments and refunds as customer receipts and credit memos in Visma.net.
  • Discover and adapt to multi-region Zuora endpoints and refresh OAuth tokens on each system independently.
  • Poll on a schedule tied to your billing cycle, with retries, optimistic locking, and full audit trails on every record.

Questions

Does the integration handle Zuora's multi-region endpoints?
Yes. ml-connector captures the customer-specific Zuora base URL (rest.zuora.com, rest.eu.zuora.com, rest.ap.zuora.com, etc) and uses it to route all API calls. This ensures that EU tenants call the EU endpoint and data residency is respected.
What happens when Zuora sends a webhook notification?
Zuora callout webhooks contain only the object ID, not the full record. ml-connector receives the notification, validates its HMAC signature, then calls back to Zuora to fetch the complete invoice or payment details before posting to Visma. This ensures full data fidelity and handles Zuora's 25-second callout timeout.
How does ml-connector handle the two different OAuth flows?
Zuora and Visma.net both use OAuth 2.0 client credentials, but tokens expire on different schedules and must be refreshed independently. ml-connector manages each credential set separately, caches tokens until expiry, and refreshes on demand, so a token timeout in one system does not block the other.

Related integrations

Connect Visma and Zuora

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

Get started