ml-connector
AcumaticaPayPal

Acumatica and PayPal integration

Acumatica runs finance, distribution, and operations. PayPal moves money: it collects payments, issues refunds, and sends payouts. Connecting the two brings settled PayPal activity into the Acumatica general ledger without re-keying, so captured payments, refunds, and processing fees post against the right accounts. Where you collect or pay through PayPal, Acumatica sales invoices become PayPal invoices sent to customers and Acumatica bills become PayPal payouts to vendors. ml-connector handles the very different authentication and data shapes on each side.

How Acumatica works

Acumatica Cloud ERP exposes vendors, bills, purchase orders, payments, GL accounts, journal transactions, customers, and sales invoices through its Contract-Based REST API. Each instance has its own URL and a version-locked endpoint path, such as /entity/Default/24.200.001/, that must match the customer's ERP release or the call returns 404. All field values are wrapped in value objects, and flat key-value pairs return 400. Authentication is OAuth 2.0 through the built-in OpenID Connect server, or a legacy login session cookie. Acumatica offers Push Notifications, but the common and reliable pattern is polling on LastModifiedDateTime with OData $top and $skip.

How PayPal works

PayPal exposes orders, payment authorizations, captures and refunds, invoices, subscriptions, payouts, and a transaction search through versioned REST APIs, with some resources under /v2 and others under /v1. Authentication is OAuth 2.0 client credentials sent as HTTP Basic auth to the token endpoint, returning a bearer token that is cached for roughly eight hours. Transaction search is read-only, capped at a 31-day window per request, with data appearing up to three hours after a payment. PayPal pushes webhook events signed with RSA-SHA256 and verified against a certificate fetched from a paypal.com URL. It has no GL account, purchase order, or vendor objects.

What moves between them

The main flow runs from PayPal into Acumatica. ml-connector reads settled PayPal activity through transaction search, payment captures, and refunds and posts the resulting entries into Acumatica as journal transactions and AR payments, with captured amounts, refunds, and processing fees each mapped to the matching GL account. A second flow runs the other way for customers and vendors who transact through PayPal: Acumatica sales invoices are created and sent as PayPal invoices, and approved Acumatica bills are paid as PayPal payouts to vendor PayPal accounts. PayPal has no GL resource, so the ledger stays in Acumatica and ml-connector never writes accounting entries back into PayPal.

How ml-connector handles it

ml-connector stores both credential sets encrypted. For PayPal it Base64-encodes the client ID and secret, requests a bearer token from the token endpoint, and caches it for its full lifetime rather than minting one per call. On the Acumatica side it accepts the full instance URL and the exact endpoint version per customer, since a version mismatch returns 404, and it wraps every field value in the required value object so writes do not fail with a 400. Settled PayPal captures, refunds, and fees become Acumatica journal transactions and AR payments, with GL accounts mapped first so every line references an account that already exists. PayPal capture and refund webhooks, verified by RSA-SHA256 against the certificate from the paypal-cert-url, trigger the work as money settles, and a scheduled transaction search backfills anything a webhook missed, walking history in 31-day windows because that is the search limit. Outbound, each PayPal payout carries a sender_batch_id and each create call a PayPal-Request-Id so a retry cannot double-pay, and the Acumatica reference number rides the PayPal invoice_id so the money ties back to the bill or invoice. Acumatica push notifications are not guaranteed, so finance records are polled on LastModifiedDateTime, and both sides return HTTP 429 under load, so ml-connector backs off with jitter and replays on failure.

A real-world example

A mid-sized e-commerce wholesaler with around 120 staff runs Acumatica Cloud ERP for inventory, purchasing, and finance, and takes customer payments and pays some overseas contractors through PayPal. Before the integration, a clerk downloaded PayPal activity each day and typed the gross sales, refunds, and processing fees into Acumatica by hand, then spent month-end close reconciling the PayPal balance against the orders it was supposed to cover, while contractor payouts were entered into PayPal one at a time from a spreadsheet. With Acumatica and PayPal connected, settled payments and fees post into the Acumatica ledger automatically against the right accounts, approved bills go out as PayPal payouts in a batch, and the deposits already tie out. The daily re-keying is gone and close starts from reconciled numbers.

What you can do

  • Post settled PayPal captures, refunds, and processing fees into Acumatica as journal transactions and AR payments against the mapped GL accounts.
  • Pay approved Acumatica bills as PayPal payouts to vendor PayPal accounts, with a sender_batch_id so a retry cannot double-pay.
  • Create and send Acumatica sales invoices as PayPal invoices, carrying the Acumatica reference number in the PayPal invoice_id.
  • Authenticate PayPal with cached OAuth 2.0 client credentials and Acumatica with its version-locked tenant login, wrapping every field value.
  • Verify PayPal webhooks by RSA-SHA256 and backfill with 31-day transaction searches, with retries, error replay, and a full audit trail on every record.

Questions

Which direction does data move between Acumatica and PayPal?
The main flow is PayPal into Acumatica: settled captures, refunds, and processing fees post into the Acumatica general ledger as journal transactions and AR payments. A second flow runs the other way for PayPal customers and vendors, creating PayPal invoices from Acumatica sales invoices and PayPal payouts from approved bills. PayPal has no GL account object, so the ledger stays in Acumatica and ml-connector never writes accounting entries back into PayPal.
How does the integration reconcile PayPal activity into the ledger?
PayPal capture and refund webhooks, verified by RSA-SHA256 against the certificate from the paypal-cert-url, trigger a posting as soon as money settles. A scheduled transaction search backfills anything a webhook missed, walking history in 31-day windows because that is PayPal's per-request search limit and transactions can take up to three hours to appear. Each amount, refund, and fee maps to a GL account that already exists in Acumatica.
How does the integration handle Acumatica's version-locked URL and PayPal's token?
ml-connector accepts the full Acumatica instance URL and the exact endpoint version per customer, since a version mismatch returns a 404, and it wraps every field value in the value object Acumatica requires so posts do not fail with a 400. For PayPal it caches the OAuth 2.0 bearer token for its roughly eight-hour lifetime rather than requesting one per call, which avoids the rate limits PayPal applies to abusive traffic.

Related integrations

Connect Acumatica and PayPal

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

Get started