ml-connector
AcumaticaTipalti

Acumatica and Tipalti integration

Acumatica Cloud ERP runs finance, including the vendor master, accounts payable, and the general ledger. Tipalti runs global supplier onboarding and payment execution. Connecting the two means approved AP bills and their vendors leave Acumatica, get paid through Tipalti across many countries and methods, and the payment result comes back to mark the bill paid in Acumatica. ml-connector handles the very different APIs on each side and moves the records on a schedule you control. Because Acumatica stays the system of record for the ledger, ml-connector never lets Tipalti overwrite Acumatica's chart of accounts.

How Acumatica works

Acumatica Cloud ERP exposes Vendor, Bill, Payment, Purchase Order, JournalTransaction, and Account records through its Contract-Based REST API, JSON over HTTPS on a tenant-specific URL whose endpoint version, such as 24.200.001, must match the running ERP release or the call returns 404. It authenticates with OAuth 2.0 through the built-in OpenID Connect identity server, where the client ID embeds the company name, or with a legacy session cookie. All field values are wrapped in value objects, and writes use PUT upsert semantics. Acumatica can push changes through Push Notifications secured by a shared-secret header, but the common and reliable pattern is polling on LastModifiedDateTime with top and skip offset paging.

How Tipalti works

Tipalti exposes two API families. The mature SOAP Payer and Payee API, currently v14, covers payees, invoices, purchase orders, payments, GL accounts, and tax codes, and authenticates with an HMAC-SHA256 key computed from the payer name, payee id, and a timestamp rather than a session token. The newer REST API uses OAuth 2.0 client credentials, with the Procurement module on the approve.com domain using a static x-api-key. Reads use timestamp-based incremental calls such as GetPayeesChangedSinceTimestamp, capped at 250 records per SOAP call. Tipalti reports payment outcomes through IPN webhooks signed with the same HMAC key, delivered to a single endpoint per payer account.

What moves between them

The main flow runs from Acumatica into Tipalti. ml-connector reads vendors and approved, released AP bills from Acumatica and creates or updates the matching payees and invoices in Tipalti through UpdateOrCreatePayeeInfo and CreateOrUpdateInvoices so the payment runs on Tipalti's rails. Payment results flow the other way: Tipalti payment status, including completed, error, and cancelled, returns to Acumatica where ml-connector records the AP payment against the original bill and updates its status. GL accounts and currencies are aligned in both directions so each invoice and payment lands on a valid Acumatica account. The Acumatica general ledger and chart of accounts stay the source of record, so ml-connector never writes ledger structure back from Tipalti.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the Acumatica side it requests and refreshes an OAuth 2.0 bearer token against the tenant identity server, keeps the endpoint version in config so the version-locked URL stays valid, and wraps every field value in the required value object. On the Tipalti side it computes the HMAC-SHA256 key for each SOAP call from the exact payer name, payee id, and timestamp, since any casing or spacing mismatch in the payer name breaks auth silently, and it uses the x-api-key or OAuth path for any REST Procurement calls. Vendors are mapped to payees and GL accounts are aligned first, so every invoice and returned payment references records that already exist on both sides. Because Acumatica cloud reads are pull-based, ml-connector polls released Bill records on LastModifiedDateTime with top and skip paging, and it consumes Tipalti IPN payment events to update bill status without waiting for a poll. Acumatica has no idempotency header and Tipalti can redeliver an IPN, so ml-connector dedupes on the bill reference and a BullMQ jobId before posting a payment, which prevents double-marking a bill paid. Acumatica rate limits return HTTP 429 by license tier and Tipalti caps SOAP reads at 250 records, so ml-connector backs off, retries, and pages within those limits. One real edge case is handled explicitly: updating a payee street address in Tipalti forces the payee to re-verify their payment method, so ml-connector only pushes address changes when they actually differ. Every record carries a full audit trail and can be replayed if a downstream call fails.

A real-world example

A mid-sized software company with about 300 employees runs Acumatica Cloud ERP for finance and pays a few hundred contractors and vendors across a dozen countries each month. Before the integration, the AP team approved bills in Acumatica, then exported a payment file and re-keyed payee and invoice details into Tipalti by hand, and at month-end chased which bills had actually cleared versus failed. With Acumatica and Tipalti connected, approved bills and their vendors flow into Tipalti automatically, payments run on Tipalti's global rails with the right currency, and each completed or rejected payment posts back to the matching Acumatica bill. The re-keying step is gone, failed payments are visible against the original bill, and the AP ledger reflects real payment status without a manual reconciliation pass.

What you can do

  • Create and update Tipalti payees and invoices from Acumatica vendors and approved AP bills.
  • Post Tipalti payment results back to Acumatica and mark the original bill paid, failed, or cancelled.
  • Map GL accounts and currencies between Acumatica and Tipalti so every invoice and payment lands on a valid account.
  • Authenticate Acumatica with OAuth 2.0 and tenant login, and Tipalti with its HMAC-SHA256 key and OAuth 2.0.
  • Poll released Acumatica bills and consume Tipalti IPN events, with jobId dedup, retries, and a full audit trail on every record.

Questions

Which direction does data move between Acumatica and Tipalti?
The main flow is Acumatica into Tipalti, where vendors become payees and approved AP bills become invoices for payment. Payment results then return from Tipalti to Acumatica to mark the original bill paid, failed, or cancelled. The Acumatica general ledger and chart of accounts stay the source of record, so ml-connector never writes ledger structure back from Tipalti.
Does Acumatica push AP bills, or does ml-connector poll for them?
Polling is the default. Acumatica can send Push Notifications secured by a shared-secret header, but the reliable pattern is to poll released Bill records on LastModifiedDateTime with top and skip paging. In the other direction Tipalti pushes payment outcomes through IPN webhooks, which ml-connector consumes to update bill status as soon as a payment completes or fails.
How does the integration handle Tipalti's HMAC key and the two API families?
ml-connector computes the HMAC-SHA256 key for every SOAP call from the exact payer name, payee id, and timestamp, because any payer name mismatch breaks auth without a clear error. It uses the SOAP Payer and Payee API for payees, invoices, and payment status, and the OAuth 2.0 or x-api-key REST path for Procurement calls. Tipalti IPN callbacks are verified against the same HMAC key before any Acumatica bill is updated.

Related integrations

Connect Acumatica and Tipalti

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

Get started