01 / backbone
Kinetic is the ledger
Jobs, parts, available-to-promise, pricing, order management. The authoritative record the business is run on.
Integration / Makro Middleware
Epicor Kinetic ⇄ Shopify Plus Integration, Built to Fit · formerly Epicor ERP
Your ERP stays the system of record. Shopify Plus becomes where the order gets placed. We build custom Epicor Kinetic ⇄ Shopify Plus middleware for job-based inventory, BOM, B2B price tiers and orders.
The real problem
Jobs, parts, available-to-promise and pricing on one side, dealer and distributor self-serve on the other. The middle is where commerce breaks.
01 / backbone
Jobs, parts, available-to-promise, pricing, order management. The authoritative record the business is run on.
02 / front door
Where dealers and distributors place repeat orders without a phone call, a rep, or a faxed PO.
03 / the gap
Duplicate customers. Orders written twice. Pricing that drifts. Silent failures at month-end close.
Epicor ships no Shopify connector at all, so the manufacturing data model is left to a generic mapping tool. We built a product around that gap, and Epicor Kinetic plugs in as a mapped REST and BAQ adapter.
How we build it
Customers, parts, available-to-promise inventory and price tiers are read out of Kinetic and pushed to Shopify. The storefront never writes to the ledger. Orders are the only thing that travels both ways.
System of record
read · never overwritten
The platform
map · reconcile · audit
The storefront
where buyers self-serve
The 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 · OrderNum 10288 | PERMANENT · validation | 3 / 3 | held | Inspect |
| 07:55:22 | customer · CUST-00910 | TRANSIENT · timeout | 2 / 5 | 09:50 | Retry now |
| 06:40:11 | part · PN-44120 | RATE_LIMIT · license | 1 / 5 | paced | Inspect |
Every record carries three identities at once. The middleware reads this row before every write and decides create, update, or skip.
Kinetic has no idempotency key and no Shopify-external-ID column, so the middleware owns the map: Shopify GID against CustNum, OrderNum and PartNum. This is what stops duplicate customers and double-posted orders before they reach your ledger.
Change detection runs on the stored checksum, so a catalog of 50,000 parts with 12 real edits syncs 12 records, not 50,000.
entity key map · every id matched before write
Inside the platform
Ten engineered subsystems, one shared dataset. The same platform that runs in production for NetSuite, mapped to the Epicor Kinetic surface.
01 / 10
When a record fails
An order write to Kinetic fails on a license-concurrency penalty. It is classified before it is retried, and nothing disappears into a log file. Colour carries the verdict: amber is sorted, teal paces, red is held, green replays.
An order write to Kinetic fails on a license-concurrency penalty. Instead of disappearing into a log, it enters the pipeline.
capturedEvery failure is sorted before anything is retried, so a bad record never loops forever.
classifiedThe license penalty routes to a paced lane that reuses one session and bounds concurrency, automatically, until the burst clears.
retryingA validation failure routes straight to the dead-letter queue for review. It is never retried blindly, and a duplicate OrderNum is never written.
Fix the cause, replay from the queue. A daily reconciliation pass catches anything the live path missed.
replayed · reconciledThe failure modes no vendor page admits
Epicor ships no first-party Shopify connector, so every route is a generic mapping tool against a manufacturing data model. These are the points where job-based inventory, the price matrix and the customization layer break a fixed-mapping connector. A custom middleware layer is built to handle all of them, explicitly.
Epicor Commerce Connect (ECC) is built on Magento Community Edition and never mentions Shopify. Every Shopify route is third-party or custom. The real choice is a packaged connector versus purpose-built middleware, not a connector versus a build.
→ build on Kinetic REST v2, BAQs and Epicor FunctionsKinetic does not store an available-to-sell number, it is derived. Available equals OnHandQty minus AllocatedQty, and in a shop it depends on job status. Publish on-hand and you sell stock already committed to open production jobs.
→ available-to-promise from a BAQ, per warehouseReading the Part returns a unit price that ignores customer and customer-group lists, and no documented endpoint returns a single resolved customer price. The price is a layered, stacking cube that only evaluates at order-line entry.
→ wrap the pricing engine in a function, pre-compute B2B listsThe Kinetic part master carries revisions, BOMs, UOM conversions and configure-to-order structures that do not map to Shopify's flat product and variant model. The data model, not the API call, is where these projects succeed or fail.
→ map the part master and job structure before any endpointA UD field surfaces as a …_c field on full-row reads once the data model is regenerated, but GetList deliberately drops it. Build sync on GetList and Shopify receives blank custom attributes.
Epicor has no app-level rate limiting and no 429. The throttle is Web Service license concurrency, a 20-second penalty per call on a shared license. Shopify's side is the opposite, a hard 429 with Retry-After. One backoff policy cannot serve both.
→ self-throttle Kinetic, honor 429 on ShopifyWriting a Kinetic order is a multi-call dataset dance, each row carrying a RowMod flag. A recipe-based iPaaS runs these sequentially with partial-write risk, and the Jitterbit connector has no native Epicor Function activity at all.
→ one Epicor Function POST, all-or-nothing server-sideKinetic has no idempotency key. OrderNum is server-assigned on every create, so a retried POST writes a second sales order, and there is no native Shopify external-ID column on the standard tables.
→ dedupe on the Shopify order ID before create, own the ID mapClaims you can check
Every reality below is verified against a primary Epicor source, a named vendor doc, or attributed practitioner consensus. This is the difference between a team that read the marketing and a team that shipped against the documentation.
OnHandQty − AllocatedQty, and in a manufacturing shop available-to-sell depends on job status. Publish on-hand and you sell stock already hard-allocated to open jobs. The correct feed is a BAQ computing availability per warehouse from PartAlloc / PartBin.Part returns a unit price that does not account for customer or customer-group lists. Price is a layered cube (part base, base list, group list, customer list, quantity break, percentage discount) that stacks and only evaluates at order-line entry. Wrap the pricing engine in an Epicor Function and pre-compute B2B price lists.OrderNum is server-assigned on every create, so a retried POST creates a second sales order, and there is no native Shopify external-ID column. The middleware must own idempotency (dedupe on the Shopify order ID before create, then persist the returned OrderNum) and own the ID map.GetNewOrderHed → ChangeCustomer → ChangePartNum → MasterUpdate), each row carrying a RowMod flag. A recipe-based iPaaS runs these sequentially with partial-write risk, and the Jitterbit connector has no native Epicor Function activity at all. The clean pattern is one Epicor Function POST that collapses the chain server-side into an all-or-nothing transaction.…_c field on full-row reads (GetRows) once the data model is regenerated, but is deliberately absent from GetList. Build sync on GetList and Shopify receives blank custom attributes. Use GetRows or a BAQ. Adding a UD field is an ERP change, not a connector toggle.The decision guide
There is no first-party Epicor Shopify connector, so there are three real paths: no native option (Epicor Commerce Connect targets Magento, not Shopify), a third-party iPaaS or packaged connector, or a custom integration built on Kinetic's OData v4 REST API and Shopify's Admin API. The right choice depends on order volume, job-based inventory, B2B complexity and how customized the Kinetic install is. Note that Kinetic, Prophet 21 and ECC are different Epicor products: confirm which one you run before scoping.
Option 01
Epicor Commerce Connect is Epicor's commerce product, but it targets Epicor's own storefront and Magento / Adobe Commerce, not Shopify. There is nothing to turn on for Shopify.
Right for nobody on Shopify, the option exists only to rule it out.
Option 02
Subscription middleware and packaged tiles: Celigo, Boomi, MuleSoft, Commercient SYNC, StarfishETL, Codeless, and the Epicor-blessed Jitterbit / Workato.
Right for standard multi-system sync where the manufacturing logic fits a fixed-mapping template.
Option 03 our build
Built around your exact part master, job-based inventory and B2B logic, owned by you, operated with a support agreement. Where manufacturers and distributors end up.
Right for job-based inventory, configure-to-order and BOM products, the stacking price matrix, BPM-customized installs, or non-standard fulfillment a fixed-mapping connector cannot model.
How long it takes
An Epicor Kinetic ⇄ Shopify Plus build lands in one of three bands depending on B2B complexity, the part master depth, and how many of the break points above are in play.
Band 01 · foundation
single site · standard catalog
Band 02 · B2B
Shopify Plus B2B · price tiers
Band 03 · manufacturing
BOM / configure-to-order · multi-plant
We price an Epicor Kinetic 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, the industry reports an 8 to 14 week scope and iPaaS at roughly $40,000 to $80,000 setup plus monthly fees, cited as industry-reported context, never as our quote. 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
Epicor and Shopify secrets are held as encrypted fields, isolated per tenant and rotatable without downtime. The OAuth client secret and API key never sit in plaintext, anywhere.
Every Shopify webhook is HMAC-verified before it is trusted, then deduplicated by event id, so a replayed webhook cannot create a second order.
OAuth 2.0 client-credentials against the Epicor IdP on Cloud (a ServerToServer client) or a bearer token on on-prem, an API key on every v2 call, and a dedicated least-privilege service user, never an admin login.
An append-only audit trail logs every operation, source-tagged, so you can prove what happened during month-end close.
Frequently asked questions
The details that separate a team that read the docs from a team that shipped against them. Open any one.
GetList, which deliberately drops UD fields, so we build on GetRows or a BAQ. Adding a UD field is an ERP change to scope into the plan, not a connector toggle.The framework underneath
Every ERP sits behind the same contract: authenticate, fetch master data, push orders, validate, report. The sync engine, mapping layer, error handling and Shopify integration never change when a new system plugs in. NetSuite runs on that framework in production today. Epicor Kinetic is a registered target on the same platform, its path mapped to REST v2, BAQs and Epicor Functions.
We say this plainly: the credibility is a real platform and a precisely mapped Kinetic path, not a decade of Kinetic traffic. That distinction is exactly what your architect can verify, which is why we lead with it.
Proof and outcomes
Clarius · NetSuite + Salesforce + Shopify PlusCapability proof, on NetSuite, not Epicor. We built a unified account page integrating Clarius' NetSuite ERP, Salesforce CRM and Shopify Plus into a single view of customer information, orders and invoices, and used Shopify Flow automation feeding order data into NetSuite to keep the platforms in sync. It is proof Makro runs real ERP to Shopify Plus middleware in production. The Epicor Kinetic path is the mapped extension of that same platform.
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 Kinetic environment, your part master, and the three sharp questions you already have.