ml-connector
QADPlaid

QAD and Plaid integration

QAD runs manufacturing, procurement, and finance. Plaid connects to bank accounts for account verification, bank transactions, and ACH and wire payment initiation. Connecting the two lets QAD supplier and customer bank details be verified against the real account and routing numbers Plaid returns, lets approved QAD supplier invoices be paid by ACH or wire through Plaid Transfer, and lets Plaid bank transactions reconcile against QAD AP payments. Plaid is a bank-data network, not an ERP, so it has no vendors, invoices, or GL accounts, and the integration is shaped around the bank side of the relationship. ml-connector handles the two very different APIs and moves the data on a schedule you control.

How QAD works

QAD Adaptive ERP exposes suppliers, customers, purchase orders, supplier invoices, AP payments, 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, and on-premise QXO can push XML events.

How Plaid works

Plaid exposes bank accounts, account and routing numbers through Auth, bank transactions, ACH and wire transfers, identity, and investment holdings through the Plaid API. Every endpoint is an HTTP POST with a JSON body, including reads, and there are no GET endpoints. Authentication uses a long-lived client_id and secret supplied as headers or body fields, plus a per-user access_token obtained when an end user links a bank through Plaid Link. Plaid pushes real webhooks for transaction and transfer updates and Item health, signed with an ES256 JWT in the Plaid-Verification header. Transfer status is event-driven and read with /transfer/event/sync rather than by polling.

What moves between them

Bank account and routing numbers move from Plaid Auth into QAD to verify supplier and customer bank details before payments go out. Approved QAD supplier invoices and AP payment instructions move from QAD into Plaid Transfer as ACH or wire authorizations and transfers. Transfer status changes and cleared bank transactions move from Plaid back into QAD so AP payments are marked paid, failed, or returned and reconciled against the ledger. QAD is polled on a schedule for newly approved invoices and payment runs, while Plaid transfer events and transaction updates arrive by webhook and are then fetched with the matching sync endpoint.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the QAD side it accepts the full tenant URL per customer, since QAD publishes no shared base URL, and authenticates with the tenant JWT or OAuth2 token, validating entity paths against that instance. On the Plaid side it sends the client_id and secret as headers and stores the per-user access_token returned from the Plaid Link exchange, since the access_token is per bank connection rather than a single system credential. Because every Plaid call is a POST, including reads, requests are built as JSON bodies with the Plaid-Version header set to 2020-09-14. Supplier and customer bank details are matched first so a QAD supplier maps to the Plaid Item and account that holds its real routing and account number. Payments use a Plaid transfer authorization followed by a transfer create, with an idempotency_key on the authorization and idempotency on the authorization_id so a retry never double-pays. Plaid transfer events arrive by webhook, are verified by decoding the ES256 JWT and fetching the rotating JWK with /webhook_verification_key/get, and the status is read with /transfer/event/sync, never by repeatedly polling /transfer/get. Description fields are truncated to the ACH and RTP limits before sending, HTTP 429 from per-Item or per-client rate limits triggers exponential backoff, and a 500 from transfer create is resolved by checking transfer events before any retry. Every record carries a full audit trail and can be replayed if a downstream call fails.

A real-world example

A mid-sized industrial parts manufacturer runs QAD Adaptive ERP for procurement and finance and pays a few hundred suppliers each month. Before the integration, the AP team keyed supplier bank details from emails and PDFs, then ran payments through a bank portal by hand, with no quick way to confirm that the account and routing number on file were still valid or that a payment had actually cleared. With QAD and Plaid connected, supplier bank details are verified against Plaid Auth before a payment goes out, approved invoices are paid by ACH through Plaid Transfer, and transfer events plus cleared bank transactions flow back into QAD so each AP payment is marked paid or returned without manual checking. Payment errors from stale account numbers drop, and reconciliation stops being a manual chase.

What you can do

  • Verify QAD supplier and customer bank details against the real account and routing numbers Plaid Auth returns before paying.
  • Initiate ACH and wire payments for approved QAD supplier invoices through Plaid Transfer with idempotent authorizations.
  • Reconcile Plaid bank transactions and transfer events against QAD AP payments so cleared, failed, and returned payments are reflected.
  • Bridge QAD tenant login with Plaid's client_id and secret and per-user access tokens from Plaid Link.
  • Consume Plaid transfer and transaction webhooks with ES256 JWT verification, with retries and a full audit trail on every record.

Questions

Can Plaid send invoices or GL data into QAD?
No. Plaid is a bank-data network and has no vendors, invoices, purchase orders, or GL accounts. It provides bank account and routing numbers, bank transactions, and ACH and wire payment initiation, so the integration uses Plaid to verify supplier bank details, pay approved QAD invoices, and reconcile cleared payments rather than to source accounting documents.
How does ml-connector authenticate to QAD and Plaid?
On the QAD side ml-connector accepts the full tenant-specific instance URL per customer and authenticates with the tenant JWT or OAuth2 token, since QAD publishes no shared base address. On the Plaid side it sends a long-lived client_id and secret and stores the per-user access_token returned when an end user links a bank through Plaid Link. Both credential sets are stored encrypted.
How are payment status updates handled given QAD has no webhooks?
Plaid transfer status is event-driven, so ml-connector receives the TRANSFER_EVENTS_UPDATE webhook, verifies it by decoding the ES256 JWT and fetching the rotating JWK, then reads the change with /transfer/event/sync rather than polling. Because QAD cloud is pull-only, ml-connector polls QAD on a schedule for newly approved invoices and writes the resulting payment status back, so QAD AP payments stay aligned without any push from QAD.

Related integrations

Connect QAD and Plaid

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

Get started