A complete implementation guide for merchants and support teams deploying the Celigo Shopify B2B – NetSuite integration template (NA) and (EU).
The following video explains the Shopify B2B - NetSuite integration template
Just getting started? Start here
If you want companies, locations, contacts, catalog pricing, and orders up and running, follow sections in order.
What this template does
The Shopify B2B – NetSuite template connects your Shopify Plus B2B storefront to NetSuite so that both systems share a single, accurate version of your business data. Companies and their locations managed in NetSuite appear in Shopify automatically. B2B orders placed by buyers flow into NetSuite as Sales Orders. Catalogs and pricing tiers sync from NetSuite price levels. Fulfillments, payments, and refunds update both systems without manual entry.
What merchants gain
- Sales teams stop manually creating NetSuite customers for every new B2B buyer. Every Shopify company and location lands in NetSuite automatically.
- Operations teams stop keying orders by hand. Every B2B order placed in Shopify lands in NetSuite within minutes.
- Finance teams get accurate payment capture: Shopify order payments create NetSuite Customer Payments and apply them to the correct invoice.
- Merchandising manages price levels in NetSuite and publishes them as Shopify Catalogs automatically — with per-location catalog assignments.
- Warehouse teams close the fulfillment loop: Item Fulfillments posted in NetSuite mark Shopify orders as shipped and send tracking notifications to buyers.
Who this guide is for
This guide is written for:
- Merchants and store owners who are setting up the integration themselves or overseeing an implementation.
- Support teams who need to understand how each flow works in order to diagnose issues and answer merchant questions.
- NetSuite administrators who are preparing NetSuite for the integration (bundle installation, roles, saved searches).
This guide assumes you are already working in NetSuite and know what records like Customers, Sub-Customers, Contacts, Sales Orders, and Item Fulfillments are. Where a concept needs clarification for integration purposes, it will be explained in context — but general NetSuite navigation is out of scope.
B2B data model: how the two platforms map to each other
Before you begin, understand how Shopify B2B entities correspond to NetSuite records. This mapping drives everything — connections, flow behavior, and how lookups work.
The Assign Order to Location setting controls whether Sales Orders land on the parent Customer (Company) or the Sub-Customer (Location). Most B2B implementations set this to enabled so orders are tracked at the delivery-site level.
All 16 flows at a glance
The template ships with 16 flows grouped across 9 modules. All flows are disabled by default — you enable them in a specific order after completing setup. Section First-time enablement walks through the exact sequence.
| # | Flow Name | Direction | Trigger |
|---|---|---|---|
| Products | |||
| 1 | Shopify products to NetSuite item ID map (add or update) | SHP → NS | On-demand / Scheduled |
| Companies | |||
| 2 | NetSuite customer to Shopify company (add or update) | NS → SHP | Scheduled |
| 3 | Shopify companies and locations to NetSuite (add or update) | SHP → NS | Scheduled |
| Locations | |||
| 4 | NetSuite locations to Shopify locations (add or update) | NS → SHP | Scheduled |
| 5 | NetSuite locations to Shopify locations (delete) | NS → SHP | Scheduled |
| Contacts | |||
| 6 | Shopify contacts to NetSuite contacts (add or update) | SHP → NS | Scheduled |
| 7 | NetSuite contacts to Shopify contacts (add or update) | NS → SHP | Scheduled |
| Orders | |||
| 8 | Shopify B2B order to NetSuite sales order (add) | SHP → NS | Scheduled |
| Shipments | |||
| 9 | NetSuite fulfillment to Shopify fulfillment (add) | NS → SHP | Scheduled |
| Catalogs & Pricing | |||
| 10 | NetSuite price level catalogs to Shopify catalogs (add or update) | NS → SHP | Scheduled |
| 11 | NetSuite price level catalogs to Shopify companies and locations | NS → SHP | Scheduled |
| 12 | NetSuite product price level to Shopify catalog product price | NS → SHP | Scheduled |
| 13 | Remove locations from catalogs | NS → SHP | Scheduled |
| Payments | |||
| 14 | Shopify payments to NetSuite customer payments (add) | SHP → NS | Scheduled |
| 15 | NetSuite payments to Shopify payments (add) | NS → SHP | Scheduled |
| Refunds | |||
| 16 | Shopify refund to NetSuite credit memo (add) | SHP → NS | Scheduled |
Prerequisites
Complete every item in this section before installing the template. Skipping prerequisites is the single most common cause of errors on new installations.
Install the template only after confirming all prerequisites are met. If you install and then discover a missing bundle or permission, you will need to reconfigure connections.
NetSuite requirements
Install the Celigo integrator.io SuiteApp
In NetSuite, go to Setup > SuiteApp Marketplace and search for "Integrator.io". Install the SuiteApp. This installs the base Celigo restlets needed for all NetSuite communication.
Install the Celigo Shopify Connector bundle
Go to
Customization > SuiteBundler > Search & Install Bundles.
Search for Bundle ID 81289 and install it. This bundle
deploys all saved searches the template relies on (prefixed
customsearch_etail_b2b_*), plus custom fields on Customer
and Contact records (Shopify Company ID, Location ID, Celigo External
ID), and two custom record types: Celigo Shopify Item ID Map and
Celigo Location Mapping. Do not rename, modify, or delete any search
installed by this bundle.
Enable Sub-Customers
Go to Setup > Company > Enable Features > CRM tab. Check Subcustomers and save. Shopify Company Locations map to NetSuite Sub-Customers — this must be enabled before the Locations flows can create records.
Create a Discount Item in NetSuite
Go to Lists > Accounting > Items > New and select Other Charge as the item type. Name it clearly (e.g., "Shopify B2B Discount"). Assign it to an appropriate discount or income account. Note the exact item name — you will select it in the Orders flow group settings.
Create a Refund Adjustment Item in NetSuite
Go to Lists > Accounting > Items > New and select Non-Inventory Item. Include "refund" in the name (e.g., "Shopify Refund Adjustment") — the bundle's saved search filters by this keyword. Assign an income account. Note the exact item name for the Refunds group settings.
Create a Token-Based Authentication (TBA) integration record
Go to Setup > Integration > Manage Integrations > New. Enter a name (e.g., "Celigo Shopify B2B Integration"). Under Authentication, check Token-Based Authentication and uncheck all other auth options. Save and copy the Consumer Key and Consumer Secret shown on the confirmation screen.
Create an Access Token
Go to Setup > Users/Roles > Access Tokens > New. Select the integration record you just created. Choose the user and role — the role must have full permissions on: Customers, Contacts, Sales Orders, Item Fulfillments, Credit Memos, Return Authorizations, Customer Payments, Custom Records, and Restlets. Save and copy the Token ID and Token Secret.
NetSuite shows the Consumer Secret and Token Secret only once. If you navigate away without copying them, you must create new credentials.
Shopify requirements
- A Shopify Plus plan — B2B features are exclusive to Shopify Plus.
- B2B / Wholesale features enabled — Shopify Admin > Settings > Markets > B2B should be active.
-
An Admin API access token with the following scopes:
read_orders,write_orders,read_customers,write_customers,read_products,write_products,read_fulfillments,write_fulfillments. Create a Custom App in Shopify Admin > Apps > Develop apps. -
Your store URL noted — the
yourstore.myshopify.comdomain.
Celigo requirements
- An active Celigo integrator.io account. Contact your Celigo account manager if you are unsure whether your subscription supports marketplace templates.
- Only account owners in integrator.io can configure connections. Ensure the person performing setup has account owner permissions in Celigo.
Install the Template
Find the template in the Celigo marketplace
In Celigo integrator.io, click Marketplace in the left navigation. Search for "Shopify B2B NetSuite" or browse Shopify templates. Click the Shopify B2B – NetSuite Integration Template tile.
Open the marketplace listing
Click the template tile. You will see the template preview page showing the included flows and a description.
Click Install Template
The installation wizard opens. It will walk you through configuring all three connections — do not skip any.
Complete the wizard
After configuring connections, select "Copy resources now from template zip" and click Install. The integration "Shopify B2B – NetSuite" will appear in your Integrations list. All flows will be off — this is expected.
Configure connections
During installation, Celigo will prompt you to configure three connections. All must be fully authorized before any flow can run.
Connection 1 — NetSuite (Token-Based Authentication)
| Field | Value |
|---|---|
| Account ID |
Your NetSuite Account ID (e.g., 1234567). Visible
in the URL when logged in:
https://XXXXXX.app.netsuite.com — the number before
.app.
|
| Consumer Key | From the Integration record created in prerequisites. |
| Consumer Secret | From the Integration record created in prerequisites. |
| Token ID | From the Access Token created in prerequisites. |
| Token Secret | From the Access Token created in prerequisites. |
Click Test Connection — must show green before saving.
Connection 2 — Shopify B2B Store (read)
Type: HTTP / GraphQL. Used for reading data from Shopify (companies, orders, contacts).
| Field | Value |
|---|---|
| Base URI |
https://{your-store}.myshopify.com/admin/api/2025-07/graphql.json
|
| Authentication |
Token — enter Bearer {your-admin-api-token}
|
Connection 3 — Shopify B2B Store (write)
Type: HTTP / GraphQL. Used for write operations back to Shopify (fulfillments, catalog updates, payment status). Uses the same store URL and token as Connection 2.
Using separate read and write connections keeps rate limit management and flow debugging easier for high-volume stores.
Once authorized, all connections are shared across all 16 flows. If any connection expires or is re-authorized with different credentials, every flow that uses it will be affected. See OAuth token expirations in Troubleshooting for recovery steps.
Initial Setup
Before you enable any transactional flow, you must run the Products setup flow and complete the integration-level settings. This section is the most important part of a new installation — getting it right prevents a category of hard-to-diagnose errors later.
The steps below must happen in order. Enabling transactional flows (Companies, Orders) before completing setup will produce reference errors because downstream flows look up records that do not yet exist.
| Step | Action | Where |
|---|---|---|
| 1 | Run the Products (Item ID Map) flow | Celigo — flow dashboard |
| 2 | Configure integration-level settings | Celigo — integration Settings tab |
| 3 | Configure Orders flow group settings | Celigo — Flows tab > Orders gear icon |
| 4 | Configure Refunds flow group settings | Celigo — Flows tab > Refunds gear icon |
| 5 | Configure Catalogs & Pricing flow group settings | Celigo — Flows tab > Catalogs gear icon |
Step 1 · Build the item ID map
The very first action after installation is to run the Shopify products to NetSuite item ID map (add or update) flow. This flow reads your Shopify product catalog and creates cross-reference records in NetSuite that map each Shopify product variant (by SKU) to its corresponding NetSuite item internal ID.
This mapping is the structural backbone of the integration. Every order flow depends on these records to resolve Shopify line items into NetSuite item records. Without them, order imports will fail because NetSuite cannot identify which item is on each order line.
Confirm items exist in both systems first
Before running this flow, make sure your product catalog is in reasonable sync. Items must exist in NetSuite (either manually entered or imported). The flow matches by SKU — if an item exists in Shopify but has no matching SKU in NetSuite, that item will not get a map record and orders containing it will error.
Run the Item ID Map flow
Find Shopify products to NetSuite item ID map (add or update) and click Run now. For large catalogs this may take several minutes.
Review the results
Check how many records were created vs. how many errors occurred. An error typically means a Shopify SKU did not match any NetSuite item. Resolve SKU mismatches before going live with the order flow.
Configure Settings
The integration's Settings page controls how data moves between Shopify and NetSuite. Most settings are configured once at go-live and rarely changed. This section explains each setting group, what each field does, and what happens if you leave it at its default.
Each field in the Settings form is tagged with one of three labels:
| Label | Meaning |
|---|---|
| Required | Must be set before the related flow can be enabled. Celigo will block enablement until these are configured. |
| Optional | Can be left at its default in most implementations. |
| Conditional | Optional in the form but becomes effectively required when a specific scenario applies. The scenario is noted inline. Skipping a Conditional field when your scenario applies is one of the most common causes of silent data issues post go-live. |
Integration-level settings (General)
In the integration, click the Settings tab, then the gear icon. These settings apply globally across all flows.
| Setting | Tag | What it does |
|---|---|---|
| Default Payment Terms | Optional | The Shopify payment terms template applied to companies synced from NetSuite when no terms exist on the NetSuite Customer. Options: Due on receipt, Due on fulfillment, Within 7 / 15 / 30 / 45 / 60 / 90 days, Fixed date. Choose to match your standard B2B credit terms. |
| Default Contact Role | Optional | Role assigned to contacts at a Shopify Location. Ordering only — the contact can place orders but cannot manage the account. Location admin — full administrative rights. Most implementations start with "Ordering only". |
| NetSuite Tax Code | Required | A non-inventory item representing the tax code applied to Sales Orders. Select from the dropdown. Required — every order sync will fail if this is blank. |
Location settings
| Setting | Tag | What it does |
|---|---|---|
| Create Location for Company | Conditional | When on, creates a Shopify Location using the parent Company's own address in addition to any sub-customer locations. Enable when NetSuite Customers have a meaningful address on the parent record that buyers should use for shipping. |
| Billing Same as Shipping | Optional | Sets billing address equal to shipping address for locations. Enable for customers who always bill and ship to the same address. |
| Editable Shipping Address | Optional | Whether buyers can change their shipping address at checkout. Enable for flexibility; disable to enforce fixed ship-to addresses for strict procurement scenarios. |
| Checkout to Draft | Conditional | Creates Shopify orders as Draft Orders pending merchant review. Enable when your business requires order approval workflows before fulfilment begins. |
| Main Contact Selection | Optional | Controls which contact becomes the main contact for a Company. Oldest Internal ID — uses the Contact with the lowest NetSuite Internal ID. Primary Contact role — uses the Contact tagged with the "Primary Contact" role. If your NetSuite data does not have a consistent Primary Contact role set, use "Oldest Internal ID". |
Orders flow group settings
On the Flows tab, click the gear icon on the Orders module row.
| Setting | Tag | What it does |
|---|---|---|
| Assign Order to Location | Optional | When on, Sales Orders are created under the Sub-Customer (Location). When off, all orders land on the parent Customer (Company). Recommended: on — most B2B operations track orders at the delivery-site level. |
| NetSuite Discount Item | Conditional | The Other Charge item representing Shopify discounts on Sales Orders. Select the item you created in prerequisites. Required if any B2B orders use discount codes or price adjustments. |
Refunds flow group settings
On the Flows tab, click the gear icon on the Refunds module row.
| Setting | Tag | What it does |
|---|---|---|
| Create Return for Refund | Conditional | When on, creates a Return Authorization in NetSuite before the Credit Memo (full returns workflow). When off, creates the Credit Memo directly from the invoice. Enable for formal returns processes; leave off for simple refund-only workflows. |
| NetSuite Adjustment Item | Required | The Non-Inventory item used for shipping refunds and other adjustments that don't match a product line. Select the item created in prerequisites. Required — the refunds flow will error on every record without this. |
Catalogs & Pricing flow group settings
On the Flows tab, click the gear icon on the Catalogs & Pricing module row.
| Setting | Tag | What it does |
|---|---|---|
| Default State | Optional | All Products — new Catalogs are pre-populated with every published product. Empty — new Catalogs start with no products; you add them separately. Use Empty for fine-grained product access control; use All Products for standard open-catalog B2B setups. |
| Autopublish | Conditional | When on, any newly created Shopify product is automatically added to all existing Catalogs. Enable for setups where all B2B customers always access your full product range. |
Flows: Products
Utility flow. Reads your Shopify product catalog and creates or updates Item ID map records in NetSuite by matching Shopify variant SKUs to NetSuite internal item IDs. This is the cross-reference lookup that every order flow depends on.
Depends on: Items must exist in NetSuite with matching SKUs
Run this flow at least once before enabling the order flow. Re-run it any time new Shopify products are added before their first orders arrive. Schedule it daily or weekly for ongoing catalog changes.
Flows: Companies
Companies are the foundation of the B2B data model. All other entities (Locations, Contacts, Orders) depend on Companies being in sync first.
Reads NetSuite Customer records and creates or updates Shopify Companies.
Syncs: company name, billing and shipping addresses, payment terms, tax-exempt
status, main contact, and any custom metafields (NetSuite fields prefixed
with met- are mapped as Shopify metafields). Ampersands
(&) in company names are automatically converted to "And" for Shopify
GraphQL compatibility.
If Create Location for Company is on, a default Shopify Location is auto-created from the Company's address. The main contact is selected per the Main Contact Selection setting — if no contact exists on the NetSuite Customer, a fallback contact is created using the company name.
Reads Shopify Company and Location data and creates or updates NetSuite Customers (parent) and Sub-Customers (child, one per location). Stores the Shopify Company GID as the external ID on the NetSuite Customer for reverse lookups. The flow checks for the existing NetSuite record by external ID — if found, updates; if not, creates.
NetSuite term names must match exactly: Net 7,
Net 15, Net 30, Net 45,
Net 60, Net 90, Due on receipt,
Due on fulfillment, Fixed date. Any other term
names will not map.
Flows: Locations
Reads NetSuite Sub-Customer records and creates or updates Shopify Company Locations. Applies the Billing Same as Shipping, Editable Shipping Address, Checkout to Draft, and Default Payment Terms settings at the location level. Creates a Celigo Location Mapping record in NetSuite for cross-system lookups. Tax registration IDs are synced if present.
Detects deleted or inactivated NetSuite Sub-Customers and removes the corresponding Shopify Location from its Company.
Deleting a Shopify Location also removes its catalog assignments. Coordinate location deletions carefully — notify your Catalogs & Pricing team before inactivating Sub-Customers in NetSuite.
Flows: Contacts
Reads Shopify Company Contacts and creates or updates NetSuite Contact records linked to the corresponding NetSuite Customer. Syncs: name, email, company association, and location role assignments. If a Shopify Contact also has a standard Shopify customer account, the flow creates a NetSuite Customer record for the profile and links it as a Contact — the "Assign Customer as Contact" step handles this dual-identity scenario automatically.
Reads NetSuite Contact records and creates or updates Shopify Company Contacts. After create or update, the flow automatically assigns the contact to all active locations of the Company using the Default Contact Role. The flow checks existing role assignments first — it only adds new assignments for locations where the contact isn't yet assigned, so it is safe to re-run.
Flows: Orders
The Orders flow is B2B-only by design. It filters Shopify orders to only
those placed through the B2B portal — identified by the presence of a
purchasingEntity (company + location). Regular consumer orders
from the same store are automatically excluded.
Polls Shopify for new and updated B2B orders. Looks up the NetSuite Customer or Sub-Customer via the Celigo Location Mapping record. Creates or updates a Sales Order in NetSuite.
Depends on: Products (Item ID Map), Companies, Locations flows have run
What this flow maps
| Shopify data | NetSuite field |
|---|---|
| Line items (SKU + qty + price) | Sales Order lines — items resolved via Product Item ID Map |
| Line-level discount allocations | Discount line per item (negative, uses Discount Item) |
| Header-level discount | Single header discount line (negative, uses Discount Item) |
| Shipping cost | Shipping charge line |
| Shipping discount | Shipping discount line (negative) |
| Gift card applied | Gift Card Certificate line (negative, reduces total) |
| Payment terms (purchasingEntity) | Terms on Sales Order |
| Note + PO number | Memo: "Note text - PO: PO-12345" |
| Tax lines per item |
Stored in etailOrderCustomData for Refunds flow
downstream
|
| Currency | Order currency |
If you see "No customer record found for Location" errors, the Locations flow hasn't yet synced those locations. Run the Locations flow first, then retry the failed order records.
Flows: Shipments
When your warehouse creates an Item Fulfillment in NetSuite, this flow
notifies Shopify so the B2B buyer receives a shipping confirmation. It
calls Shopify's fulfillmentCreate GraphQL mutation.
Multiple tracking numbers are supported — if stored in NetSuite separated
by <BR> (NetSuite's multi-line field separator), they
are split and sent as individual tracking numbers to Shopify. Line item
matching resolves NetSuite fulfillment lines to the correct Shopify Fulfillment
Order lines by SKU and order line ID, ensuring quantities are fulfilled
accurately.
Depends on: Order flow has created the NetSuite Sales Order
Flows: Catalogs & Pricing
This module maps NetSuite Price Levels to Shopify Catalogs and keeps product prices within each catalog in sync. Run flows in order A → B → C. Flow D runs independently to clean up stale assignments.
In Shopify B2B, a Catalog is a published price list assigned to a Company or Location. A NetSuite Price Level is the equivalent concept. This module creates a Shopify Catalog for each Price Level, assigns it to the right companies and locations, and populates per-product prices within each catalog.
Creates or updates a Shopify Catalog for each NetSuite Price Level. Applies the Default State and Autopublish settings. Run this first.
Reads NetSuite Customers' assigned Price Level and assigns the corresponding Shopify Catalog to each Company Location. Locations are batched up to 250 per API call (Shopify's limit). Only locations whose current catalog doesn't match are updated. Run after Flow A.
Syncs the actual prices for each product variant within each Catalog. Looks up the Shopify variant via the Product Item ID Map, then sets the price in the correct Catalog. Depends on the Products flow having been run.
Depends on: Products (Item ID Map) flow has populated records
Detects Shopify Locations whose current catalog assignment no longer matches the NetSuite Price Level and removes the stale assignment. Works in tandem with Flow B to keep assignments accurate.
Flows: Payments
When a B2B order is paid in Shopify, creates a Customer Payment in NetSuite and applies it to the open invoice. Reads only successful transactions (status = SUCCESS, kind = SALE). Payment amounts are converted to absolute values to handle any sign differences.
Depends on: Order flow has created the NetSuite Sales Order and invoice
When an invoice is paid in NetSuite (for example, via manual AR entry or bank reconciliation), updates the corresponding Shopify order's payment status to paid. Marks the NetSuite payment record as sent to avoid re-processing.
Flows: Refunds
Enable this module last — it requires NetSuite invoices to already exist for orders. If enabled before the Orders flow has run, every record will error with "No Invoice found".
Imports Shopify refunds into NetSuite, creating the correct refund transaction based on the refund type.
Depends on: Original Sales Order in NetSuite has been
invoiced; Orders flow has populated etailOrderCustomData
Routing logic
| Refund type | Shopify trigger | NetSuite outcome |
|---|---|---|
| Product refund | One or more line items refunded | Return Authorization (if "Create Return for Refund" is on) + Credit Memo against the original invoice |
| Shipping refund | Shipping line refunded, no items | Credit Memo with Adjustment Item representing the shipping amount |
| Other adjustment | No items, no shipping (manual refund) | Credit Memo with Adjustment Item for the refund amount |
The flow looks up the original invoice by Shopify Order ID. If the Sales Order hasn't been invoiced yet in NetSuite, the refund will error. Ensure your NetSuite order-to-invoice process has run before enabling this flow.
Enable Flows and Schedule
Enabling flows in the wrong order is the most common cause of errors on new installations. This section covers which flows depend on which, the recommended first-time enablement sequence, and how to set schedules for production operation.
All 16 flows ship disabled. Enable them one module at a time in the order shown below. Enabling a flow before its dependencies are met will generate reference errors that are difficult to diagnose after the fact.
Dependency order
| Flow | Depends on | Notes |
|---|---|---|
| Products (Item ID Map) | Items in NetSuite with matching SKUs | Run first, before every other module. |
| Companies (NS → Shopify) | Nothing (NS as source) | Run before Locations and Contacts. |
| Companies (Shopify → NS) | Nothing | Independent direction; can run simultaneously. |
| Locations (Create/Update) | Companies in both systems | Sub-Customers must have a parent Customer. |
| Locations (Delete) | Locations (Create/Update) has run | Detects inactivated Sub-Customers. |
| Contacts (Shopify → NS) | Companies in NetSuite | Contacts link to existing Customer records. |
| Contacts (NS → Shopify) | Companies and Locations in Shopify | Role assignments require Locations to exist. |
| Orders | Item ID Map, Companies, Locations in both systems | The most dependent flow — all setup must be complete. |
| Shipments | Order flow has created the NS Sales Order | Reads NetSuite Item Fulfillment records. |
| Catalogs A (Create/Update) | Nothing (NS as source) | Run before Catalogs B and C. |
| Catalogs B (Assign) | Catalogs A has run | Requires Catalogs to exist in Shopify first. |
| Catalogs C (Prices) | Item ID Map, Catalogs A | Requires Shopify products and Catalogs to exist. |
| Catalogs D (Remove) | Catalogs B has run | Cleanup flow; runs independently. |
| Payments (Shopify → NS) | Order flow + invoices in NetSuite | Requires open invoice to apply payment against. |
| Payments (NS → Shopify) | Order flow (order must exist in Shopify) | Enable with the Shopify → NS direction. |
| Refunds | Order flow + invoices in NetSuite | Enable last — requires NetSuite invoices to exist. |
First-time enablement sequence
Follow this sequence when enabling flows for the first time on a new installation. Complete each group before moving to the next.
Products — Item ID Map
Run Shopify products to NetSuite item ID map manually. Verify the run shows matched records with no SKU mismatch errors before proceeding. Schedule daily or weekly for ongoing catalog changes.
Companies
Enable both company sync flows: NS → Shopify and Shopify → NS. Let them run at least once before enabling Locations to pre-populate company records in both systems.
Locations
Enable Locations (Create/Update) and let it run. Then enable Locations (Delete).
Contacts
Enable both contact sync flows: Shopify → NS and NS → Shopify. Let them run at least once before enabling the order flow to pre-populate contact records and role assignments.
Primary order flow
Enable Shopify B2B order to NetSuite sales order. This is the highest-value flow in the integration. Monitor the first few runs closely — check for errors on individual records and resolve any item ID map gaps or setting misconfigurations before processing large volumes.
Catalogs & Pricing
Enable in order: Catalogs A → Catalogs B → Catalogs C. Enable Catalogs D independently for ongoing cleanup.
Payments
Enable both payment flows: Shopify → NS and NS → Shopify.
Shipments
Enable NetSuite fulfillment to Shopify fulfillment.
Refunds
Enable Shopify refund to NetSuite credit memo last, only after confirming that Sales Orders have been invoiced in NetSuite.
Scheduling best practices
| Flow group | Recommended schedule | Reason |
|---|---|---|
| Products (Item ID Map) | Daily / On-demand | Run manually before go-live. Schedule daily after that, plus re-run whenever new products are added. |
| Companies (both directions) | Every 15–30 min | Core entity — keep it frequent for near-real-time company management. |
| Locations (Create/Update) | Every 15–30 min | Location changes should stay near-real-time. |
| Locations (Delete) | Every 30–60 min | Deletions are rare — less frequent schedule is fine. |
| Contacts (both directions) | Every 15–30 min | Role assignments and contact changes should stay in sync promptly. |
| Orders | Every 5–15 min | Orders are time-sensitive — keep this as frequent as your plan supports. |
| Payments (both directions) | Every 15–30 min | Payment status should resolve promptly after orders are placed. |
| Shipments | Every 15–30 min | Buyers expect shipping notifications quickly after fulfillment. |
| Catalogs A & B | Every 1–4 hours | Catalog structure changes infrequently — hourly is sufficient. |
| Catalogs C (Prices) | Every 30–60 min | Price changes should reflect in Shopify within the hour. |
| Catalogs D (Remove) | Every 1–2 hours | Cleanup flow — less urgent, hourly is fine. |
| Refunds | Every 15–30 min | Refunds should post to NetSuite promptly to keep AR accurate. |
Coexistence with the Shopify – NetSuite Integration App
This B2B template can run alongside Celigo's Shopify – NetSuite Integration App (D2C). They serve different customer segments and can complement each other — but you must configure each to process only its intended orders.
Both the Integration App and this template poll the same Shopify store for orders. Without a filter on the Integration App, B2B orders may be processed by both, creating duplicate Sales Orders in NetSuite.
| This template (B2B) | Shopify – NetSuite IA (D2C) |
|---|---|
Already filters to B2B orders only (orders with a
purchasingEntity)
|
Must add filter: exclude orders where purchasingEntity
is not null
|
| Handles Companies, Locations, Contacts, Catalogs | Handles D2C customers, standard orders |
| Fully customizable — you own it | Centrally maintained by Celigo |
| Not centrally maintained by Celigo | Can share the same Shopify store |
To add the filter to the Integration App: open the Orders export in the Shopify-NetSuite
IA, go to the Filter section, and add a condition:
purchasingEntity is null. This ensures the IA processes only
consumer orders with no company association.
Troubleshooting
This section covers the most common issues across all flow modules. For each issue, the fastest path to diagnosis is to open the failing record in the Celigo flow dashboard, examine both the source payload and the error response, and identify which step failed (export, lookup, transformation, or import). Each stage has different root causes.
Companies not syncing
- Check subsidiary assignment. If your NetSuite account uses subsidiaries and the customer's subsidiary does not match the expected value, the import may fail or create a duplicate. Verify the subsidiary mapping in the customer import step.
-
Check for ampersands in company names. Shopify GraphQL
rejects
&in names. The template auto-converts&to "And" — if errors persist, check the company name in NetSuite and re-run the Companies flow. - Check payment terms format. NetSuite term names must match Shopify's supported formats exactly. See the note in the Companies flow section above.
Locations not syncing
- Verify sub-customers are enabled in NetSuite (Setup > Company > Enable Features > CRM tab). If not enabled, the Locations flow cannot create Sub-Customer records and will error.
- Verify Companies have synced first. A Sub-Customer requires a parent Customer. If the Companies flow hasn't run or errored, Locations will fail with a "parent not found" error.
Orders not syncing
- Check for "No customer record found for Location" errors. This means the Locations flow hasn't yet synced those locations. Run the Locations flow, then retry the failed order records.
- Check for Item ID map gaps. If the order contains a line item with no matching NetSuite item (no Item ID map record), the import step will fail. Locate the failing SKU in the error log and create or re-run the Products flow to generate a map record for it.
- Verify the order has a purchasingEntity. The flow filters for B2B orders only. Consumer orders placed without a company association will not be picked up by this flow — they belong to the D2C Integration App.
Contacts not assigned to all locations
- Check the Default Contact Role setting is configured in integration settings.
- Review the Contacts flow run history for role assignment step errors. The assignment step runs after contact create/update — errors there will not fail the whole flow but will skip the assignment.
Catalog prices not updating
- Run the Products flow first. Catalogs C (Prices) depends on the Item ID Map being populated. If a Shopify variant has no map record, its price will not be updated. Run the Products flow and then re-run Catalogs C.
- Run Catalogs A before Catalogs C. The Catalog must exist in Shopify before prices can be written to it. Confirm Catalogs A has run successfully.
Refund errors
- Check "No Invoice for #[order] found" errors. The refunds flow looks up the original invoice by Shopify Order ID. Check the NetSuite Sales Order status — ensure your order-to-invoice workflow has run for this order, then retry.
- Check etailOrderCustomData on the Sales Order. The refunds flow reads this field (populated by the Orders flow) to apply per-line tax rates to the Credit Memo. If the Orders flow errored or was disabled when the original order came through, this field may be missing. Re-run the Orders flow for the affected order to re-populate it, then retry the refund.
OAuth token expirations
- Shopify Admin API tokens can become invalidated after an app uninstall/reinstall or changes to API scopes. When this happens, every flow using the Shopify connection will fail with an authentication error. Regenerate the access token in Shopify Admin > Apps > Develop apps, then update the Celigo connection.
- Only the account owner in Celigo can update connection credentials. Ensure the person who has access to both Shopify and the Celigo account is available if this occurs. Include this in your operations runbook.
- NetSuite TBA tokens do not expire automatically but should be rotated on a regular cadence (every 90–180 days is standard for security compliance). Schedule token rotation as a recurring maintenance task.
General debugging approach
- Find the failing record. In the Celigo flow dashboard, open the flow run that contains the error and locate the specific record(s) that failed. Each failed record has a detailed error log.
- Identify the failing step. Export failures indicate a connection or query issue. Lookup failures indicate a missing or non-matching record in the target system. Transformation failures indicate a mapping or scripting error. Import failures indicate a payload or permissions issue.
- For lookup failures: Find the saved search referenced by the failing step. Preview that search in NetSuite with the same filter values the flow used. If the search returns no results, the problem is the underlying data — the record does not exist or does not match the expected criteria.
- For transformation failures: Check any handlebars expressions in the mapping for typos, missing field references, or fields that are null in the source payload. The flow dashboard shows the source payload for each failing record — use it to verify which fields are actually populated.
- Fix before retrying in bulk. Retrying records against an unresolved root cause generates noise in your error logs and can create partial records. Resolve the underlying issue first, then retry.