ml-connector
Microsoft Dynamics 365 F&OZoho CRM

Microsoft Dynamics 365 F&O and Zoho CRM integration

Microsoft Dynamics 365 F&O runs finance, supply chain, and order processing as the system of record. Zoho CRM runs the sales pipeline and produces customer-facing sales orders, quotes, and invoices. Connecting the two means the customer, product, and vendor masters in Dynamics stay reflected in Zoho CRM, and the orders and invoices sales reps create in Zoho CRM flow back into Dynamics without re-keying. ml-connector handles the different APIs on each side and moves the data on a schedule you control. The general ledger stays in Dynamics, where it belongs, since Zoho CRM has no chart-of-accounts resource.

How Microsoft Dynamics 365 F&O works

Microsoft Dynamics 365 F&O exposes customers, vendors, products, purchase orders, vendor invoices, GL main accounts, and financial dimensions through its OData v4 REST service at a tenant-specific host such as contoso.operations.dynamics.com/data. It authenticates with OAuth 2.0 client credentials issued by Microsoft Entra ID, using a scope tied to the environment host, and Bearer tokens expire about every hour. OData queries return only the default legal entity unless cross-company is requested, and entity keys must be fully specified. Dynamics pushes outbound Business Events for actions such as invoice posted or PO confirmed, but those payloads carry identifiers only and need a follow-up OData read for full detail.

How Zoho CRM works

Zoho CRM exposes Accounts, Contacts, Products, Vendors, Sales Orders, Quotes, Purchase Orders, and Invoices through its REST v8 API over JSON and HTTPS. Authentication uses OAuth 2.0 with a long-lived refresh token exchanged for hourly access tokens, and the correct base URL comes from the api_domain in the token response, since a customer org can live on any of seven datacenters. Line items are nested subforms inside each record, not separate endpoints. Zoho CRM can push create, edit, and delete notifications to a registered watch endpoint, but those channels expire in about a day and must be renewed, and notifications deliver record IDs only. The financial modules require a Professional plan or above.

What moves between them

Master data flows from Microsoft Dynamics 365 F&O into Zoho CRM. ml-connector reads Dynamics customers, products, and vendors and writes them into Zoho CRM as Accounts, Products, and Vendors, so reps build quotes and orders against records that already exist in the ERP. Sales documents flow the other direction: Zoho CRM sales orders and posted invoices are read back into Dynamics as sales orders and customer receivables, mapped to the matching customer account and item numbers. Reference data such as customer accounts and product numbers is aligned first so every order line resolves to a real Dynamics record. GL postings and the chart of accounts stay in Dynamics, since Zoho CRM has no GL resource, so ml-connector never writes ledger entries into the CRM.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the Dynamics side it requests an Entra ID client-credentials token scoped to the environment host and refreshes it when a call returns 401, accepts the tenant-specific OData host per customer, and adds cross-company plus a dataAreaId filter so the right legal entity is read. On the Zoho side it exchanges the refresh token for an access token, caches it until just before its hourly expiry, and always uses the api_domain from the token response as the base URL rather than a hardcoded datacenter. Customers and products are mapped first so every Zoho sales order line references a Dynamics item and customer that already exist. Neither system offers an idempotency key, so ml-connector dedupes on natural keys, the Dynamics InvoiceNumber and customer account on one side and the Zoho record id with an upsert duplicate-check field on the other, before each write, which avoids double-booking a re-read record. Where Zoho watch channels are enabled it consumes create and edit notifications, verifies the echoed token, fetches the full record by ID since the payload carries only IDs, and renews the channel before its roughly one-day expiry; otherwise it polls with a COQL query filtered on Modified_Time. Dynamics rate limits return HTTP 429 with a Retry-After header and Zoho enforces a daily credit quota, so ml-connector backs off and retries on both. Every record carries a full audit trail and can be replayed if a downstream call fails.

A real-world example

A mid-sized industrial equipment distributor with around 250 employees runs Microsoft Dynamics 365 F&O for finance, inventory, and order fulfillment, and runs Zoho CRM for its sales team to manage the pipeline and write quotes and orders. Before the integration, a sales coordinator looked up stock and pricing in Dynamics, typed quotes into Zoho CRM by hand, and then re-keyed every won order back into Dynamics, which left product and customer lists drifting apart and meant orders sat for hours before they reached fulfillment. With Microsoft Dynamics 365 F&O and Zoho CRM connected, the customer, product, and vendor masters stay reflected in Zoho CRM, and each sales order and invoice the team creates flows into Dynamics within the polling window, allocated to the correct customer and item. The re-keying step is gone, the catalogs agree, and orders reach fulfillment the same day.

What you can do

  • Push Microsoft Dynamics 365 F&O customers, products, and vendors into Zoho CRM as Accounts, Products, and Vendors.
  • Read Zoho CRM sales orders and invoices back into Dynamics as sales orders and customer receivables.
  • Map Zoho CRM line items to Dynamics item numbers and customer accounts so every order line lands on a real record.
  • Bridge the Entra ID client-credentials token and the Zoho datacenter refresh token, using the api_domain from each token response.
  • Follow Zoho webhooks with a callback fetch and natural-key dedup, with retries and a full audit trail on every record.

Questions

Which direction does data move between Microsoft Dynamics 365 F&O and Zoho CRM?
Both directions, by record type. Customers, products, and vendors move from Dynamics into Zoho CRM as Accounts, Products, and Vendors, while sales orders and invoices move from Zoho CRM back into Dynamics as orders and customer receivables. Zoho CRM has no GL chart-of-accounts resource, so the general ledger stays in Dynamics and ml-connector never writes ledger entries into the CRM.
How does the integration handle Zoho CRM's datacenter routing and token refresh?
Zoho orgs can live on any of seven datacenters, so ml-connector never hardcodes a base URL. It exchanges the stored refresh token for an hourly access token, reads the api_domain field from the token response, and uses that domain for every call to the customer's org. The access token is cached and refreshed shortly before it expires so requests never go out with a stale token.
Does Zoho CRM push records, or does ml-connector poll for them?
Both are supported. Where Zoho watch channels are enabled, ml-connector receives create and edit notifications, verifies the echoed token, and fetches the full record by ID because the notification carries only IDs, and it renews each channel before its roughly one-day expiry. Otherwise it polls with a COQL query filtered on Modified_Time, which avoids paging the whole module and burning the daily credit quota.

Related integrations

Connect Microsoft Dynamics 365 F&O and Zoho CRM

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

Get started