ml-connector
AcumaticaPaychex

Acumatica and Paychex integration

Acumatica runs finance, distribution, and operations. Paychex Flex runs HR and payroll. Connecting the two keeps your workforce and your general ledger in agreement without re-keying. New hires, terminations, and pay changes in Paychex line up with Acumatica employee records and departments, and the labor cost from each processed payroll check posts into the Acumatica general ledger against the correct accounts. ml-connector handles the very different APIs on each side and moves the data on a schedule you control.

How Acumatica works

Acumatica Cloud ERP exposes vendors, bills, purchase orders, GL accounts, journal transactions, employees, and organizations through its contract-based REST API. Each instance lives at a tenant-specific URL and the endpoint version in the path must match the running ERP release exactly, or the call returns 404. Authentication is OAuth 2.0 through the built-in identity server, with cookie session login as a legacy fallback. Acumatica can push events through its Push Notifications feature using a shared-secret header rather than an HMAC signature, but the most common pattern is polling records by their LastModifiedDateTime, and field values in every payload are wrapped in value objects.

How Paychex works

Paychex Flex exposes workers, jobs, organizations, locations, pay components, and processed payroll checks through a REST API at the fixed base URL https://api.paychex.com. Authentication is OAuth 2.0 client credentials, which returns a bearer token with no refresh token, so the integration re-acquires a token before expiry. Every company-scoped call requires resolving companyId first through GET companies. Paychex supports webhooks for events such as new worker added, employment status changed, and compensation changed, but the payloads are notification-only and carry no data, so the current record must be fetched with a follow-up GET. Paychex is an HR and payroll system and has no vendors, invoices, or GL accounts.

What moves between them

The main flow runs from Paychex into Acumatica. Worker records move from Paychex into Acumatica employee records so headcount, hires, terminations, and pay changes stay aligned. After each payroll is processed, ml-connector reads the Paychex checks and posts the labor cost into Acumatica as journal transactions, mapped to the matching GL accounts and to subaccounts derived from Paychex organizations. Reference data such as Paychex organizations, locations, and job definitions is used to keep every posting on a valid Acumatica dimension. Paychex is treated as the system of record for people and pay, so ml-connector does not write financial entries back into Paychex.

How ml-connector handles it

ml-connector stores both credential sets encrypted and runs two separate OAuth flows: client credentials against the Paychex token endpoint and OAuth 2.0 against the Acumatica identity server on the customer tenant URL. It re-acquires the Paychex bearer token before it expires, since no refresh token is issued, and refreshes the Acumatica token when a call returns 401. On the Acumatica side it stores the exact endpoint version per customer so the version-locked URL never returns a 404, and it wraps every field value in the required value object. Paychex change events arrive as notification-only webhooks, so each event triggers a follow-up GET to read the current worker or check before anything is written. Because the same Paychex notification can arrive more than once and Acumatica push notifications retry up to five times, every record is processed idempotently: workers are matched on a stable key and upserted, and a posted journal is checked before a duplicate is created. Paychex organizations are mapped to Acumatica subaccounts first, so each payroll journal line references a GL account and dimension that already exists. Both sides return HTTP 429 under load, so ml-connector backs off with jitter and retries, and it sequences worker sub-resource calls because a full Paychex worker profile needs several GET calls.

A real-world example

A mid-sized field services company with about 300 employees across several branches runs Acumatica Cloud ERP for finance and operations and uses Paychex Flex for payroll and HR. Before the integration, the finance team exported payroll registers from Paychex every pay period and keyed the labor totals into Acumatica by hand, then re-entered new hires and terminations into Acumatica employee records, and spent the first days of month-end close chasing differences between HR headcount and the labor accounts in the ledger. With Acumatica and Paychex connected, each processed payroll posts into Acumatica automatically, allocated to the subaccount for each branch, and worker changes keep the two systems aligned. Month-end close starts with the labor accounts already reconciled and the manual re-keying step is gone.

What you can do

  • Sync Paychex workers into Acumatica employee records so hires, terminations, and pay changes stay aligned.
  • Post the labor cost from each processed Paychex payroll into Acumatica as GL journal transactions.
  • Map Paychex organizations and locations to Acumatica subaccounts so payroll lands on valid dimensions.
  • Run both OAuth flows, re-acquiring the Paychex token before expiry and refreshing the Acumatica token on 401.
  • Fetch the current record after each notification-only Paychex webhook, with retries and a full audit trail.

Questions

Which direction does data move between Acumatica and Paychex?
The main flow is Paychex into Acumatica. Worker records and the labor cost from processed payroll checks move from Paychex into Acumatica employee records and the general ledger. Paychex is the system of record for people and pay, so ml-connector does not write financial entries back into Paychex.
How does the integration handle the two different OAuth methods?
Paychex uses OAuth 2.0 client credentials and issues a bearer token with no refresh token, so ml-connector re-acquires the token before it expires. Acumatica uses OAuth 2.0 against the identity server on the customer tenant URL, and ml-connector refreshes that token when a call returns 401. Both credential sets are stored encrypted.
What happens with Paychex webhooks that carry no data?
Paychex webhooks are notification-only and tell you that a worker or check changed without including the changed data. ml-connector responds to the event and then calls the relevant Paychex GET endpoint to read the current record before writing to Acumatica. Because Paychex does not deduplicate deliveries, each record is processed idempotently so a repeated notification does not create a duplicate.

Related integrations

Connect Acumatica and Paychex

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

Get started