ml-connector
Sage IntacctSPS Commerce

Sage Intacct and SPS Commerce integration

Sage Intacct runs accounting, finance, and supply chain operations. SPS Commerce connects you to retail trading partners via EDI. When these two systems are connected, purchase orders and fulfillment data from trading partners flow into Sage Intacct automatically, creating vendor bills and GL postings without manual entry. ml-connector translates between Sage Intacct's XML gateway and SPS Commerce's REST API, keeping both systems in sync.

How Sage Intacct works

Sage Intacct is a cloud-based ERP and accounting system that exposes vendors, purchase orders, invoices, payments, GL accounts, cost centers, and dimensions through a single XML gateway endpoint at https://api.intacct.com/ia/xml/xmlgw.phtml. It uses session-based authentication: an initial getAPISession call exchanges a senderId, senderPassword, companyId, userId, and userPassword for a sessionid cached for 50 minutes. Intacct has no webhook system, so all data is read by polling. HTTP 200 responses may contain application-level errors in XML error tags, not HTTP status codes, so the response body must be parsed. Sessions are automatically refreshed when they expire.

How SPS Commerce works

SPS Commerce is a cloud-based EDI network platform that abstracts legacy EDI standards like X12 and EDIFACT and exposes transaction data via a REST API with JSON request and response bodies. All documents are wrapped in an RSX 7.7.7 JSON envelope format. Authentication uses OAuth 2.0 client credentials flow: POST client credentials to https://api.spscommerce.net/authorization/v1/token and include the returned JWT bearer token in all API calls. SPS Commerce supports polling-based integration via its /fulfillment/v1/purchaseorders endpoint with cursor-based pagination. Trading partner IDs are provisioned during onboarding and are not discoverable via API.

What moves between them

Purchase orders, invoices, and advance ship notices flow from SPS Commerce into Sage Intacct. ml-connector polls SPS Commerce at regular intervals for inbound purchase orders and fulfillment records from trading partners, unwraps the RSX envelope, translates the EDI transactions into Sage Intacct vendor bills and GL line items, and posts them to the correct vendor, GL account, and cost center in Intacct. Outbound documents such as invoices and acknowledgments are pushed from Sage Intacct to SPS Commerce immediately when an ERP event occurs, wrapped in RSX format for delivery to trading partners.

How ml-connector handles it

ml-connector maintains separate OAuth tokens for SPS Commerce and Sage Intacct sessions. For Sage Intacct, it caches the 50-minute sessionid and refreshes it on the next poll if expired, parsing the XML response body for application-level errors rather than relying on HTTP status alone. For SPS Commerce, it refreshes the OAuth bearer token when a call returns 401, and handles cursor-based pagination by storing the opaque Base64 cursor from each response. Trading partner IDs and vendor mappings are stored during setup so incoming purchase orders from a retailer land on the correct Intacct vendor and cost center. SPS rate limits are not publicly documented, so ml-connector implements exponential backoff with jitter on 429 responses. Because both Sage Intacct and SPS Commerce lack native idempotency, ml-connector deduplicates at the application layer using the purchase order number or invoice number. All records carry a full audit trail and can be replayed if a downstream call fails.

A real-world example

A wholesale distributor running Sage Intacct for accounting and procurement receives purchase orders from major retail partners through SPS Commerce, which handles EDI translation. Before integration, the procurement team received EDI orders via SPS, printed or copied them, and manually keyed vendor bills into Sage Intacct by hand, a process that took 2-3 days per week and introduced data entry errors. With Sage Intacct and SPS Commerce connected, each incoming purchase order and fulfillment update from a trading partner flows directly into Intacct as a vendor bill on the correct cost center, and outbound invoices and shipment confirmations post back to SPS for delivery to the retailer. Manual entry is eliminated, data is consistent across both systems, and fulfillment cycles complete in hours instead of days.

What you can do

  • Receive purchase orders and fulfillment documents from SPS Commerce trading partners and post them as vendor bills in Sage Intacct, mapped to the correct vendor, GL account, and cost center.
  • Translate EDI documents wrapped in SPS Commerce RSX format into Sage Intacct XML transactions, handling envelope unwrapping and field mapping automatically.
  • Authenticate Sage Intacct via session-based XML gateway credentials and SPS Commerce via OAuth 2.0 client credentials, refreshing both when needed.
  • Poll SPS Commerce for inbound purchase orders at regular intervals and push outbound invoices and acknowledgments to SPS immediately when created in Sage Intacct.
  • Deduplicate purchase orders and invoices at the application layer, handle SPS rate limits with exponential backoff, and maintain a full audit trail on every transaction.

Questions

How does ml-connector handle the different authentication methods between Sage Intacct and SPS Commerce?
ml-connector stores both credential sets encrypted and maintains them separately. For Sage Intacct, it calls getAPISession once with senderId, senderPassword, companyId, userId, and userPassword, and caches the returned sessionid for 50 minutes, refreshing automatically when it expires. For SPS Commerce, it posts client credentials to the OAuth token endpoint, stores the JWT bearer token, and refreshes it when an API call returns 401. Both flows are transparent to the user.
Why does ml-connector poll SPS Commerce rather than receive webhooks?
SPS Commerce has a webhook framework still under development, so the recommended and stable pattern is polling at regular intervals (typically 5-15 minutes). ml-connector polls the /fulfillment/v1/purchaseorders endpoint and uses cursor-based pagination to track position across requests. This approach is reliable for both inbound orders and outbound document pushes.
How are purchase orders from multiple trading partners routed to the correct vendor in Sage Intacct?
Trading partner IDs are provisioned in SPS Commerce during onboarding and are not discoverable via API. ml-connector stores the mapping from each SPS trading partner ID to the corresponding Sage Intacct vendor and cost center during setup. When a purchase order arrives from a trading partner, ml-connector looks up the vendor mapping and posts the bill to that vendor and cost center, so different retailers automatically land on the correct GL accounts and dimensions.

Related integrations

Connect Sage Intacct and SPS Commerce

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

Get started