ml-connector
Microsoft Dynamics 365 Business CentralSalesforce

Microsoft Dynamics 365 Business Central and Salesforce integration

Microsoft Dynamics 365 Business Central runs finance, sales, and inventory. Salesforce runs the sales pipeline and customer relationships. Connecting the two keeps the customer master and product catalog in agreement and gives sales reps the billing picture without leaving the CRM. When a deal closes in Salesforce, the account and order details flow into Business Central, and as Business Central invoices and records payment against them, that status flows back onto the Salesforce record. ml-connector handles the different auth on each side and moves the data on the cadence you choose.

How Microsoft Dynamics 365 Business Central works

Microsoft Dynamics 365 Business Central exposes customers, items, sales orders, sales invoices, GL accounts, and dimensions through the Business Central API v2.0, a REST surface built on OData v4. Resources nest under a company id on a tenant environment URL, and the connector authenticates with the OAuth2 client credentials grant through Microsoft Entra ID using a registered app with the API.ReadWrite.All application permission. Sales invoices are created as drafts and posted with the Microsoft.NAV.post bound action, while the chart of accounts and general ledger entries are read-only over the API. Business Central can push change notifications by subscription, but those notifications carry no payload, expire every three days, and must be renewed by the connector, so the changed record is fetched after each notification.

How Salesforce works

Salesforce exposes Accounts, Contacts, Opportunities, Orders, OrderItems, and Product2 records through its REST API, with SObject CRUD under a versioned services data path and SOQL for filtered reads. The connector authenticates with the OAuth2 client credentials flow against the org My Domain URL, then uses the instance_url returned in the token response for every call, since tokens carry no refresh token and expire on the org session timeout. Writes can be made idempotent by upserting against an External Id field rather than the Salesforce Id. Salesforce publishes Change Data Capture events for Accounts, Contacts, Opportunities, and Orders over the Pub/Sub API, retained for 72 hours with replay by replayId. The standard Invoice and Payment objects exist only in orgs with Revenue Cloud.

What moves between them

Data moves in both directions. From Salesforce into Microsoft Dynamics 365 Business Central, ml-connector reads Accounts, Contacts, and closed Orders and upserts them as Business Central customers and sales orders, so a won deal becomes a real order without re-keying. The item catalog is aligned so each Salesforce Product2 maps to a Business Central item and every order line resolves to a valid item number. From Business Central back into Salesforce, the connector writes order, sales invoice, and payment status onto the matching Salesforce Order and Account so reps see whether an order is invoiced, open, or paid. Because the Business Central chart of accounts and general ledger entries are read-only over the API and basic Salesforce orgs have no Payment object, financial postings stay in Business Central rather than being mirrored into the CRM.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the Salesforce side it requests an OAuth2 client credentials token from the org My Domain URL and then calls the instance_url from the token response, refreshing the token when the session expires, since the client credentials flow issues no refresh token. On the Business Central side it holds a Microsoft Entra ID client credentials token for the tenant and targets the company id on the configured environment name, since the environment is part of the URL. New and changed Salesforce records arrive over Change Data Capture on the Pub/Sub API and are tracked by replayId, with a SOQL poll on the updated endpoint as a fallback if the connector is offline past the 72-hour event retention. Writes into Salesforce use upsert against an External Id field, so the Business Central record id matches an existing Account or Order instead of creating a duplicate, and writes into Business Central dedupe on the customer number and a BullMQ jobId for the same reason. Sales invoices in Business Central are posted with the Microsoft.NAV.post bound action before their status is read back to Salesforce. Items and accounts are mapped first so every order line references an item and a customer that already exist. The three-day Business Central subscriptions are renewed before they expire so the change feed never goes dark, and 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 of about two hundred staff runs Microsoft Dynamics 365 Business Central for finance, inventory, and order fulfillment, and runs Salesforce as the system of record for its sales team. Before the integration, a sales coordinator rekeyed every won opportunity into Business Central as an order, and reps had no view of whether an order had shipped, been invoiced, or been paid, so they called accounting to check before chasing a renewal. With Business Central and Salesforce connected, a closed Salesforce Order flows into Business Central as a sales order against the right customer and items, and the invoice and payment status flows back onto the Salesforce record. The double entry is gone and reps see live billing state on the account they are working.

What you can do

  • Upsert Salesforce Accounts and Contacts into Business Central customers, and closed Orders into Business Central sales orders.
  • Align the Salesforce Product2 catalog with Business Central items so every order line resolves to a valid item number.
  • Write Business Central order, sales invoice, and payment status back onto the matching Salesforce Order and Account.
  • Authenticate Salesforce with OAuth2 client credentials and Business Central with a Microsoft Entra ID client credentials token.
  • Listen to Salesforce Change Data Capture with a SOQL fallback, dedupe writes by external id, and keep a full audit trail on every record.

Questions

Which direction does data move between Microsoft Dynamics 365 Business Central and Salesforce?
It moves both ways. Salesforce Accounts, Contacts, and closed Orders flow into Business Central as customers and sales orders, while order, invoice, and payment status flows from Business Central back onto the Salesforce records. The item catalog is aligned so every order line resolves to a valid Business Central item, and financial postings stay in Business Central since the GL is read-only over the API and basic Salesforce orgs have no Payment object.
How does the integration avoid creating duplicate records in Salesforce?
Writes into Salesforce use upsert against an External Id field rather than the Salesforce Id, so the Business Central record id matches an existing Account or Order instead of creating a new one. The External Id field must be declared on the object in Salesforce Setup. Writes into Business Central dedupe on the customer number and a BullMQ jobId for the same reason.
Does Salesforce push changes, or does ml-connector poll for them?
Salesforce pushes changes through Change Data Capture over the Pub/Sub API, and ml-connector subscribes to the Account, Contact, Opportunity, and Order channels and tracks position by replayId. Because those events are retained for only 72 hours, a SOQL poll on the updated endpoint serves as a fallback if the connector is offline longer than that. On the Business Central side, change subscriptions expire every three days and are renewed by the connector before they lapse.

Related integrations

Connect Microsoft Dynamics 365 Business Central and Salesforce

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

Get started