Skip to content
SyncMyShop

Notes

What not to sync between a store and an ERP

Sync what the business transacts on: orders placed after go-live, stock, fulfillments, and the customer and item keys that join them. Closed historical orders, values one system calculates, payment data and content the store owns stay where they are, because every synced field is a rule that has to keep working for as long as the integration runs.

Updated

The short answer

Sync the data both systems transact on and nothing else: orders from go-live onward, stock, fulfillments and tracking, and the customer and item keys that let the two systems find each other's records. Everything else has an owner, and it stays with its owner.

Data Default Why
Orders placed after go-live Store to ERP Revenue, picking, invoicing
Stock per location ERP or WMS to store What can be sold
Fulfillments and tracking ERP or WMS to store The customer sees the shipment
Customer and item keys Both ways, once per record Joins orders to accounts and items
Orders closed before go-live Stay in the source Already posted; still readable there
Tax totals, available quantity, average cost One way, from the system that calculates them Two calculations disagree
Card numbers, passwords Never Neither system needs them
Descriptions, SEO fields, collections Owned by the store after the first load Written and checked there

The list is short on purpose. Each row is a set of mapping rules, and each rule is checked on every record of every run.

Every synced field is a rule that runs forever

A field in the integration is more than a column. It is a mapping rule, a validation, a test case, and one more thing to check when either side changes its API. Shopify releases a new API version every quarter and supports each one for at least 12 months. In version 2026-10 the variant field barcode is marked deprecated in favor of barcodes, a list of up to 20 typed barcodes. An integration that writes barcode has to be changed before that field goes away; one that never mapped barcodes has nothing to change.

The same count applies on the ERP side. NetSuite's item record has hundreds of fields, and most of them are planning, costing and accounting fields: autoreorderpoint, costingmethod, cogsaccount. A store needs a handful. Mapping 12 fields means 12 rules to keep working; mapping 60 because they were available means 60, and the 48 extra are the ones nobody looks at until one of them breaks a run.

A field that turns out to be needed later is added as one rule plus a single backfill run over the existing records. That is cheaper than carrying an unused field for years.

Which items to send: not the whole item master

An ERP holds every item the company ever bought, sold, phased out or set up for a single quote. The store needs the ones it sells. NetSuite marks those with the checkbox isonline (Display in Web Store); isinactive hides an item from lists. Exact Online has IsWebshopItem on its items. The filter belongs in the query that reads the ERP:

SELECT id, itemid, upccode, displayname
FROM item
WHERE isonline = 'T'
  AND isinactive = 'F'

A worked example. A distributor's NetSuite account has 620,000 item records: 318,000 inactive, 265,000 active but not marked for the web store, and 37,000 with isonline checked.

Which NetSuite items reach Shopify Of 620,000 NetSuite item records, 318,000 are inactive and 265,000 are not marked for the web store; 37,000 go to Shopify. Sent without a filter, the last 120,000 of the 620,000 run into Shopify's limit of 10,000 new variants a day and take 12 days. NetSuite item records, filtered on isonline and isinactive 620,000 Inactive 318,000 Active, not in web store 265,000 Web store 37,000 Sent to Shopify 37,000 All item records sent to a store below Plus 620,000 Created, no daily cap 500,000 10,000 a day 120,000 Time for the last 120,000 12 days
Filter on the ERP side: 37,000 items instead of 620,000, and no variant throttle.

Sent without a filter, all 620,000 become Shopify variants. Shopify's resource limit applies once a store has 500,000 variants: from then on at most 10,000 new variants a day can be created, on any API, on plans below Plus. The last 120,000 items take 120,000 / 10,000 = 12 days, and every product created in those 12 days waits in the queue. With the filter, 37,000 items go over and the limit never comes into play. The same arithmetic applies to every later run: a nightly price check over 37,000 items instead of 620,000 is 6% of the reads. How to work out a run's duration is on integration throughput.

Historical orders stay where they are

Orders closed before go-live are already invoiced, paid and posted in the old system. Copying them into the new store or ERP adds no information and creates three problems.

Order state at go-live What happens to it
Open, not shipped Moved: someone still picks and ships it
Shipped, not invoiced Moved, or invoiced in the old system before the switch
Closed before go-live Stays in the source, read-only and searchable

First, the store side. Shopify's orderCreate mutation is documented for importing orders from an external system. Its defaults are set for that: inventoryBehaviour is BYPASS, so no stock is claimed, and sendReceipt and sendFulfillmentReceipt are false. A historical order is still a new order on the day it is created, so every app subscribed to new orders receives it as one. On a development or trial store, where an import is tested first, orderCreate is limited to five new orders a minute. Three years at 52,000 orders a year is 156,000 orders: 156,000 / 5 = 31,200 minutes, or 21 days and 16 hours for one test run.

Second, reading them back. An app reads orders from the last 60 days by default; older orders need the read_all_orders scope, which Shopify approves on request. Most integrations never need it, because they only handle orders from go-live onward.

Third, the ERP side. A NetSuite sales order that is created without a trandate gets today's date, so an imported 2024 order posts revenue in the current period without an error. The rules for the switch itself, including orders placed during it, are on replacing an integration.

Values one system calculates

Some fields are not data but results. Each has one system that calculates it, and it moves one way or not at all.

  • Tax. Shopify calculates tax at checkout. If the ERP recalculates the same order with its own rates and rounding, the two totals differ by a cent on some orders and the payout no longer matches the invoice. The integration sends Shopify's tax lines as amounts and the ERP posts them as given. The details are in money, tax and rounding.
  • Available stock. NetSuite derives quantityavailable from on hand minus committed. It is read from NetSuite and written to the store; the store's own count is never written back as a new on-hand value. Which number to send is on which stock counts.
  • Cost. averagecost and lastpurchaseprice are calculated by NetSuite from receipts. They can go to the store for margin reports, never the other way.

A value written into the system that calculates it is overwritten on the next calculation, or it overwrites the calculation. Both look like a sync working until someone compares the numbers.

Data that should not leave its system

The ERP gets what reconciliation and fulfillment need. It does not get what it cannot use.

Data Where it stays What crosses instead
Card number Payment gateway Gateway, transaction ID, amount, card brand
Customer password or login code Store Nothing
Marketing consent, browsing data Store Nothing
Full order history per customer Each system for its own orders Customer key

Shopify enforces the first row itself: CardPaymentDetails.number comes back with most of the leading digits redacted, and the bin field holds only the first few digits that identify the issuer. The other rows are a choice. A warehouse system needs the ship-to address and a phone number for the carrier, not the customer's newsletter status. Every personal field that crosses is one more copy to secure, to correct and to delete on request.

Content the store owns

Product descriptions, SEO titles, images and collections are written and checked in the store. They come from the ERP or PIM once, at the first load, and from then on the store owns them. The ERP keeps sending price, stock, barcode and weight.

The reason is concrete in Shopify's productSet mutation, which Shopify documents for syncing product data from an external source. For list fields such as collections, metafields and variants, it creates, updates and deletes: entries that are not in the input are removed. An integration that sends the ERP's category as the only collection on every run takes the product out of every collection the merchandiser added by hand. The fix is to leave collections out of the input, which leaves the field unchanged. More on what crosses for products is on field mapping.

What this means for your integration

We write down, with you, which data moves, in which direction and from which system, before anything is built. Inactive items, closed orders and calculated values are named in that list as staying where they are, so the decision is recorded instead of left to whoever builds the next flow. The integration then reads only what the list names.

A dry run shows per record what would change in the store or ERP before anything is written, which is where a filter that lets 620,000 items through gets caught. The data flows themselves are described on integrations. Tell us which systems you run, and you get the list of what we would sync and what we would leave.

Frequently asked questions

Should we import our old orders into the new store?

Usually not. Orders closed before go-live stay in the old store or ERP, where they are already posted and can still be looked up. Orders that are open at go-live, not yet shipped or not yet invoiced, are moved, because someone still has to act on them.

Is it safer to sync every field in case we need it later?

No. Each field is a mapping rule with its own validation and its own way to break when an API version changes. A field added later costs one rule and one backfill run; a field synced without an owner gets overwritten in both directions and nobody can tell which value is right.

Can we sync product descriptions from the ERP?

For the first load, yes. After that the description, SEO fields, images and collections belong to the store, because that is where they are written and checked. The ERP keeps sending price, stock, barcode and weight. Sending descriptions on every run overwrites the edits made in the store.

Does the ERP need the customer's card details?

No, and Shopify does not hand them out: its API returns the card number with most leading digits redacted. The ERP gets the payment method, the amount, the gateway and the transaction ID, which is what reconciliation against the payout needs.

What about customers who never ordered online?

They stay in the ERP until they order or until you open a B2B portal for them. Sending 40,000 ERP customers to a store that will see 3,000 of them creates 37,000 accounts to keep in sync and a set of welcome emails nobody asked for.

Tell us what you need

Tell us which systems you use and what needs to work better. We reply personally within one working day. We help you define the work, then agree the price and timing before you commit.

  • You know the price and the timeline before you commit to anything
  • We work out the connection that takes the work off your hands
  • We handle the build, hosting, monitoring and maintenance
  • Your team has less information to retype and fewer discrepancies to chase

Suppliers, products, orders per day, a rough estimate is fine.

Or email directly: carsten@syncmyshop.com