Connect Shopify to NetSuite
Why teams connect Shopify and NetSuite
The store runs in Shopify, the business runs in NetSuite, and between them sits a person exporting orders to a CSV each morning, or a rigid connector that drops an order when a SKU is missing. Order volume grows and the gap turns into backlog and mis-shipments.
- Paid orders become NetSuite sales orders as each webhook arrives, so fulfillment and invoicing start the same day
- Shoppers are matched to customers on email and an external ID, and a missing item holds the order for review instead of dropping it
- High-risk orders, flagged by Shopify's fraud analysis, wait for a person before they ever reach finance
- Fulfillment, tracking, and inventory levels flow back, so the storefront shows the truth and support stops guessing
Worked example
The order-to-cash flow most stores turn on first.
Paid Shopify order to a NetSuite Sales Order, with a fraud hold and a SKU guard
Started when an order is paid, with two branches that keep bad data out of NetSuite.
- Trigger: a Webhook trigger with Auto Register With Shopify for
orders/paid, carrying the order, line items, customer, and addresses. - Risk check: read the order's risks. If the recommendation is
cancelorinvestigate, a Wait for form step sends a reviewer the order link, and the flow continues only when they release it. - Resolve customer: NetSuite
Upsert by external idonCustomer, keyed onexternalId = shopify_customer_id, from the mapping below. - Resolve items: for each line, match NetSuite
Itembyline.sku → itemId. If any SKU does not match, send the whole order to a reviewer rather than creating a partial order. - Write order: NetSuite
Upsert by external idonSalesOrder, keyed onexternalId = shopify_order_id, adding a shipping line and a discount line from the order totals. - Write back: write the NetSuite internal ID to a Shopify order metafield
custom.netsuite_so_id. - Ongoing: a second flow polls NetSuite item fulfillments with the
Record Created or Changedtrigger and creates the Shopify fulfillment with the tracking number, and a scheduled flow pushes inventory levels from NetSuite to the Shopify location.
Field mapping
The starting map for the Shopify order to NetSuite Sales Order step.
| Shopify | NetSuite | Notes |
|---|---|---|
order.id | SalesOrder.externalId | Idempotency key. A redelivered webhook updates the order, not a second one. |
customer.id | Customer.externalId | Match key. Creates the customer if missing. |
customer.email | Customer.email | Secondary match when the customer ID is absent (guest checkout). |
order.created_at | SalesOrder.tranDate | ISO 8601 with timezone. Converted to the NetSuite account timezone. |
order.currency | SalesOrder.currency | Fails the run if the currency is not set up in NetSuite. |
line_items[].sku | SalesOrder.item.item | Resolved to internal item ID. A miss sends the order to a reviewer. |
line_items[].quantity | SalesOrder.item.quantity | Line level. |
line_items[].price | SalesOrder.item.rate | Override, so NetSuite price rules do not restate the charged price. Amounts are strings in Shopify; cast to number. |
total_shipping_price_set | SalesOrder.item (shipping item) | Added as a non-inventory line, not the header shipping cost field. |
total_discounts | SalesOrder.discountItem | Single order-level discount line. Line-level discounts are pre-applied to rate. |
order.name | SalesOrder.otherRefNum | The #1001 style store order number, for support lookups. |
What syncs, each direction
- Orders and customers. Paid orders become sales orders. New shoppers become customers. Refunds create credit memos against the original order. (Shopify to NetSuite)
- Fulfillment and tracking. An item fulfillment in NetSuite creates the Shopify fulfillment with the carrier and tracking number, which notifies the shopper. (NetSuite to Shopify)
- Inventory levels. Available quantity per item is pushed to the matching Shopify location on a schedule, so the storefront does not oversell. (NetSuite to Shopify)
- Products and pricing. New items and price changes keep the Shopify catalog and the NetSuite item list aligned, with one system set as the source of truth. (Either direction)
Governance and audit
The same controls apply to this sync as to every other Neblex workload.
- Run history. Every order is a run with the payload, the customer and item resolution, and the sales order it wrote. A failed run can be replayed from the step that failed, and the upserts stop a second order.
- Approval and holds. High-risk orders and orders with unmapped SKUs go to a reviewer as Wait for form tasks. A person releases or rejects each one.
- Scoped access. Shopify uses an admin API token with only the order and inventory scopes. NetSuite uses a role limited to sales orders, customers, and items.
- Environments. Build against a Shopify development store and a NetSuite sandbox, then promote the same flow to production.
Frequently asked questions
Is the order sync immediate or batched?
Immediate. The order-to-cash flow starts from Shopify's orders/paid webhook and writes the sales order when the webhook arrives. Inventory push runs on a short schedule instead.
What happens to an order with a SKU that is not in NetSuite?
The flow sends the whole order to a reviewer with the unmapped SKU named, rather than creating a partial sales order. Add the item mapping and release it, and the flow continues.
How are duplicate orders prevented?
The sales order is written with Upsert by external id on the Shopify order ID. A redelivered webhook updates the existing order rather than creating a second one.
How are refunds handled?
A Shopify refund creates a NetSuite credit memo against the original sales order, with the refunded lines and any restock reflected.
Does anything get installed in NetSuite?
No. The connector uses NetSuite's REST web services. No SuiteScript or bundle is deployed.
Can we run more than one store into one NetSuite account?
Yes. Each store is its own connection, and a subsidiary or a class can be set per store on the sales order.
Connectors used
Shopify
E-commerce
- Operations
- 367
- Operations with typed output
- 100%
- Change triggers
- Poll or inbound webhook
- Signs in with
- Connection fields
NetSuite
ERP & Enterprise Systems
- Operations
- 271
- Operations with typed output
- 0%
- Change triggers
- 1 (poll)
- Signs in with
- Connection details
NetSuite does not describe its output fields in advance, so check the field mapping with Test this step when you build the flow.
Bring one real integration
We will build it with you against your own systems, with the run log open.