ml-connector
QADPaychex

QAD and Paychex integration

QAD runs manufacturing and finance. Paychex Flex runs payroll and HR. Connecting the two keeps your workforce and your QAD cost structure in agreement without re-keying. New hires, terminations, and department moves in Paychex line up with QAD cost centers, and the organization units Paychex maintains stay aligned with the dimensions QAD posts against. ml-connector handles the very different APIs on each side and moves the data on a schedule you control.

How QAD works

QAD Adaptive ERP exposes suppliers, purchase orders, supplier invoices, GL accounts, cost centers, items, and goods receipts through REST business document APIs, documented in Swagger inside each customer instance. The cloud product authenticates with a JWT session or OAuth2 bearer token against a tenant-specific URL, so there is no shared hostname. Older on-premise sites run QAD Enterprise Edition with the QXtend SOAP framework instead. QAD has no public webhook system for cloud connectors, so finance records are read by polling.

How Paychex works

Paychex Flex exposes workers, organization units such as departments and cost centers, locations, jobs, payroll checks, and pay components through the Paychex Developer API, a REST and JSON service on the fixed base URL api.paychex.com. Every call uses an OAuth2 client-credentials bearer token with a finite lifetime and no refresh token, and the companyId must be resolved through GET companies before any company-scoped call. Workers are read and write, while organizations, locations, and pay reference data are read-only. Paychex supports notification webhooks for worker changes, but the payloads carry no data, so each event is followed by a GET to fetch the current record.

What moves between them

The main flow runs from Paychex Flex into QAD. ml-connector reads Paychex workers and organization units and keeps QAD headcount and cost centers aligned with hires, terminations, rehires, and department moves. Paychex organizations and locations map to QAD cost centers and dimensions so every workforce record references a QAD value that already exists. Because Paychex Flex holds no GL accounts, invoices, or supplier data, no financial documents move on this connection; the scope is HR and cost-center alignment, not payroll journal posting. QAD cost-center definitions can seed the Paychex organization mapping so both sides agree on department codes.

How ml-connector handles it

ml-connector stores both credential sets encrypted and acquires a fresh Paychex OAuth2 client-credentials token before the prior one expires, since Paychex issues no refresh token. It resolves the Paychex companyId through GET companies at the start of every run, because there is no global worker namespace and each company-scoped path needs that id. On the QAD side it accepts the full tenant URL per customer, since QAD publishes no shared base URL. Paychex worker webhooks for added, demographic, compensation, and employment-status changes carry no data, so ml-connector receives the event and then calls the matching GET endpoint to fetch the current worker, while QAD cloud is polled on a schedule because it has no webhooks. Worker lists are paged with offset and limit up to one hundred records, and the ETag is carried between pages to avoid skipped or duplicated rows when the dataset shifts mid-crawl. Organizations and locations are mapped to QAD cost centers first, so every headcount update lands on a valid dimension. Paychex rate limits return HTTP 429 with a Retry-After header, so ml-connector backs off with jitter and paginates sequentially rather than in parallel, and because Paychex has no idempotency-key scheme it checks for an existing record before any create. Every record carries a full audit trail and can be replayed if a downstream call fails.

A real-world example

A mid-sized discrete manufacturer runs QAD Adaptive ERP for production, procurement, and finance, and uses Paychex Flex for payroll and HR across two plants and a head office. Before the integration, the operations team maintained department and headcount data in Paychex but had to re-enter cost-center and staffing changes into QAD by hand, so labor allocations in the ERP drifted out of step with who actually worked where. With QAD and Paychex Flex connected, worker and organization changes flow into QAD automatically, mapped to the cost center for each plant, and the two systems stay aligned without manual re-keying. Cost reporting in QAD reflects the current workforce, and the duplicate data entry is gone.

What you can do

  • Keep QAD headcount aligned with Paychex Flex hires, terminations, rehires, and department moves.
  • Map Paychex organizations and locations to QAD cost centers and dimensions so workforce records land on valid values.
  • Authenticate Paychex with OAuth2 client credentials and refresh the token before expiry, and QAD with its tenant-specific login.
  • React to Paychex worker webhooks by fetching the changed record, and poll QAD on a schedule because it has no webhooks.
  • Page Paychex workers with offset and limit and the ETag for consistency, with backoff on HTTP 429 and a full audit trail on every record.

Questions

Which direction does data move between QAD and Paychex?
The main flow is Paychex Flex into QAD. Workers and organization units move from Paychex into QAD to keep headcount and cost centers aligned, while QAD cost-center definitions can seed the Paychex organization mapping so both sides agree on department codes. Paychex Flex holds no GL accounts or invoices, so no financial documents move on this connection.
Does this integration post payroll journals into QAD?
No. The Paychex Developer API exposes HR and payroll data such as workers, organizations, and payroll checks, but it has no general ledger, supplier, or invoice entities. This connection handles workforce and cost-center alignment, not GL posting, so labor journals are not written into QAD's general ledger from Paychex.
How does ml-connector handle Paychex webhooks and token expiry?
Paychex worker webhooks are notification-only and carry no changed data, so ml-connector receives the event and then calls the matching GET endpoint to fetch the current record. Paychex tokens expire with no refresh token under client credentials, so ml-connector acquires a new token proactively before expiry and re-authenticates once on a 401. Because QAD cloud has no webhooks, QAD is read by polling on a schedule you control.

Related integrations

Connect QAD and Paychex

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

Get started