Integration and data model
Connecting an ERP to Shopify: ownership, patterns, operations
Integration & data model · Updated
In short
An ERP integration with Shopify lives or dies by one question: which system holds the truth for which object. Once that is decided per object, direction, integration pattern and sync mode follow almost by themselves. Products, inventory and prices usually come from the ERP, orders originate in Shopify, and customer data is the contested case in nearly every project.
This guide explains the decision logic that applies to any ERP — not the configuration of one specific product or connector.
Contents
- Which system holds the truth for which object?
- How do you derive ownership from the process?
- Which integration pattern will carry your setup?
- When do you sync on events and when on an interval?
- Why does every transfer have to be repeatable?
- How do you notice that an interface has gone quiet?
- Which mistakes cost the most time in ERP projects?
- In which order do you build the integration?
Which system holds the truth for which object?
Data ownership means that for every object exactly one system holds the value that counts when the two disagree. Without that decision both sides write the same field and the last write wins, not the correct one. Most so-called sync problems are unresolved responsibilities rather than technical faults.
The answer is decided per object, not per system. An ERP can own the product master and inventory and still have nothing to say about product descriptions. Shopify can own orders and still not issue the document numbers that accounting relies on. Both at once is the normal case, not the exception.
Two questions settle almost every individual case: who creates the object, and who corrects it when something is wrong. If a refund is booked in accounting, it belongs in the ERP. If it is triggered in the Shopify admin, Shopify has to own it and the ERP follows the movement.
| Object | Direction | Leading system | What matters |
|---|---|---|---|
| Products | ERP → Shopify | ERP | Master data only, marketing copy stays in the store |
| Inventory | ERP → Shopify | ERP | Map warehouses cleanly onto Shopify locations |
| Prices | ERP → Shopify | ERP | Customer-specific prices need their own logic |
| Orders | Shopify → ERP | Shopify | Transfer idempotently, agree number ranges first |
| Customers | Both ways | Split by field | Account in the ERP, login and consent in Shopify |
| Fulfillments | ERP → Shopify | ERP | Write back tracking numbers and partial shipments |
| Credit notes | ERP → Shopify | ERP | Rule out double refunds technically |
How do you derive ownership from the process?
Whoever creates an object usually owns it. Products originate in purchasing, so in the ERP. Orders originate in the checkout, so in Shopify. Customer accounts originate at both ends — which is why this one object is where the discussion starts in almost every project.
The second question is the harder one: who corrects things when they are wrong. If accounting fixes a wrong billing address in the ERP and that change never reaches Shopify, the store keeps working with the old state. Whoever corrects data must be allowed to write it, otherwise the correction has no effect.
For shared objects it helps to cut ownership at field level rather than object level. On the customer, the ERP owns the account number, payment terms and credit limit, while Shopify owns the login, newsletter consent and the addresses on the account. Each side writes only its own fields and leaves the others untouched.
Questions to answer per object before you build
- Who creates the object, and can it appear in two places at the same time?
- Who corrects it when it is wrong, and does that system have write access there?
- Which fields belong to the object but to a different leading system?
- What happens in business terms if both sides change the same field at once?
Which integration pattern will carry your setup?
Four patterns show up in practice: a native connector from the ERP vendor, an iPaaS platform, custom middleware, and a direct coupling through both APIs. The choice depends less on budget than on how far your processes deviate from the standard and who operates the integration after launch.
A connector is the fastest route as long as your processes match the standard. As soon as customer-specific prices, multiple warehouses or your own order logic enter the picture, that standard ends. The real question then is whether the connector can be extended at that point or whether you have to bypass it there.
One question decides more often than the technology: who picks up the phone on Monday morning when no orders have reached the ERP since Friday. Where there is no clear answer, the pattern with the largest custom-built share is usually the wrong one, even when it fits best on paper.
Patterns and their trade-offs
- Native connector: live quickly and with little effort, but you are tied to the vendor scope and release cycle.
- iPaaS platform: visible flows, monitoring and retries out of the box, in exchange for running costs and another platform to operate.
- Custom middleware: full control over mapping and error handling, but you need someone to maintain it for years.
- Direct API coupling: few moving parts in simple cases, but without a buffer layer every ERP maintenance window hits the store immediately.
When do you sync on events and when on an interval?
Event-driven means a transaction triggers a transfer immediately, usually through webhooks. That suits everything that has to be fast — an order into the ERP, an inventory change after a sale. The price is that you have to handle lost and duplicated events yourself.
Interval syncs run at fixed intervals and pick up everything that changed since the last run. That is more robust against outages and easier on API quotas, but it costs freshness. For the product master and prices it is almost always enough; for inventory on scarce goods it often is not.
The nightly full reconciliation is the safety net. It compares both sides completely and reports what drifted apart during the day. Without it, nobody notices that a handful of products have carried a wrong stock level for weeks. With it, the discrepancy is a morning report instead of a later complaint.
What each mode is good for
- Event-driven: orders, payments and stock decrements — anything where minutes matter commercially.
- Interval: product master, prices and shipping status — anything where a lag of minutes has no consequences.
- Nightly full run: reconcile inventory and prices, report discrepancies instead of overwriting them silently.
Why does every transfer have to be repeatable?
Every interface eventually sends the same message twice. A timeout, a restart, a redelivered webhook — you cannot prevent that, only absorb it. Idempotency means the second run produces the same result as the first and does not create a second order in the ERP.
Technically this rests on a business key stored on both sides: the Shopify order number as a reference on the ERP order, the ERP document number as a metafield on the order. Before every write the interface checks whether that key already exists. Only when it is missing does it create anything.
Retries need spacing. A failed call repeated immediately and endlessly burns your API quota and hides the actual cause. The common approach is a few attempts with growing intervals; after that the transaction lands in a visible error queue rather than disappearing.
How do you notice that an interface has gone quiet?
The most dangerous state of an integration is not a crash but silence. A process that transfers nothing and throws no error is often noticed only when someone complains. That is why you monitor not just errors but also the absence of successful transfers.
Errors need a destination. A transaction that fails after all attempts belongs in a visible queue with payload, timestamp and error message — not in a log line nobody reads. From that queue a single transaction has to be replayable without repeating the entire run.
It helps to separate business errors from technical ones. A missing variant mapping is a data problem and needs a human. A timeout is a technical problem and usually resolves on the next attempt. Pour both into the same channel and people will soon ignore both.
What you monitor
- Timestamp of the last successful transfer per object, not just per interface.
- Length of the error queue and how it has grown over the last few hours.
- Missing runs: no transferred order on a weekday morning is an alert.
- Result of the nightly reconciliation as a count of discrepancies, not as a success message.
Which mistakes cost the most time in ERP projects?
The expensive mistakes are rarely exotic. They almost always come from a model being cut finer or coarser in the ERP than in Shopify, so something is lost in the mapping. Naming those spots before you build saves you from hunting for them in live operations.
Errors that move money are the nastiest. A refund executed twice goes unnoticed by everyone except accounting at month-end close. That is exactly why every money-moving transaction belongs behind a key that blocks the second execution, instead of relying on careful handling.
Where things regularly go wrong
- Inventory across warehouses: Shopify counts per location, many ERPs carry one total — you have to define the split.
- Variant mapping: Shopify allows three option dimensions per product, ERP article attributes are often more numerous.
- Customer-specific prices: price lists and volume tiers cannot be represented as a plain product price.
- Double refunds: a cancellation in the ERP and a refund in the store create two postings without a shared key.
- Rate limits: a full reconciliation during peak hours throttles exactly the calls the store needs right then.
In which order do you build the integration?
The sequence follows the risk. What has no effect on money and customers comes first, what creates postings when it fails comes last. That way you build confidence in data quality before the interface triggers transactions somebody has to reverse by hand.
Not every brand needs the full programme. With few orders a day and a manageable assortment, an orderly manual handover is often cheaper than an integration that wants to be operated. The maths flips as soon as duplicate maintenance produces errors instead of merely costing time.
A sequence that has proven itself
- Write down the object list and the ownership decision for each object.
- Build the product master and variant mapping, then verify it with real data.
- Connect inventory, first read-only alongside the live system, and compare.
- Add prices and price lists, including the customer-specific cases.
- Transfer orders to the ERP idempotently once they are completed in Shopify.
- Write back fulfillments and credit notes, then switch monitoring on properly.
FAQ
Frequently asked questions
Does every Shopify ERP integration need middleware?
No. If your processes match the standard and a maintained connector exists, the extra layer is unnecessary effort. Middleware pays off as soon as you have to reshape data, serve several systems, buffer transactions or replay failures selectively. The trigger is almost never data volume but the number of special cases nobody can express within the standard.
Which system should own inventory?
In most setups the ERP, because goods receipts, returns and corrections are booked there and because the same stock supplies other channels too. Shopify receives the value and decrements it on sale. If Shopify owns inventory itself, you need a clear rule for how goods receipts and stocktaking corrections come back from the warehouse.
How often should inventory be synchronised?
As often as your cost of error demands. With deep stock and slow turnover an interval of a few minutes is enough. With scarce goods, limited drops or campaigns you need event-driven updates, otherwise you sell products that no longer exist. In both cases a nightly full reconciliation stays useful because it makes drift visible.
What happens to orders when the ERP is unreachable?
The checkout must not notice at all. Orders are created in Shopify and transferred afterwards, not during. If the ERP goes down, transactions collect in a queue and catch up once it is back. The only thing that matters is that the catch-up is idempotent, otherwise a maintenance window produces duplicate orders.
How do you handle customer-specific prices in B2B?
Not as an overwritten product price, but through the price list and catalog mechanics Shopify provides for B2B. The ERP stays the leading system for the terms, and Shopify receives them as a list per customer group or company. Individual per-customer prices are the point where many standard connectors end and custom logic becomes necessary.
Can Shopify be the leading system for products?
Yes, if Shopify is your only channel and products are created in marketing rather than purchasing. As soon as purchasing, the warehouse or accounting need to create articles themselves, or a second channel appears, that becomes untenable. A workable middle ground is split ownership: master data from the ERP, descriptions, media and categories from Shopify or a PIM.
Official documentation
Primary sources for the technical statements in this guide.
Keep reading
Related guides
One more thing
We build and operate integrations like this at NICCOS on a regular basis. The work almost never starts with the interface, but with the object list and the question of who corrects things when they go wrong.
What we do