ml-connector
Microsoft Dynamics 365 F&OPaychex

Microsoft Dynamics 365 F&O and Paychex integration

Microsoft Dynamics 365 F&O runs finance, procurement, and the general ledger. Paychex runs HR and payroll. Connecting the two keeps your workforce and your ledger in agreement. New hires, terminations, and pay-rate changes in Paychex line up with Dynamics workers and cost centers, and the earnings and deduction totals from each processed payroll check post into the Dynamics general ledger without re-keying. ml-connector handles the different REST APIs on each side and moves the data on a schedule you control.

How Microsoft Dynamics 365 F&O works

Microsoft Dynamics 365 F&O exposes vendors, customers, products, purchase orders, vendor invoices, main accounts, journal entries, and financial dimensions through an OData v4 REST API at a tenant-specific environment host such as contoso.operations.dynamics.com. It authenticates with OAuth2 client credentials issued by Microsoft Entra ID, scoped to that host, with bearer tokens that expire in about an hour. OData entity keys must be fully specified and writes use natural keys with no idempotency header, so duplicates raise a key violation. Dynamics pushes outbound Business Events to an HTTPS or Azure endpoint, but each payload is a lightweight stub carrying identifiers, so the handler must call OData back for full record detail.

How Paychex works

Paychex Flex exposes companies, workers covering both employees and contractors, jobs, organizations and locations, pay components, and processed payroll checks through a REST JSON API at the fixed base URL api.paychex.com. Authentication is OAuth2 client credentials with a finite token TTL and no refresh token, so the token is re-acquired before it expires. Every company-scoped call requires resolving companyId first via GET /companies, and a full worker profile needs several sequential calls for communications, compensation, and taxes. Paychex has no vendor, invoice, purchase order, or GL account objects, so it is an HR and payroll source, not an accounting target. It can push notification-only webhooks for worker add, demographic, compensation, and employment events.

What moves between them

The main flow runs from Paychex into Microsoft Dynamics 365 F&O. ml-connector reads Paychex workers and posts them into the Dynamics worker and HR entities so headcount reflects Paychex hires, terminations, and rehires, and it carries compensation and pay-rate changes the same direction. After each pay run, it reads the processed Paychex checks and their pay components and posts the earnings and deduction totals into the Dynamics general ledger as labor cost journals, mapped to the matching main accounts and cost centers. Reference data such as Paychex organizations, locations, and job codes is aligned to Dynamics financial dimensions so every journal line lands on a valid combination. Paychex has no GL account object, so the chart of accounts stays in Dynamics and ml-connector never writes accounting records back into Paychex.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the Paychex side it requests an OAuth2 client-credentials token, re-acquires it before the TTL expires, and resolves companyId through GET /companies before any worker or check call, sending the Paychex vendor media type Accept and Content-Type headers each request. On the Dynamics side it accepts the tenant environment host per customer, since there is no shared base URL, and requests an Entra ID token scoped to that host, refreshing on a 401. Because Paychex has no GL document object, the labor journal is built in ml-connector from each processed check's pay components rather than read whole, and organizations and cost centers are mapped first so every line resolves to a real Dynamics main account and financial dimension. Dynamics has no idempotency header and rejects duplicate natural keys, so each worker and journal carries a BullMQ jobId and is deduplicated before the OData write to avoid double-posting a re-read record. Paychex offset pagination can skip or duplicate rows mid-crawl, so ml-connector pages sequentially with the page ETag, and on a 429 from either side it reads Retry-After and backs off with jitter. Where Paychex webhooks are enabled, ml-connector takes a worker-add or compensation event as a trigger, then fetches the full record by GET since the payload is notification-only. Every record carries a full audit trail and can be replayed if a downstream call fails.

A real-world example

A mid-sized manufacturer with roughly 400 employees across two plants runs Microsoft Dynamics 365 F&O for finance and procurement and uses Paychex Flex for payroll and HR. Before the integration, the finance team exported the payroll register from Paychex every pay period and hand-keyed the labor totals into Dynamics, then re-entered new hires and terminations into the worker records, and spent the first days of month-end close chasing differences between HR headcount and the labor accounts in the ledger. With Microsoft Dynamics 365 F&O and Paychex connected, each pay run's check totals flow into the Dynamics general ledger automatically, allocated to the cost center for each plant, and worker changes keep the two systems aligned. Close starts with the labor accounts already reconciled, and the manual re-keying is gone.

What you can do

  • Post Paychex processed-check earnings and deduction totals into the Microsoft Dynamics 365 F&O general ledger after every pay run.
  • Keep Dynamics worker records aligned with Paychex hires, terminations, rehires, and pay-rate changes.
  • Map Paychex organizations, locations, and job codes to Dynamics financial dimensions so payroll lands on valid accounts.
  • Authenticate Paychex with OAuth2 client credentials and Dynamics with an Entra ID token scoped to the tenant host.
  • Resolve companyId per run, dedupe on natural keys and jobId, and keep a full audit trail with replay on every record.

Questions

Which direction does data move between Microsoft Dynamics 365 F&O and Paychex?
The main flow is Paychex into Dynamics. Worker records, compensation changes, and the earnings and deduction totals from each processed payroll check move from Paychex into Dynamics, posted as worker updates and general ledger journals. Paychex has no vendor, invoice, or GL account objects, so the chart of accounts stays in Dynamics and ml-connector does not write accounting records back into Paychex.
Paychex has no general ledger document, so how does payroll reach the Dynamics GL?
Paychex exposes processed checks and their pay components rather than a finished GL document. ml-connector reads each check, sums the earnings and deduction pay components, and builds the labor cost journal it posts into the Dynamics general ledger. Organizations and cost centers are mapped to Dynamics financial dimensions first, so every journal line lands on a valid main account and dimension combination.
How does the integration handle Paychex companyId, tokens, and pagination?
Every Paychex flow begins with GET /companies to resolve companyId, since there is no global worker namespace. ml-connector acquires an OAuth2 client-credentials token and re-acquires it before the TTL expires because Paychex issues no refresh token, retrying once on a 401. It pages worker lists sequentially with offset, limit, and the page ETag to avoid skipped or duplicated rows, and backs off on a 429 using the Retry-After header.

Related integrations

Connect Microsoft Dynamics 365 F&O and Paychex

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

Get started