ml-connector
AcumaticaSquare

Acumatica and Square integration

Acumatica Cloud ERP runs finance, AR, AP, and the general ledger. Square runs point of sale, online payments, and invoicing at the storefront. Connecting the two means card and online sales, the invoices behind them, and refunds flow into Acumatica as AR invoices and cash without re-keying, and the customer master stays in agreement on both sides. ml-connector handles the different APIs on each system and moves the data on a schedule you control. Because Square has no chart of accounts, the general ledger stays in Acumatica where it belongs.

How Acumatica works

Acumatica exposes vendors, customers, AP bills, sales invoices, payments, GL accounts, journal transactions, and stock items through its Contract-Based REST API, which serves JSON over HTTPS on a tenant-specific URL such as mycompany.acumatica.com. Every request targets an endpoint version that must exactly match the running ERP release, and field values in each body are wrapped in value objects. Authentication uses OAuth 2.0 against the built-in OpenID Connect server, with a Client ID that embeds the company name, or a legacy session cookie. Acumatica can push events through its Push Notifications screen, but those use a shared-secret header rather than a signed payload, so finance records are most reliably read by polling on LastModifiedDateTime.

How Square works

Square exposes payments, refunds, invoices, orders, customers, vendors, catalog items, and locations through its versioned REST API at connect.squareup.com, with the Square-Version header set on every call. Authentication is OAuth 2.0 with a Bearer access token that expires in 30 days plus a non-expiring refresh token, or a personal access token for a single account. Most resources are scoped to a location_id, and an invoice always sits on top of an order. Square has no chart of accounts and no purchase order API, since it is a commerce and payments layer rather than an accounting system. Square pushes events such as payment.created, invoice.payment_made, and refund.updated by webhook, each signed with HMAC-SHA-256.

What moves between them

The main flow runs from Square into Acumatica. ml-connector reads settled payments, the invoices and orders behind them, and refunds from Square and posts them into Acumatica as AR sales invoices and the matching receivable and cash entries, mapped to the right Acumatica customers, GL accounts, and branches. Customer records flow the same direction so the Acumatica customer master reflects Square buyers. Each Square location is mapped to an Acumatica branch so sales land on the correct books. GL postings stay in Acumatica, since Square has no GL resource, so ml-connector never writes ledger or chart-of-accounts data back to Square.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the Square side it sends the OAuth Bearer token with the Square-Version header on every call and refreshes the 30-day access token before it expires rather than waiting for a 401. On the Acumatica side it accepts the full tenant URL and the matching endpoint version per customer, validates entity paths against that instance, and wraps every field value in the required value object. Square webhooks are verified with HMAC-SHA-256 over the signature key, notification URL, and raw body, and a bad signature returns 403; a verified event triggers the sync right away, while a scheduled poll on LastModifiedDateTime backfills anything a webhook missed. Customers are mapped first, so every Square sale resolves to an Acumatica customer that already exists, and each location maps to a branch. Because Acumatica has no idempotency header, ml-connector dedupes on the Square payment or order id and a BullMQ jobId before it posts, and uses PUT upsert so a re-read sale updates rather than duplicates. Square paginates by cursor with a five-minute TTL, so cursors are consumed promptly. Every record carries a full audit trail and can be replayed if a downstream Acumatica call fails.

A real-world example

A regional cafe group with eight locations takes payments and sells online through Square, and runs Acumatica Cloud ERP for finance and the general ledger. Before the integration, a bookkeeper exported Square sales and payout reports each week and keyed daily totals into Acumatica by hand, which meant the receivables and sales accounts lagged by days, location splits were often wrong, and refunds were missed at month-end. With Acumatica and Square connected, each day's payments and the invoices behind them post into Acumatica as AR invoices allocated to the branch for each location, and refunds post as credit entries. The sales and cash accounts reconcile on their own, the per-location books are accurate, and the weekly re-keying step is gone.

What you can do

  • Post Square payments and the invoices behind them into Acumatica as AR sales invoices and receivables.
  • Map each Square location to an Acumatica branch so sales land on the correct books.
  • Keep the Acumatica customer master aligned with Square buyers.
  • Authenticate Square with OAuth 2.0 bearer tokens and Acumatica with its tenant-specific login and endpoint version.
  • Trigger on HMAC-verified Square webhooks with payment-id dedup, polling backfill, retries, and a full audit trail.

Questions

Which direction does data move between Acumatica and Square?
The main flow is Square into Acumatica. Payments, refunds, the invoices and orders behind them, and customer records move from Square into Acumatica, where they post as AR sales invoices and receivables. Square has no chart of accounts, so the general ledger stays in Acumatica and ml-connector never writes ledger data back to Square.
Does Square push events, or does ml-connector poll Acumatica?
Both happen. Square pushes events such as payment.created and invoice.payment_made by webhook, which ml-connector verifies with HMAC-SHA-256 and returns 403 on a bad signature. Because Acumatica has no public webhook for finance records, ml-connector polls Acumatica on LastModifiedDateTime and uses that same poll to backfill any Square event that was missed.
How does the integration avoid duplicate postings in Acumatica?
Acumatica has no idempotency-key header, so ml-connector dedupes before it writes. It keys each posting on the Square payment or order id plus a BullMQ jobId, and it uses Acumatica PUT upsert so a re-read sale updates the existing record instead of creating a second one. Every posting is also recorded in the audit trail so a failed downstream call can be replayed safely.

Related integrations

Connect Acumatica and Square

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

Get started