ml-connector
Microsoft Dynamics 365 Business CentralSAP Concur

Microsoft Dynamics 365 Business Central and SAP Concur integration

Microsoft Dynamics 365 Business Central runs finance, purchasing, and the general ledger. SAP Concur runs travel, expense, and invoice capture and approval. Connecting the two means approved expense reports and invoice payment requests from Concur post into Business Central as purchase invoices and ledger entries without re-keying, allocated to the correct vendors, dimensions, and GL accounts. ml-connector reads Concur's Financial Integration v4 feed, posts each document into Business Central, and confirms the result back to Concur so spend is recognized once and only once. The Business Central vendor master flows the other way so every Concur document maps to a real vendor.

How Microsoft Dynamics 365 Business Central works

Microsoft Dynamics 365 Business Central exposes vendors, purchase invoices, GL accounts, dimensions, general ledger entries, and customer payment journals through its Business Central API v2.0, a REST surface built on OData v4 with JSON payloads. All resources nest under a company path on an environment-specific base URL, and authentication uses an Entra ID OAuth2 client credentials token scoped to the Business Central API. Purchase invoices are created as drafts and posted with the Microsoft.NAV.post bound action, while accounts and general ledger entries are read-only. Business Central supports push webhooks via a subscription API on vendors, purchase invoices, and accounts, but notifications carry no payload and subscriptions expire every three days, so the connector also reads with OData delta filters on lastModifiedDateTime.

How SAP Concur works

SAP Concur exposes approved invoice payment requests and expense reports for ERP posting through its Financial Integration Service v4, a REST and JSON API. The connector reads ready documents from the transactions feed by document type, then writes back through the acknowledgements, posting confirmations, and payment confirmations endpoints on the same service. Authentication uses company-level OAuth2 with a one-time auth token exchanged for a six-month refresh token, and every call uses the geolocation base URL returned at token exchange rather than a fixed host. Vendors are managed through the Invoice Vendor v3.0 endpoint. Concur also pushes status changes through its Event Subscription Service, which is signed and delivered over mutual TLS from a known certificate.

What moves between them

The main flow runs from SAP Concur into Microsoft Dynamics 365 Business Central. ml-connector reads approved invoice payment requests and expense reports from Concur's Financial Integration v4 transactions feed and posts them into Business Central as purchase invoices, mapped to the matching vendor, dimensions, and GL accounts, then drafts are posted with the Microsoft.NAV.post bound action. After each post, the Business Central document number is sent back to Concur as a posting confirmation, and a payment confirmation follows once the invoice is paid. The Business Central vendor master flows the other direction into Concur so every spend document resolves to a real vendor. GL accounts are read-only in Business Central and the chart of accounts stays the source of truth, so ml-connector never writes accounts back. The cadence is event-driven from Concur's subscription service where enabled, with a scheduled poll of the Financial Integration feed as the reliable backstop.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the Concur side it exchanges the one-time auth token for a refresh token, rotates the one-hour access token, and uses the geolocation base URL from the token response rather than a hardcoded host, since hardcoding US breaks EMEA and China customers. On the Business Central side it requests an Entra ID client credentials token and builds the company base URL from the stored environment name. Vendors are mapped first, so every Concur document posts against a Business Central vendor that already exists. Because a Concur document must be acknowledged before posting, the Financial Integration acknowledgement endpoint detects previously acknowledged documents and returns a previously acknowledged state, which protects against double processing on re-read; on the Business Central side ml-connector dedupes on the Concur document id with a colon-free BullMQ jobId and checks the purchase invoice number before posting, since Business Central has no idempotency-key header. Posting is two-step: a draft is created, then the Microsoft.NAV.post bound action posts it, after which the document number is returned to Concur as a posting confirmation. Concur status events arrive over mutual TLS signed with a Concur-Signature header, verified by the known webhook certificate, while the Financial Integration feed is paged with page and limit and used as a scheduled backstop. Concur returns HTTP 429 with no published global limit and Business Central throttles at 600 requests per minute, so ml-connector backs off with jitter, and it renews the three-day Business Central webhook subscription before expiry so a lapse does not silently stop change signals. Every record carries a full audit trail and can be replayed if a downstream call fails.

A real-world example

A mid-sized professional services firm with roughly 400 employees runs Microsoft Dynamics 365 Business Central for finance and the general ledger and uses SAP Concur to capture employee travel expenses and supplier invoices. Before the integration, the accounting team exported approved expense reports and invoices from Concur every few days and keyed each one into Business Central as a purchase invoice by hand, allocating cost centers and accounts manually, which left documents sitting for days, produced posting errors, and made month-end close a reconciliation chase between approved spend in Concur and the ledger. With Microsoft Dynamics 365 Business Central and SAP Concur connected, each approved document flows into Business Central within the polling window, posts against the correct vendor, dimensions, and GL accounts, and the Business Central document number is confirmed back to Concur. The manual keying step is gone and the expense and AP accounts reconcile against both systems.

What you can do

  • Post approved SAP Concur invoice payment requests and expense reports into Microsoft Dynamics 365 Business Central as purchase invoices.
  • Map Concur documents to Business Central vendors, dimensions, and GL accounts, then post drafts with the Microsoft.NAV.post action.
  • Send the Business Central document number back to Concur as a posting confirmation, and a payment confirmation once the invoice is paid.
  • Push the Business Central vendor master into Concur so every spend document resolves to a real vendor.
  • Bridge Concur company-level OAuth2 and the Entra ID token, with acknowledgement-based dedup, retries, and a full audit trail on every record.

Questions

Which direction does data move between Microsoft Dynamics 365 Business Central and SAP Concur?
The main flow is SAP Concur into Business Central. Approved invoice payment requests and expense reports move from Concur's Financial Integration v4 feed into Business Central as purchase invoices, and posting and payment confirmations flow back to Concur. The Business Central vendor master flows the other direction into Concur. GL accounts are read-only in Business Central, so ml-connector never writes the chart of accounts back.
How does the integration avoid posting the same Concur document twice?
Concur's Financial Integration acknowledgement endpoint detects documents that were already acknowledged and returns a previously acknowledged state, which guards the read side. On the Business Central side, ml-connector dedupes on the Concur document id with a stable BullMQ jobId and checks the purchase invoice number before creating it, because Business Central has no idempotency-key header. Together these stop a re-read document from posting a duplicate invoice.
Does the integration use webhooks or polling?
Both. Concur can push status changes through its Event Subscription Service over mutual TLS, verified by the Concur-Signature header and the known webhook certificate, and Business Central can push change signals through its subscription API. Because Concur events are at-least-once and Business Central notifications carry no payload and expire every three days, ml-connector treats a scheduled poll of the Financial Integration feed as the reliable backstop and renews Business Central subscriptions before they lapse.

Related integrations

Connect Microsoft Dynamics 365 Business Central and SAP Concur

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

Get started