Microsoft Dynamics 365 F&O and TaxJar integration
Microsoft Dynamics 365 F&O is the system of record for sales orders, customer invoices, and the general ledger. TaxJar is where finalized sales get filed to state tax authorities. Connecting the two means each posted customer invoice and credit note flows into TaxJar as a reported transaction, so gross sales, tax collected, and refunds reach the states without anyone re-keying a register. ml-connector handles the very different APIs on each side, bridges the two auth schemes, and moves records on a schedule you control. TaxJar can also return live tax rates on demand when a flow needs them.
What moves between them
The main flow runs from Microsoft Dynamics 365 F&O into TaxJar. After a customer invoice posts, ml-connector reads it from the OData entities and writes it to the TaxJar orders endpoint as a reported transaction, carrying the from and to addresses, amount, shipping, and per-line product tax codes. Posted credit notes flow the same way into the TaxJar refunds endpoint, linked back to the original order by reference id. Exempt customers in Dynamics 365 F&O are synced into TaxJar customers so their exemption_type is applied at filing time. Nexus regions are pulled from TaxJar on a schedule so the ERP can flag where tax obligations exist. TaxJar stores the compliance record, so ml-connector does not write tax data back into the ledger unless a flow explicitly calls the taxes endpoint for a live rate.
How ml-connector handles it
ml-connector stores both credential sets encrypted. On the ERP side it requests an Entra ID client-credentials token scoped to the environment host and refreshes it before the roughly one-hour expiry, and it accepts the full tenant URL per customer because Dynamics 365 F&O has no shared base address. On the tax side it sends the TaxJar API token and pins x-api-version on every call. Because Dynamics 365 F&O business events deliver only a stub with a ControlNumber, ml-connector treats the event as a trigger and calls OData back for the full invoice, and where events are not enabled it polls posted invoices on a schedule, paging with @odata.nextLink and scoping multi-entity reads with cross-company and a dataAreaId filter. Writing to TaxJar follows its upsert rule: a POST that returns 422 because the transaction_id already exists falls back to a PUT, and a PUT that returns 404 falls back to a POST, with a BullMQ jobId deduplicating a re-read invoice. Shipping is always sent, even when zero, and zero-tax orders are still reported because states want gross sales. Dynamics 365 F&O service protection returns HTTP 429 with a Retry-After header, which ml-connector honors, and a once-reported transaction is not silently rewritten after a state has received it.
A real-world example
A mid-sized online retailer with roughly 250 employees runs Microsoft Dynamics 365 F&O for order management, inventory, and finance, and ships into more than twenty states where it has economic nexus. Before the integration, an accountant exported posted invoices each month, reformatted them into a spreadsheet, and keyed gross sales and tax collected into TaxJar by hand, which delayed filings and meant exemption certificates were applied inconsistently. With Microsoft Dynamics 365 F&O and TaxJar connected, every posted invoice and credit note flows into TaxJar within the polling window, exempt customers carry their exemption_type automatically, and refunds reduce the reported totals. Filings come from clean data, and the monthly export-and-rekey step is gone.
What you can do
- Report posted Microsoft Dynamics 365 F&O customer invoices into TaxJar as orders for state sales tax filing.
- Push posted credit notes into TaxJar as refunds, linked back to the original order transaction.
- Sync exempt customers so TaxJar applies the correct exemption_type at filing time.
- Bridge Entra ID OAuth client credentials on the ERP side to the TaxJar API token, with x-api-version pinned.
- Upsert each transaction by transaction_id, always send shipping, honor Retry-After, and audit every record.
Questions
- Which direction does data move between Microsoft Dynamics 365 F&O and TaxJar?
- The main flow is Microsoft Dynamics 365 F&O into TaxJar. Posted customer invoices become reported orders, posted credit notes become refunds, and exempt customers are synced for exemption handling. TaxJar is the compliance record, so ml-connector does not write tax data back into the ledger unless a flow explicitly requests a live rate from the taxes endpoint.
- How does the integration deal with TaxJar having no webhooks and Dynamics business events being stubs?
- TaxJar publishes no push events, so it is always written to or pulled from on a schedule. Dynamics 365 F&O business events deliver only a lightweight stub with a ControlNumber, so ml-connector uses the event as a trigger and calls OData back for the full invoice, and falls back to scheduled polling where business events are not enabled.
- How are duplicate transactions prevented when an invoice is read more than once?
- TaxJar has no idempotency header, so ml-connector follows its recommended upsert pattern: a POST that returns 422 for an existing transaction_id falls back to a PUT, and a PUT that returns 404 falls back to a POST. A BullMQ jobId also deduplicates a re-read invoice, and a transaction already reported to a state is not silently rewritten.
Related integrations
More Microsoft Dynamics 365 F&O integrations
Other systems that connect to TaxJar
Connect Microsoft Dynamics 365 F&O and TaxJar
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started