ml-connector
AcumaticaStripe

Acumatica and Stripe integration

Acumatica Cloud ERP runs your finance, AR, and accounting. Stripe processes the card payments, refunds, and payouts that sit downstream of those AR invoices. Connecting the two lets customers pay Acumatica invoices through Stripe and brings the settled cash, fees, and refunds back into the ledger without re-keying. ml-connector mirrors AR customers and finalized invoices into Stripe, then reads Stripe payment activity and posts it into Acumatica as applied payments and GL journals. It handles the very different auth and event models on each side and runs the sync on the cadence you set.

How Acumatica works

Acumatica Cloud ERP exposes Customer, SalesInvoice, Bill, Payment, Account, JournalTransaction, and StockItem records through its Contract-Based REST API, served as JSON over HTTPS from a tenant-specific URL whose endpoint version must exactly match the customer's ERP release. Authentication is OAuth 2.0 from the OpenID Connect identity server built into each instance, with a legacy cookie session as a fallback. All field values in request and response bodies are wrapped in value objects, and there is no native idempotency key. Acumatica can push events through its Push Notifications system using a shared-secret header rather than a signed payload, but the common and most reliable pattern is polling on the LastModifiedDateTime filter with offset pagination.

How Stripe works

Stripe is a payments platform, not an ERP, so it has no vendor, purchase order, or GL account objects. It exposes Customers, Invoices, PaymentIntents, Charges, Refunds, Payouts, Disputes, and read-only Balance Transactions through a REST API where updates are POST requests and amounts are in the smallest currency unit. Every call carries a secret API key over HTTP Basic auth, since Stripe offers no OAuth2 for standard server-to-server use; restricted keys allow least-privilege scoping. Stripe pushes events such as invoice.paid, charge.refunded, and payout.paid by webhook, signed with HMAC-SHA256 over the raw body, delivered at least once with retries for up to three days.

What moves between them

Two directions. From Acumatica into Stripe, ml-connector mirrors AR Customer records and pushes finalized SalesInvoice documents so buyers receive a Stripe invoice they can pay by card. From Stripe into Acumatica, it reads settled PaymentIntents, charges, refunds, and the fee lines on balance transactions, then posts applied AR payments against the matching Acumatica invoice and GL journals for the processing fees and refunds. Stripe webhooks such as invoice.paid, charge.refunded, and payout.paid trigger the inbound work as money settles, and a scheduled poll on LastModifiedDateTime backfills any Acumatica change or Stripe event a webhook missed.

How ml-connector handles it

ml-connector stores both credential sets encrypted, sends Stripe's secret key over HTTP Basic auth on every request, and refreshes the Acumatica OAuth token when a call returns 401. On the Acumatica side it accepts the full instance URL and endpoint version per customer, since the version is locked and a mismatch returns 404, and it wraps every field value in the required value object. Stripe webhooks arrive signed with HMAC-SHA256 over the raw body, so each event is verified before processing and deduplicated on its event id, because Stripe delivers at least once and does not guarantee order; after verifying, the connector re-fetches the resource from the Stripe API rather than trusting the event payload. Amounts are converted from Stripe's smallest currency unit into Acumatica decimal values before any journal is posted. Customers are mapped first so every invoice and payment references an account that exists on both sides. Acumatica rate limits return 429 once usage passes the licensed threshold, and Stripe returns 429 with a rate-limited reason header, so ml-connector backs off with jitter and retries. Every record carries a full audit trail and can be replayed if a downstream post fails.

A real-world example

A regional professional-services firm of around 150 staff runs Acumatica Cloud ERP for AR and accounting and uses Stripe to collect card payments on its client invoices. Before the integration, billing staff exported open invoices from Acumatica and rebuilt them in Stripe by hand, then each week downloaded the Stripe payout report and keyed the receipts, refunds, and processing fees back into Acumatica, where deposits rarely tied out to the invoices they covered. With Acumatica and Stripe connected, finalized invoices flow to Stripe automatically, settled payments post back as applied AR payments against the right invoice, and the processing fees land in their own GL account. The weekly re-keying disappears and month-end close starts from cash that already reconciles.

What you can do

  • Mirror Acumatica AR customers into Stripe and push finalized sales invoices so buyers can pay by card.
  • Post settled Stripe payments back into Acumatica as AR payments applied to the matching invoice.
  • Record Stripe refunds and processing fees as Acumatica GL journals against the correct accounts.
  • Authenticate Stripe with its secret key over HTTP Basic and Acumatica with its OAuth token on the version-locked instance URL.
  • Verify Stripe webhook signatures, deduplicate on event id, and reconcile smallest-unit amounts with retries and a full audit trail.

Questions

Which direction does data move between Acumatica and Stripe?
Both directions, by record type. AR customers and finalized sales invoices move from Acumatica into Stripe so buyers can pay by card. Settled payments, refunds, and processing fees move from Stripe back into Acumatica as applied AR payments and GL journals. ml-connector does not create vendors, purchase orders, or GL accounts in Stripe, because Stripe is a payments platform and has no such objects.
How does the integration handle Stripe webhooks and Acumatica's version-locked API?
Stripe webhooks are verified against the HMAC-SHA256 signature on the raw body, deduplicated on the event id, and confirmed by re-fetching the resource from the Stripe API, since events are unordered and delivered at least once. On the Acumatica side, ml-connector accepts the exact instance URL and endpoint version per customer, because a version mismatch returns HTTP 404, and it polls on LastModifiedDateTime as a catch-up alongside the webhooks.
What happens to Stripe processing fees and amount formatting?
Stripe reports fees on its balance transactions, so ml-connector reads those fee lines and posts them into Acumatica as GL journal entries against the processing-fee account you map, keeping the net deposit reconciled. All Stripe amounts are in the smallest currency unit, such as cents, so the connector converts them to Acumatica decimal values before posting any payment or journal.

Related integrations

Connect Acumatica and Stripe

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

Get started