01 / backbone
Sage 100 is the ledger
Finance, inventory, pricing, order management. The authoritative record the business is run on.
Integration / Makro Middleware
Custom middleware between Shopify Plus and Sage 100. Your ERP stays the system of record. Shopify Plus becomes where the order gets placed.
The real problem
Finance, inventory, pricing and order management on one side, B2B buyer self-serve on the other. The gap between the ERP and the storefront is where commerce breaks: duplicate customers, orders written twice, pricing that drifts, silent failures at month-end close.
01 / backbone
Finance, inventory, pricing, order management. The authoritative record the business is run on.
02 / front door
Where B2B buyers place repeat orders without a phone call, a rep, or an EDI batch.
03 / the gap
Duplicate customers. Orders written twice. Pricing that drifts. Silent failures at month-end close.
We built a product around that exact gap. For Sage 100 the path is fully mapped, and it plugs into the platform as an adapter.
How we connect Sage 100 to Shopify Plus
Customers, products, inventory and pricing are read out of Sage 100 and pushed to Shopify. The storefront never writes to the ledger. Orders are the only thing that travels both ways, and Sage 100 stays the system of record.
System of record
read · never overwritten
The platform
map · reconcile · audit
The storefront
where buyers self-serve
SO_SalesOrder_bus and its peers. Every order writes through Sage's own validation and posting logic, server-resident on the Sage 100 host where ProvideX is installed.MK → Sage 100UDF_ field, and the order is written exactly once.Shopify ↕ Sage 100The console
Every sync, every failure, every reconciliation is visible. This is the same Makro Middleware console your team would watch in production. Move through the views.
| Time | Entity | Error class | Attempts | Next | Action |
|---|---|---|---|---|---|
| 08:13:04 | order · #SO-10288 | PERMANENT · validation | 3 / 3 | held | Inspect |
| 07:55:22 | customer · 01-CASCWEST | USER_LIMIT | 2 / 5 | 09:50 | Retry now |
| 06:40:11 | item · 99320-A | TRANSIENT · timeout | 1 / 5 | paced | Inspect |
Every record carries three identities at once. The Sage 100 key is a composite business key, ARDivisionNo plus CustomerNo, and the middleware reads this row before every write to decide create, update, or skip.
Sage 100 has no native external-ID field and the BOI does not deduplicate, so the platform stamps the Shopify id into a UDF field and keeps a sync ledger keyed by Shopify id. A redelivered webhook writes exactly one Sage document, never two.
Change detection runs on the stored checksum, so a catalog of 50,000 items with 12 real edits syncs 12 records, not 50,000.
entity key map · every id matched before write
Inside the platform
Ten engineered subsystems sit between Sage 100 and Shopify Plus. None of them is a setting you toggle. Each is something we built, and something your team can watch run.
01 / 10
When a record fails
Instead of disappearing into a log, every failure is classified before it is retried. Colour carries the verdict: amber is sorted, teal retries, red is held, green replays.
A record fails to write to Shopify or Sage 100. Instead of disappearing into a log, it enters the pipeline.
capturedEvery failure is sorted before anything is retried. A BOI validation reject is held, a User Limit Exceeded error is paced.
classifiedA User Limit Exceeded error backs off and pools the BOI and ODBC connections until a seat frees, then retries on its own.
retryingA BOI validation reject, like a Shopify customer missing a field Sage requires, routes to the dead-letter queue. Never retried blindly or lost.
held for reviewFix the cause, replay from the queue. A daily reconciliation pass catches anything the live path missed.
replayed · reconciledThe failure modes no vendor page admits
Sage 100 has no native REST API, so a Sage 100 ⇄ Shopify integration is only as good as the middleware engineered behind it. Templated connectors handle the happy path and skip these. A custom layer is built to handle all of them, explicitly.
Some connectors write the ProvideX or SQL tables directly to look fast. That silently bypasses the business logic that keeps the books correct. A correct build commits every write through the Business Object Interface and recovers speed with queuing and batching it controls, not by skipping validation.
→ every write through BOI, never raw tablesThe BOI does not deduplicate, Sage has no native external-ID field, and Shopify delivers webhooks at least once. A retry or redelivered webhook re-creates the Sage order unless the integration owns dedupe. We stamp the Shopify id into a UDF field and keep a sync ledger keyed by Shopify id.
→ idempotency ledger + Shopify-id UDFSage's raw Available field is configurable and can fold in not-yet-received PO stock, and Shopify owns the committed state itself, which you cannot set through the Admin API. Push Sage Available to Shopify available and you double-count every open order. We sync buffered physical stock, per warehouse.
→ buffered physical stock, per warehouse to locationUDFs are fully supported but not auto-discoverable. There is no introspection endpoint. Every UDF must be created in Custom Office and mapped by its exact UDF-prefixed name, with a trailing dollar sign for strings. Get it wrong and the field silently fails to map. Budget a field-discovery workstream.
→ explicit UDF discovery + name-exact mappingStandard Sage 100 on ProvideX operates with a single base currency. True multi-currency transacting requires the DSD Multi-Currency enhancement. A Shopify Plus store selling in several presentment currencies cannot assume Sage holds prices per currency, so we handle it with the add-on or in middleware.
→ DSD add-on or middleware FX handlingSage 100 has no standalone fulfillment object, and refunds route through the RMA module to a credit memo. But RMA is a separately licensed module, so not every site has it. A Shopify refund may instead need to land as a posted AR credit memo. We confirm the module exists before assuming the path.
→ RMA credit memo, AR credit memo fallbackThe BOI is COM and historically 32-bit, and Sage 100 v2026 is 64-bit-only. 32-bit and 64-bit cannot coexist, so third-party integrations have to be rebuilt in 64-bit. The integration is an owned, versioned, maintained asset, not a set-and-forget license. We scope it 64-bit-ready.
→ 64-bit-ready build, maintained through upgradesClaims you can check
Every reality below is verified against a primary Sage source, a named vendor doc, or Shopify's own documentation. This is the difference between a team that read the marketing and a team that shipped against the documentation.
SO_SalesOrder_bus object, or to re-implement the whole hierarchy in middleware and validate it against Sage's invoice.UDF_ field and keep a sync ledger keyed by Shopify id, so a redelivered webhook is a no-op.UDF_-prefixed name, with a trailing dollar sign for strings. Get it wrong and the field silently fails to map. Budget a field-discovery and mapping workstream, not a one-click sync.The decision guide
There are three ways to connect Shopify to Sage 100: an off-the-shelf connector app, a middleware or iPaaS platform, and a custom-built integration maintained by a development agency. The right choice depends on order volume, B2B complexity, and how many non-standard rules Sage 100 carries.
Option 01
A packaged app over the BOI on a Windows host. Low cost, fixed field mappings, competent on a standard B2C happy path.
Right for standard B2C order and inventory sync, with no customer-specific price levels or custom fields.
Option 02
Subscription middleware on a shared platform. Strong for standard multi-system sync across templated connectors.
Right for standard multi-system sync where Sage's rules fit a fixed-mapping template.
Option 03 our build
Built around your exact order flow and Sage 100 rules, owned by you, operated with a support agreement. Where Plus and B2B merchants end up.
Right for Sage 100 with non-standard rules: kitting and BOM, multi-warehouse allocation, customer-specific price levels, EDI, or approval workflows a templated field map cannot express.
Timeline and what drives scope
A Sage 100 ⇄ Shopify Plus build lands in one of three bands depending on B2B price-level complexity, the size and shape of the item master, and how many of the break points above are in play.
Band 01 · foundation
standard catalog · core sync
Band 02 · B2B
Shopify Plus B2B · UDFs
Band 03 · complex
RMA · multi-currency · 64-bit
We price a Sage 100 integration as an engineering engagement: a build with a support agreement, not a per-record meter or a platform seat that renews forever. For context, off-the-shelf connector apps start from roughly $99 a month and grow with volume, while a custom build is a one-time scoped engagement that removes per-order and volume fees and owns the data-mapping logic. Your exact figure is scoped to the band and the break points in play, and we put it in writing before anything starts.
Security posture
The Sage 100 service-user password and Shopify secrets are held as encrypted fields, isolated per tenant and rotatable without downtime.
vaulted · per-tenantEvery Shopify webhook is HMAC-verified before it is trusted, then deduplicated so a replay cannot create a second order.
HMAC · replay-safeSage 100 has no OAuth or token, so the integration runs as a named service user scoped in Role Maintenance, with ODBC Security enabled and scoped as a separate gate.
named user · Role Maintenance · ODBC SecurityAn append-only audit trail logs every operation, source-tagged, so you can prove what happened during close.
append-only · source-taggedFrequently asked questions
The details that separate a team that read the docs from a team that shipped against them. Open any one.
SO_SalesOrder_bus object to read the calculated price, or re-implement the hierarchy in middleware and validate it against Sage's invoice. Then we flatten Sage Price Levels into Shopify Plus B2B catalogs and price lists.The framework underneath
Every ERP sits behind the same contract: authenticate, fetch master data, push orders, validate, report. The platform runs in production today against NetSuite. Sage 100 is a registered target on that same framework, its path fully mapped to the BOI for writes, ProvideX ODBC for reads, a named service user, and the poll-stage-queue pattern.
We say this plainly: the credibility is a real platform and a precisely understood Sage 100 path, not a decade of Sage 100 traffic. That distinction is exactly what your architect can verify, which is why we lead with it.
Proof and the engineering standard
Clarius · enterprise ERP + Shopify PlusWe built a unified account page integrating Clarius' NetSuite ERP, Salesforce CRM and Shopify Plus into a single view of customer information, orders and invoices across three enterprise systems. Combined with Shopify Flow automation feeding order data into NetSuite, it eliminated manual order entry and reduced operational costs by over $100,000 a year. Evidence of our enterprise-ERP and Shopify Plus integration competence, the same standard the Sage 100 path is built to.
Automated tests across 139 suites, run on every change. No code reaches your production data without passing them.
Coverage gate enforced before any deploy.
End-to-end browser tests, across Chromium, Firefox and WebKit.
Failure classes, each with its own pre-decided policy.
Credentials stored in plaintext, anywhere, ever.
A real conversation about your Sage 100 environment, your data, and the three sharp questions you already have.