ml-connector
Sage IntacctStripe

Sage Intacct and Stripe integration

Sage Intacct handles your accounting, AR ledger, and financial reporting. Stripe handles online payments and subscriptions from your customers. Connecting the two keeps your AR records in Sage Intacct aligned with the actual payments received in Stripe. Invoices created in Stripe sync into Intacct as AR documents, refunds flow the opposite direction into your GL, and payment confirmations close invoices without manual entry. ml-connector handles the very different APIs on each side and moves the data on a schedule you control.

How Sage Intacct works

Sage Intacct exposes vendors, GL accounts, AP bills, AP payments, dimensions (departments, locations, cost centers), and general ledger through a single XML gateway endpoint at https://api.intacct.com/ia/xml/xmlgw.phtml over HTTPS POST with application/xml Content-Type. Authentication is session-based: an initial call exchanges senderId, senderPassword, companyId, userId, and userPassword for a sessionid valid for 50 minutes, then cached and refreshed automatically on timeout. All operations serialize through the single XML endpoint. HTTP 200 responses may contain application-level errors in errormessage tags, so responses must be parsed carefully. Intacct has no native webhook system; all data flows are polling-driven or manual.

How Stripe works

Stripe exposes customers, invoices, payments, charges, subscriptions, refunds, and balance transactions through a REST API at https://api.stripe.com/v1 with stable GET, POST, and DELETE verbs and JSON responses. Authentication is API Key (secret key sk_live_ for production, sk_test_ for sandbox) sent via HTTP Basic Auth or Bearer token. Stripe delivers real-time event notifications via webhooks to a registered HTTPS endpoint with HMAC-SHA256 signature validation (Stripe-Signature header), at-least-once delivery, and a 5-minute replay window. Webhook events include payment_intent., invoice., customer., charge., and refund. events. Stripe is read-write for invoices and customers but read-only for balance transactions and completed charges.

What moves between them

Data flows primarily from Stripe into Sage Intacct. Stripe invoices are read via webhook events and polled on a schedule, then written into Intacct as AR invoices mapped to the customer in Intacct and GL accounts determined by invoice line items and dimensions. Stripe payments are read via charge.succeeded and payment_intent.succeeded events and recorded as AR payments in Intacct applied to matching invoices. Refunds are read from Stripe and posted as GL credits to the original revenue account. Customer records flow from Stripe into Intacct as AR customers with billing address mapped to dimension values. Dimension mappings (location, customer segment) are controlled per customer to ensure GL postings land on valid Intacct dimensions.

How ml-connector handles it

ml-connector stores Stripe and Intacct credentials encrypted, with Stripe API Key sent via HTTP Basic Auth on each request and Intacct session refreshed automatically after 50 minutes via the XML gateway. On the Intacct side, it manages XML serialization and parsing, strips forbidden C0 control characters before escaping entity references, and checks every HTTP 200 response for application-level errormessage tags. Stripe webhook events are validated using the Stripe-Signature HMAC, and events are deduplicated by Stripe event id. Intacct does not have native idempotency; ml-connector uses the XML control block uniqueid flag for server-side deduplication on retried operations. Invoices from Stripe are mapped to Intacct GL accounts by revenue category, and customers are mapped to Intacct dimensions (location, department, business unit) so that AR records land on valid GL and cost allocation dimensions. Rate limiting and timeouts on both sides trigger exponential backoff and retry. Every record carries a full audit trail and can be replayed if a call fails.

A real-world example

A B2B SaaS company uses Sage Intacct for their general ledger and AR, and uses Stripe to invoice customers and accept online payments. Before the integration, the finance team exported payment data from Stripe weekly, manually matched it to open Intacct invoices, and posted the payments in Intacct by hand, which often took two days and created reconciliation gaps if the timing of the export and the payment posting did not match. With Sage Intacct and Stripe connected, each Stripe payment is automatically recorded as a payment application in Intacct against the matching invoice the moment it arrives, customer records are kept in sync, and the AR aging is live and accurate. The manual payment posting step is gone, and reconciliation happens in minutes.

What you can do

  • Sync Stripe invoices into Sage Intacct as AR documents mapped to the correct customer and GL revenue account.
  • Record Stripe payments and refunds as AR applications and GL credits in Intacct without manual entry.
  • Validate Stripe webhooks using HMAC-SHA256 and deduplicate by event id to prevent duplicate postings.
  • Manage Sage Intacct's 50-minute XML session lifecycle automatically, refreshing on timeout and retrying if the endpoint is temporarily unreachable.
  • Map Stripe customers and invoice dimensions to Intacct GL accounts and dimensions so AR and revenue postings land on valid accounts.

Questions

Which direction does data move between Sage Intacct and Stripe?
The main flow is Stripe into Sage Intacct. Stripe invoices, customers, and payments flow into Intacct as AR documents and payment applications. Refunds flow from Stripe into Intacct as GL credits to the original revenue account. Dimension mapping (location, business unit) is controlled in both systems so AR records allocate correctly.
How does ml-connector handle Sage Intacct's XML gateway and session expiry?
ml-connector sends all Intacct operations as XML over HTTPS POST to the single gateway endpoint. It manages the 50-minute session lifecycle: caching the sessionid after the initial getAPISession call and automatically refreshing it on timeout. It also parses HTTP 200 responses for application-level errormessage tags and strips forbidden C0 control characters before XML serialization to avoid errors.
How are Stripe webhooks validated and duplicates prevented?
ml-connector validates every Stripe webhook using the Stripe-Signature HMAC-SHA256 header and rejects any with an invalid signature. It deduplicates by Stripe event id so that retried webhooks do not create duplicate AR records. For Intacct operations, it uses the XML control block uniqueid flag for server-side deduplication on retries.

Related integrations

Connect Sage Intacct and Stripe

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

Get started