ERP integration
Ecommerce ERP integration, built around the rules your business runs on
Orders into the ERP, stock, prices and tracking back to the store, with your pricing rules, your locations and your exceptions in the mapping. We build the integration between your store and your ERP, host it, monitor it and fix it when either side changes.
Three ways to connect a store to an ERP
There are three: a packaged connector, an iPaaS platform, and an integration built for your systems. The third comes in two forms: built and handed over, or built and run for you. We do the last one.
| Packaged connector | iPaaS platform | Built and run for you | |
|---|---|---|---|
| Field mapping | fixed set, plus a few settings | you configure flows in the platform | written to your fields and rules |
| Price layers | one price level per store | scripted workaround | every layer the ERP uses |
| A record that fails | error list in the connector | error list in the platform | retried, queued, shown with payload |
| An API version change | waits for the vendor's update | your flows, your job | ours, before the old version ends |
The row that separates them is the last one. Shopify releases a new API version every three months and supports each stable version for at least twelve months. A request to a version that is no longer supported is answered by the oldest supported version, with whatever fields that version has. The REST Admin API has been a legacy API since October 1, 2024, and new public apps have had to use GraphQL since April 1, 2025. An integration built on REST runs on an API that Shopify no longer develops. The question to ask of any option is who follows these changes and who does the work.
The second difference shows with volume. An integration that fails on 1 order in 50 is workable at 20 orders a day: 20 times 7 divided by 50 is about 3 orders a week, fixed by hand. At 200 orders a day it is 4 a day. On a peak day with 2,000 orders it is 40, on the day nobody has time. What decides whether an integration holds at volume is what it does with the order that fails. The comparison of a custom integration and an iPaaS goes through the technical differences.
What moves, and who owns it
Each piece of data has one owner. Every other system receives it.
| Data | Owner | Direction | Rule |
|---|---|---|---|
| Products and variants | ERP or PIM | to the store | the ERP sends identifiers, units and status; rich content stays where it is edited |
| Prices | ERP | to the store | price levels, contract prices and quantity breaks, per customer |
| Stock and availability | ERP or WMS | to the store | available, not on hand; per location |
| Customers and companies | ERP | both ways | one matching key, one rule for duplicates |
| Orders | store until accepted, ERP after | to the ERP, status back | one ERP order per store order, store ID kept |
| Payments and refunds | payment provider | to the ERP | capture, refund and fees as separate records |
| Shipments | warehouse or 3PL | to the store | partial shipments, several tracking numbers |
Each row is a flow with its own page: stock and availability, pricing and customer terms, orders, customers and shipping and product data. Buyers who order from inside a procurement system are covered under PunchOut. All five are on the integrations overview.
Two decisions belong to the order flow and are made once. The first is the landing record: in NetSuite a store order becomes a sales order, a cash sale or an invoice, and a refund becomes a cash refund, a credit memo or a customer refund. The second is tax. When the store sends its tax lines and the ERP also calculates tax on the order, every transaction is recorded with the wrong amount. One side calculates and the other accepts the result.
The mapping is the work
Two systems rarely store the same thing the same way. This is an order as the store sends it:
{
"name": "#10482",
"customer": { "email": "ap@example.com" },
"shipping_address": {
"company": "Example Mechanical Supply of Northern Nevada LLC",
"address1": "2180 Industrial Way Ste 104",
"province_code": "NV",
"zip": "89502-5981",
"country_code": "US"
},
"total_tax": "38.61",
"taxes_included": false
}
Five things in this fragment have to be decided before it becomes an ERP order.
| Field | In the store | In the ERP | What goes wrong |
|---|---|---|---|
| Customer | email address | customer number | no match found, a second customer is created |
| Company name | 48 characters | carrier label field of 35 | truncated to "Example Mechanical Supply of Northe" |
| Suite | inside address1 |
separate address line 2 | "Ste 104" is dropped or doubled |
| ZIP code | ZIP+4, 89502-5981 |
5 digits | validation rejects the order |
| State | NV |
"Nevada" or an internal ID | lookup fails, order stays in the queue |
The customer match is a chain, in a fixed order: the customer number when the store knows it, then the company's tax or registration number, then the company's email address, then the contact's email address, and only then a new customer. A translation table between store customer and ERP customer number is kept in the integration, and someone has to own it. The notes on duplicate customers and orders and address field mapping cover both in detail.
Records that fail validation go on a list with the reason. They are not skipped. A skipped order shows up weeks later as a customer complaint; a listed one is fixed the same morning.
Where connectors stop
Standard connectors and iPaaS templates document their own limits. These come from their product documentation:
- One price level at a time. The item export carries one price level for the selling price and one for the compare-at price. Wholesale, contract and tiered prices need custom fields that a script in the ERP keeps filled.
- Location mapping without rules. ERP locations map one to one, or several into one store location. Which location fulfills first, or how much of a location is reserved for a channel, is not a setting.
- Unmapped items are skipped. An item without a mapping record is left out of the inventory sync and no error is raised.
- No delivery dates. The inventory flow carries a quantity. An expected or promised date has no field.
- Templates are unmanaged. In the catalog of one large iPaaS vendor, 16 pair integrations are managed apps and 192 are templates, counted on September 30, 2026. A template receives no fixes and no new functionality after installation.
None of this is a defect. A product that serves many accounts with one codebase stops at the shape most of them share. The work that remains is the part that is specific to your account, and that is what we build.
What happens when it fails
API limits are reached on the busiest day, because that is when every integration on the account sends the most requests. The limits are published:
| System | Limit | Number |
|---|---|---|
| Shopify webhooks | time to answer | 5 seconds, then 8 retries over 4 hours, then the subscription is removed |
| Shopify GraphQL Admin API | points restored per second | 100 standard, 200 Advanced, 1,000 Plus |
| NetSuite | concurrent requests per account | 5 Standard, 15 Premium, 20 Enterprise and Ultimate |
| Business Central online | OData requests per user | 6,000 per 5 minutes, 5 processed at once |
Sources: Shopify webhook troubleshooting, NetSuite concurrency governance and Business Central operational limits, checked on October 3, 2026.
The first row is the one that breaks quietly. An integration that creates the ERP order inside the webhook handler answers late when the ERP is slow. Shopify counts a failure and sends the order again. After 8 failed retries the webhook subscription is removed, and from then on no orders arrive and nothing reports an error.
The design that holds has four parts:
- A queue. The store gets
200 OKat once. The ERP is called from the queue, at the pace it accepts. - Retries with growing pauses. A 429 or a timeout is retried after seconds, then minutes.
- Idempotent writes. Every order carries the store's order ID as its external ID. Before a retry, the integration checks whether the order already exists.
- A dead-letter queue and reconciliation. What still fails stays, with its original payload. A scheduled comparison of store orders against ERP orders catches what never arrived.
In the diagram, attempt 2 times out after NetSuite has created the sales order. A blind third attempt creates a second one, and the customer is shipped and invoiced twice. The lookup on external ID 10482 finds SO-20418 and closes the order. The notes on API throttling and backoff and what happens when a sync fails describe each step.
What you get
We build the integration to your systems and rules, host it and run it. The build has a fixed price and running it has a monthly fee. What is in the service:
- Hosting and monitoring. The integration runs with us. We see a failing run before your customer service does.
- Changes on either side. When an API version ends, a field is renamed or a supplier changes a file, we change the integration.
- A dashboard with a login. Logs per run, the records that failed, and the diff of what each run changed.
- Dry run and approval. A run can calculate everything and write nothing. Changes can wait for your approval, per connection.
- Exclusions and overrides. Products or customers with a manual arrangement are left alone.
When an existing integration or script is being replaced, the new flow first runs next to the old one without writing. Both process the same data and the differences are logged. After that period you know what the old integration did, including the rules nobody wrote down. The switch is made per flow. See replacing an integration and how an integration works.
ERPs we connect
- NetSuite: REST and SOAP web services, with the account concurrency limit of 5 to 20 requests shared by every integration. Pairs: Shopify, Magento, BigCommerce and WooCommerce.
- Business Central: OData API with 6,000 requests per 5 minutes per user. Pairs: Shopify and Magento.
- SAP Business One: price lists and special prices per business partner with date ranges. Pairs: Shopify and Magento.
- Acumatica: the license tier sets the number of concurrent API requests and the requests per minute.
- Sage Intacct and Odoo.
For a store on Shopify, the Shopify ERP integration page covers the platform side. Trading partners that require X12 documents are covered under EDI integration.
Tell us which store and which ERP you run, and which flow hurts most. You get a concrete answer.
Frequently asked questions
Do I need an integration partner, or can we run a connector ourselves?
A connector covers the standard flows and leaves three jobs with you: mapping the fields that differ in your account, handling the records it rejects, and following the API changes of both systems. Shopify releases a new API version every three months and supports each one for at least twelve. Someone has to own that calendar. With us, the build, the hosting, the monitoring and those changes are one service.
How long does a typical ecommerce ERP integration take?
The duration follows from four things: the number of flows, whether the ERP has a sandbox, how many conflict rules a two-way flow needs, and how fast API access is granted. The last one is outside the build and is often the slowest step, because the ERP administrator or the ERP partner has to create the integration user and its permissions. You get a fixed scope and a fixed build price before work starts.
Can existing data be migrated?
Yes. Customers, open orders and order history move as a one-time batch before the live flows start. The work is in the matching: a customer that exists in the store under an email address and in the ERP under a customer number is linked once and not created a second time. The batch runs as a dry run first, and you approve the list of matches and the list of records that did not match.
What is the most common reason these integrations fail?
A change on one side that nobody passed on. A new API version removes a field, an ERP administrator renames a custom field, a sandbox refresh wipes a token, a supplier changes a column. The integration itself did not change and stops producing correct data. The second reason is a record that fails and is skipped without a trace. Both are answered by monitoring and by keeping every failed record with its payload.
Do we need middleware between the store and the ERP?
There is a layer in between, and we host it. It holds the queue, the mapping and the log. A direct call from the store to the ERP loses the order when the ERP is slow or refuses the request, and Shopify gives a webhook receiver five seconds to answer. With a queue the store gets its answer at once and the ERP is called at the pace it accepts.
What happens when a sync fails overnight?
The failed call is retried with growing pauses. If the ERP is down for an hour, orders wait in the queue and arrive in the order they were placed when it is back. A record that still fails after the retries goes to the dead-letter queue with its original payload and the error text, and an alert goes out. In the morning the dashboard shows which records are waiting and why. See what happens when a sync fails.
Which ERP systems do you integrate with?
NetSuite, Microsoft Dynamics 365 Business Central, SAP Business One, Acumatica, Sage Intacct and Odoo, and store platforms Shopify, Magento, BigCommerce and WooCommerce. A system outside that list can be integrated when its data can be read and written in a controlled way: an API, a database view or a scheduled file export.
Should the store and the ERP sync in real time?
Per flow. New orders, cancellations and stock on fast-moving items are sent as events and arrive within minutes. Prices, product updates and order status go in scheduled runs. Catalog loads, order history and reconciliation run as batches at night. Real time everywhere uses the API budget of both systems on data that does not need it.
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