Skip to content
SyncMyShop

Integrations

Orders, customers and shipping: one order, right in every system

A store order becomes a sales order, a payment, one or more shipments, an invoice and sometimes a refund. Each of those has to land in the ERP once, with the same totals the customer paid, and the tracking number has to come back. We build that integration to your order process, host it and run it.

Which system owns the order?

An order has two owners, one after the other. The store owns it from checkout until it is imported. From then on the ERP owns it, and the store receives status, shipments and invoices.

Data Owner Direction When it has to arrive
Order, lines, totals store at capture, ERP after import store to ERP within minutes of payment or checkout
Customer or company store for web buyers, ERP for accounts both ways before the order
Payment and payout payment provider store to ERP with the order, payouts daily
Shipment and tracking ERP, WMS or 3PL to the store when the box leaves
Invoice and balance ERP to the store or portal when billed
Return and refund where it starts both ways one record per event

Three rules hold the handover together. One store order becomes one ERP order. The store order ID is kept on the ERP order as its external ID. And creating the order is idempotent: a message that arrives twice finds the order that exists and changes nothing. Shopify states that the same webhook can be delivered more than once and identifies each delivery with the X-Shopify-Webhook-Id header.

After the handover, a change in the store is an event against the ERP order, not a new order. Orders are one of the five flows on the integrations overview.

One store order, several ERP records

The ERP has no single record called "order". A store order spreads over five or six records during its life, and which ones depends on how you bill. In NetSuite terms:

Event in the store NetSuite record Decided by
Order placed, ships later Sales Order, status Pending Approval or Pending Fulfillment whether sales orders need approval
Paid and handed over at once (POS, digital goods) Cash Sale sale and payment in one record
Payment captured before shipping Customer Deposit, reserved for that sales order capture at checkout
Box leaves the warehouse Item Fulfillment, status Picked, Packed or Shipped per shipment, not per order
Order billed on terms Invoice, with terms, due date and PO number B2B accounts
Goods come back Return Authorization, status Pending Receipt return request
Money goes back Credit Memo, Cash Refund or Customer Refund how the order was billed

The refund row is where most mapping errors sit. A Cash Refund is created from a return authorization and goes back on the customer's original payment method. A Credit Memo lowers what an invoiced customer owes and can stay unapplied. A Customer Refund pays out a credit that is open on the account. Booking every store refund as a credit memo leaves credits open on accounts that were paid by card.

Order 31907 from payment to refund, between Shopify, the integration and NetSuite The orders/paid webhook for order 31907 becomes a Sales Order with external ID SHOP-31907 and a Customer Deposit of 216.10 dollars. An Item Fulfillment for 2 of 3 lines comes back as a Shopify fulfillment with a UPS tracking number. Nine days later a refund of 19.48 dollars becomes a Return Authorization, a Credit Memo and a Customer Refund. Shopify store Integration queue and rules NetSuite ERP orders/paid #31907 Sales Order, external ID SHOP-31907 Customer Deposit, $216.10 warehouse ships 2 of 3 lines Item Fulfillment, Shipped, 2 lines fulfillmentCreate, UPS 9 days later, 1 unit comes back refunds/create $19.48 Return Authorization, 1 unit Credit Memo and Customer Refund, $19.48 Every NetSuite record points back to SHOP-31907. A message that arrives twice finds the record that exists and changes nothing.
One order from payment to refund. Six ERP records, each tied to store order 31907.

Business Central draws the same line: a sales order is posted into a shipment and an invoice. Its sales order has externalDocumentNumber for the store order ID and a shipAndInvoice action that posts both in one step.

What actually moves

No black box: these are the fields of an order, with the place each one lands.

Field Example What is done with it
Order name #31907 external ID SHOP-31907, with a prefix per channel so two channels cannot collide
PO number PO-88213 to the PO field of the order and the invoice
Customer email, or company and location matched before anything is created
Line SKU 20731-BLK-048, quantity 3, price 19.99 SKU resolved to the ERP item; an unknown SKU holds the order
Discount code FALL10, 20.95 a discount item, or spread over the lines
Shipping line Ground, 12.00 shipping method and shipping cost
Tax 15.58 at 8.265% taken from the store or calculated in the ERP, never both
Payment captured, 216.10 deposit against the sales order
Placed at 2026-11-01T06:30:00Z converted to the ERP's time zone before it becomes a date

The same order as Shopify returns it:

{
  "name": "#31907",
  "poNumber": "PO-88213",
  "displayFinancialStatus": "PAID",
  "taxesIncluded": false,
  "discountCodes": ["FALL10"],
  "subtotalPriceSet": { "shopMoney": { "amount": "188.52" } },
  "totalShippingPriceSet": { "shopMoney": { "amount": "12.00" } },
  "totalTaxSet": { "shopMoney": { "amount": "15.58" } },
  "totalPriceSet": { "shopMoney": { "amount": "216.10" } },
  "taxLines": [{ "title": "State tax", "ratePercentage": 8.265, "channelLiable": false }],
  "createdAt": "2026-11-01T06:30:00Z"
}

Two fields in this fragment change what the ERP has to do. taxesIncluded says whether the line prices already contain tax. channelLiable says whether the sales channel remits the tax itself, as a marketplace does. Tax that the channel remits is not your liability and is booked to a different account.

The timestamp is the third. This order was placed at 11:30 pm Pacific time on October 31. In UTC that is 6:30 am on November 1. An integration that cuts the date off the UTC value books the order in November. The dates and time zones note covers the conversion.

Customers and addresses

The ERP needs a customer on every order. For a guest checkout Shopify returns no customer on the order, only an email address and the addresses.

The choice has consequences in numbers. A store with 400 guest orders a day that creates a customer per order adds 400 times 365: 146,000 customer records a year. Booked on one web customer per store it adds none, and the buyer's name and address live on the order. Matched on email address, a repeat buyer lands on one record.

B2B orders work the other way around. The account exists in the ERP first, with its customer number, terms and price level, and the store company is created from it. An order from that company is matched on the customer number, never on a contact's email address. The match runs in a fixed order, and only when every step fails is a new customer created. The notes on duplicate customers and orders and address field mapping cover the matching chain, ZIP+4, state codes and the 35-character carrier field.

Tax, discounts and totals

The total the customer paid is a fact. The ERP order has to arrive at the same number.

3 x 19.99                59.97
1 x 149.50              149.50
items                   209.47
FALL10, 10% off         -20.95
subtotal                188.52
shipping                 12.00
tax 8.265% of 188.52     15.58
total paid              216.10

The trap: the store sends its tax lines, and the ERP calculates tax on the sales order as well. If the ERP's tax setup also taxes shipping, it arrives at 8.265% of 200.52: 16.57. The ERP order totals 217.09. The payment of 216.10 leaves 0.99 open, and it does so on every order.

Order 31907 with tax calculated once and with tax calculated twice As the customer paid: items 188.52, shipping 12.00 and tax 15.58 dollars, total 216.10. As the ERP recalculates with tax on shipping: items 188.52, shipping 12.00 and tax 16.57, total 217.09. The payment of 216.10 leaves 0.99 open. Store order, as the customer paid $216.10 Items after discount $188.52 Shipping $12.00 Tax $15.58 Payment captured $216.10 ERP order, tax calculated again with shipping taxed $217.09 Items after discount $188.52 Shipping $12.00 Tax $16.57 Open after the payment of $216.10 $0.99 8.265% of 188.52 is 15.58. 8.265% of 200.52 is 16.57. The order imports without an error and the invoice never closes.
The same order with tax calculated once in the store and once more in the ERP. The difference of $0.99 stays open on the invoice.

Nobody sees an error. The orders import, the invoices post, and after a month accounts receivable holds thousands of invoices with a balance of under a dollar that no payment will ever match. The fix is a decision made once: which system calculates tax. The other one takes the amount as given.

Rounding produces the same effect on a smaller scale. Three lines of 9.99 at 8.265% are 0.83 each when tax is rounded per line: 2.49. Rounded on the order total of 29.97 it is 2.48. Two systems that round at different levels disagree by a cent on a share of all orders.

Discounts have three forms that do not convert into each other without a rule: a percentage, an amount, and a replacement price. A 10% code on the order is 20.95 in the store. In the ERP it is one discount item of 20.95, or 6.00 on the first line and 14.95 on the second. The second form keeps margin per item correct in reports. The integration compares the store total with the ERP total on every order and holds an order that differs. The note on money, tax and rounding has the cases.

Payments, payouts and fees

A payment is not one event. The authorization, the capture, a refund, the provider's fee and the payout to your bank are five, and each is mapped on its own.

Event Example In the ERP
Authorization 216.10 held on the card nothing is booked; the order carries the status
Capture 216.10 deposit against the sales order
Fee 6.57 withheld by the provider expense, booked with the payout
Payout 209.53 net for this order part of a bank deposit
Refund 19.48 refund record against the order

The bank statement shows payouts, not orders. A payout is the sum of net amounts: each Shopify Payments balance transaction carries amount, fee and net. An integration that books 216.10 as received in the bank never matches a statement line. Booked as a deposit of 216.10 with a fee of 6.57, the payout of the day adds up to the amount the bank shows.

Authorizations expire. Shopify Payments holds a card authorization for 7 days. A store that captures on shipment and ships a backordered item on day 9 has shipped goods it can no longer charge. Orders that are authorized and not yet captured are listed with their age, and an alert goes out at the threshold you set, before day 7.

What goes wrong quietly

Failure What you see How it is handled
Tax calculated twice invoices with 0.99 open one tax owner, totals compared per order
The same webhook twice two sales orders for one payment external ID checked before every write
Order edited after import warehouse ships the old version edit applied while pending fulfillment, flagged after
Canceled during the sync a canceled order is picked status read again just before the write
Unknown SKU on a line order missing in the ERP held with the SKU named, never imported without the line
First box marks the order shipped one tracking number for two boxes one store fulfillment per ERP shipment
Carrier name not recognized tracking number is plain text shipping methods mapped to the store's carrier list
Refund booked as a return stock goes up for goods that never came back restock only on a return that was received

The carrier row comes from a list. Shopify builds a tracking link when the carrier name is one from its list, such as UPS, FedEx or USPS. An ERP shipping method called UPS GRND RES is not on it, so the customer gets a tracking number that cannot be clicked. The mapping table from shipping method to carrier name is part of the integration.

Status values do not map one to one either. Shopify has eleven fulfillment statuses on an order, from UNFULFILLED to PARTIALLY_FULFILLED, ON_HOLD and FULFILLED. A NetSuite sales order has eight, among them Pending Fulfillment, Partially Fulfilled, Pending Billing and Billed. "Pending Billing" has no store equivalent, and ON_HOLD has no NetSuite one. The order status mapping note has the full table.

Timing: when each record is sent

Standard connectors and iPaaS platforms run on a schedule and add fixed delays. A common setup waits 10 to 15 minutes before importing an order so the payment status can settle, and 5 minutes before exporting a shipment so the tracking number is on the record. The delays add up: an order flow with a 15-minute delay followed by a billing flow with a 60-minute delay shows a paid order as billed after more than an hour.

A fixed delay is a guess at how long a payment takes. We wait for the event itself.

Record Trigger Why this one
Card order orders/paid the payment is final, so no waiting period is needed
Order on terms orders/create no payment is captured at checkout
Edit or cancellation orders/edited, orders/cancelled applied to the ERP order, not imported as new
Shipment to the store Item Fulfillment set to Shipped the tracking number is on the record by then
Refund refunds/create one ERP record per refund
Payout payout report, once a day matches the bank deposit

An order paid 20 seconds after checkout is in the queue 20 seconds after checkout. An order paid by bank transfer two days later is imported two days later. A target is set per flow and measured. As an example: 95% of orders in the ERP within 5 minutes of payment, and tracking in the store within 3 minutes of the shipment. A scheduled comparison of store orders against ERP orders catches an event that never arrived. The note on webhooks explains why that comparison is not optional.

Throughput and limits

System Limit Number
Shopify webhooks time to answer 5 seconds, then up to 8 retries in 4 hours, then the subscription is removed
Shopify orders history an app can read 60 days, older orders need the read_all_orders scope
Shopify Payments card authorization 7 days
NetSuite concurrent requests per account 5 Standard, 15 Premium, 20 Enterprise and Ultimate
NetSuite order number (tranid) 45 characters
Business Central online OData requests per user 6,000 per 5 minutes

Sources: Shopify's webhook documentation, Shopify's Order object, Shopify payment capture and NetSuite concurrency governance, checked on October 3, 2026.

On a normal day the ERP side has room to spare. On a peak day it sets the pace. Take a NetSuite Standard account where a sales order save takes 4 seconds and the integration uses 2 of the 5 slots: 2 orders per 4 seconds is 30 a minute, 1,800 an hour.

On Black Friday the store takes 2,400 orders between 9:00 and 10:00. The queue delivers 1,800 of them in that hour and holds 600 at 10:00. If the next hour brings 900, the backlog is gone before 11:00: 600 plus 900 is 1,500, under the 1,800 the hour can carry. The last order of the first hour waits 600 divided by 30: 20 minutes.

The store notices nothing, because every webhook was answered within the 5 seconds. The warehouse sees orders up to 20 minutes late for one hour. An integration that writes to the ERP inside the webhook handler fails in the same hour: its answers pass 5 seconds, Shopify retries, and after 8 failures the subscription is removed.

The 60-day limit bounds the comparison run. A reconciliation that looks back 7 days stays well inside it. A one-time import of last year's orders needs the extra scope. The notes on NetSuite concurrency limits and API throttling and backoff have the full calculations.

You stay in control

Orders are the flow where a wrong write costs the most, so every order has a visible history.

  • Dry run. The integration receives real orders, builds the ERP order and writes nothing. The result is compared with what your current process created for the same orders.
  • Approval. Orders above an amount, from a new customer or with a manual price land as Pending Approval and wait for a person.
  • Exclusions. Test orders, POS sales or one sales channel are left out by rule.
  • Overrides. A held order is corrected and released from the dashboard, with the name of the person who released it.
  • Log per order. Every step, with the time, the values and the ERP record it produced.
order #31907   2026-11-01
06:30:22  received orders/paid       total 216.10
06:30:24  customer matched           email to customer 2291
06:30:25  sales order created        SHOP-31907, Pending Approval
06:30:26  totals compared            store 216.10, ERP 217.09
06:30:26  held                       difference 0.99, tax on shipping

Failed calls are retried from the queue with growing pauses. What still fails after the retries stays in the queue with its original payload and shows in the dashboard. The dry run and approval page describes the controls.

In depth

Orders connect to the other flows. An accepted order turns available stock into committed stock, which is part of stock and availability. The price on the order line comes from pricing and customer terms, and the SKU on it from product data.

Systems and platforms

ERP and accounting systems. NetSuite, Business Central, SAP Business One, Acumatica and QuickBooks. Each has its own record for a paid order: a Cash Sale or a Sales Order with a Customer Deposit in NetSuite, a sales order posted with shipAndInvoice in Business Central.

Shipping and fulfillment. ShipStation and ShipBob. When a 3PL ships the order, the shipment and the tracking number start there and go to both the store and the ERP.

Store platforms. Shopify, Magento, WooCommerce and BigCommerce.

Combinations. Shopify and NetSuite, Magento and NetSuite, WooCommerce and NetSuite, BigCommerce and NetSuite and Shopify and Business Central each have a page with the order records and limits of that pair.

A system that is not listed can be integrated when orders can be written to it in a controlled way: an API, an import table, or a file it picks up on a schedule. Tell us what you run.

Frequently asked questions

How fast does a store order reach the ERP?

It goes into the queue at the event that makes it final: the capture for a card payment, the checkout for an order on terms. From the queue it is written at the pace the ERP accepts. On a normal day that is right away. On a peak day the wait grows to minutes and no order is dropped. The dashboard shows the age of the oldest order that is still waiting.

What happens to orders while the ERP is unreachable?

The store keeps selling. Each order waits in the queue with its full payload and is delivered in the order it was placed once the ERP answers again. Because every order carries the store order ID as its external ID, an order that was half written before the outage is found and completed, not created a second time. The note on what happens when a sync fails walks through an outage of three hours.

Should the store or the ERP calculate sales tax?

One of them, never both. When the store calculates tax at checkout, that amount is what the customer paid, so the ERP order takes the store tax lines and its own calculation is switched off for those orders. When the ERP or a tax engine connected to it is the tax authority for your books, the store calls the same engine at checkout. Either way the integration compares the two totals on every order.

Can an order be changed or canceled after it was imported?

Yes, as long as the warehouse has not started on it. An edit or cancellation in the store arrives as its own event and is applied to the ERP order while it is still pending fulfillment. Once picking has started, the change is not applied automatically. It is flagged with both versions of the order so a person decides.

How do returns and refunds reach the ERP?

As separate records. The return of goods, the refund of money, the receipt in the warehouse and a restocking fee are four events that can happen on different days or not at all. Each becomes its own ERP record, linked to the original order. A refund without a return does not put stock back, and a return that fails inspection does not either.

Does every guest order create a new customer in the ERP?

Only when you want that. Guest orders can be booked on one web customer per store, or matched on email address so repeat buyers land on one record. B2B orders are matched on the company and its customer number. The note on duplicate customers and orders describes the matching order.

Do tracking numbers come back to the store for partial shipments?

Yes. Each shipment in the ERP or warehouse system becomes its own fulfillment in the store, with the lines and quantities that were in the box, the carrier and the tracking number. An order that ships in two boxes on two days produces two notifications with two tracking numbers.

Can B2B orders with a PO number and payment terms use the same integration?

Yes. The PO number, the company, the payment terms and the due date travel with the order. An order on terms is imported at checkout, since no payment is captured, and credit holds from the ERP can block it before it reaches the warehouse. The B2B terms page covers credit limits, tax exemptions and buyer permissions. Trading partners that order by EDI send an 850 purchase order instead.

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