Import Orders into Shopify from an ERP: Best Practices, Gotchas & APIs

Import Orders into Shopify from an ERP: Best Practices, Gotchas & APIs

Import Orders into Shopify from an ERP: Best Practices, Gotchas & APIs

Written by
Selo A.

Why ERP-to-Shopify Order Import Is More Complex Than It Looks

Most Shopify merchants create orders through their storefront — a customer clicks "Buy," Shopify processes the payment, and the order appears in the admin. But enterprise merchants often need to push orders into Shopify from an ERP system. Wholesale orders placed via phone or email, B2B orders managed in SAP or NetSuite, or marketplace orders routed through a central ERP all need to land in Shopify for fulfillment, inventory deduction, and customer communication.

The challenge is that Shopify's order model was designed for storefront-originated transactions. Importing external orders means working around assumptions about payment capture, inventory reservation, and customer notification that don't apply when the order originates elsewhere. Get it wrong, and you'll face duplicate charges, phantom inventory holds, or customers receiving unexpected confirmation emails.

Shopify's Order Creation APIs: orderCreate vs. Draft Orders

Shopify provides two primary paths for creating orders programmatically. The orderCreate mutation (GraphQL Admin API) creates a fully formed order in one call. You specify line items, shipping address, financial status, and fulfillment status. This is the preferred method for ERP imports because it gives you explicit control over how Shopify treats the order's payment and fulfillment state.

The alternative is the Draft Orders API. Draft orders act as order proposals — they exist in a pending state until explicitly completed. This is useful when you need human review before the order becomes "real" in Shopify, or when you need to send an invoice to the customer for payment. However, draft orders add an extra step to the workflow and aren't ideal for high-volume automated imports.

When to Use Each Approach

Use orderCreate when orders arrive from the ERP fully confirmed and paid. The ERP is the system of record for payment, and Shopify simply needs to know the order exists for fulfillment purposes. Set financial_status: "paid" and fulfillment_status: null so Shopify knows payment is settled but fulfillment hasn't started.

Use Draft Orders when the order requires review, price adjustment, or customer payment through Shopify. This is common for B2B scenarios where a sales rep creates the order and the customer pays via invoice link. Draft orders also support discount application and tax recalculation before finalization.

Payment Mapping: The Most Common Source of Errors

The single biggest mistake in ERP order imports is mishandling the payment status. When you create an order via orderCreate, you must explicitly tell Shopify whether payment has been collected. If you don't set financial_status correctly, Shopify may attempt to capture payment on a gateway that has no corresponding authorization — or mark the order as unpaid when the ERP has already collected funds.

Financial Status Options

Shopify supports several financial statuses: paid (payment fully collected), pending (payment expected but not yet received), authorized (payment authorized but not captured), and partially_paid. For ERP imports where payment was collected outside Shopify, always use paid. For B2B net-terms orders, use pending and track payment status in your ERP.

A critical detail: when importing orders with financial_status: "paid", include a transaction record that documents the payment. Without this, Shopify's financial reports won't reconcile. Specify the gateway as "manual" or "external" and include the amount. This creates a proper audit trail even though the payment didn't flow through Shopify's payment infrastructure.

Suppressing Customer Notifications

By default, Shopify sends order confirmation emails when a new order is created. For ERP imports, this is almost never desirable — the customer already received their confirmation from the original sales channel. Sending a second confirmation from Shopify is confusing at best and damages customer trust at worst.

When using orderCreate, set send_receipt: false and send_fulfillment_receipt: false. For draft orders, avoid calling the "send invoice" endpoint unless you explicitly want the customer to receive a payment link. Test this thoroughly in a development store before going live — accidental customer emails during integration testing are a common and embarrassing mistake.

Idempotency: Preventing Duplicate Orders

Network failures, API timeouts, and retry logic can all cause the same order to be submitted to Shopify multiple times. Without idempotency controls, you'll end up with duplicate orders that inflate revenue reports, trigger duplicate fulfillments, and confuse warehouse staff.

Idempotency Keys

Shopify's GraphQL mutations support idempotency keys via the X-Shopify-Idempotency-Key header. Send a unique key (typically the ERP order number) with each request. If Shopify receives a second request with the same key within 60 seconds, it returns the result of the first request instead of creating a duplicate.

However, idempotency keys have a 60-second window. For broader protection, implement a pre-check pattern: before creating an order, query Shopify for existing orders with a matching reference number stored in a metafield or tag. This catches duplicates even if the retry happens hours or days later.

Using Tags and Metafields for Cross-Reference

Store the ERP order number as both a Shopify order tag and a metafield. Tags are searchable from the admin UI (useful for support teams), while metafields provide structured data for API queries. Use a consistent namespace like erp.order_number for the metafield. Before every import, query: "Does an order with this ERP reference already exist?" If yes, skip creation and log the duplicate attempt.

Line Item Mapping and Product Resolution

ERP systems identify products by internal SKU codes, while Shopify uses variant IDs. Your integration must resolve ERP SKUs to Shopify variant IDs before creating orders. This mapping is a common failure point — a SKU might exist in the ERP but not yet be created in Shopify, or the SKU format might differ between systems.

Build a SKU resolution layer that queries Shopify's product catalog by SKU and caches the results. Handle mismatches gracefully: if a SKU can't be resolved, queue the order for manual review rather than failing silently or creating an order with missing line items. Log every resolution failure so your operations team can fix the root cause (usually a product that hasn't been synced yet).

Inventory Impact and Location Routing

When Shopify receives a new order, it decrements inventory at the assigned fulfillment location. For ERP imports, you need to control which location fulfills the order — especially if you operate multiple warehouses. Use the fulfillment_orders API to assign the correct location based on the ERP's warehouse assignment.

Be cautious about inventory timing. If your ERP already decremented inventory when the order was placed, and Shopify also decrements on order creation, you'll double-count the reduction. The solution depends on which system is the inventory master. If the ERP owns inventory, disable Shopify's automatic inventory tracking for imported orders and sync inventory levels separately. If Shopify owns inventory, let the order creation handle the decrement naturally.

Reconciliation Workflows

Even with idempotency controls and careful mapping, discrepancies will occur. Build a daily reconciliation process that compares orders in both systems. Count orders created in the ERP against orders received in Shopify. Flag any mismatches — missing orders, duplicate orders, or orders with different totals — for manual investigation.

Key metrics to track: import success rate (percentage of ERP orders that successfully land in Shopify), average import latency (time between ERP order creation and Shopify order creation), duplicate rate (percentage of import attempts that hit an existing order), and SKU resolution failure rate. Dashboard these metrics and set alerts for anomalies.

How Galantis Connect Handles ERP Order Import

Galantis Connect simplifies order import with its visual field mapping interface. Instead of writing custom code to translate ERP order fields to Shopify's API schema, you map fields visually — drag the ERP's "CustomerPO" field to Shopify's order tag, map "NetAmount" to the transaction amount, and route "WarehouseCode" to the correct fulfillment location.

The platform's rule engine handles the conditional logic that makes order import tricky. Set rules like "if payment_method = 'NET30', set financial_status to 'pending'" or "if source_channel = 'wholesale', suppress customer notifications." These rules execute before the order hits Shopify, ensuring every import is correctly configured without custom middleware.

Built-in idempotency and duplicate detection are automatic. Galantis Connect tracks every ERP order number it processes and prevents re-submission. If a network failure interrupts an import, the retry system picks up exactly where it left off — no duplicate orders, no missing data. Run-level logs show exactly what happened with each order, making reconciliation straightforward.

Getting Started with ERP Order Import

Start with a single order type — typically the highest-volume, most predictable flow like paid wholesale orders. Map the fields, configure payment status rules, and run a batch of test orders through a Shopify development store. Verify that financial status, inventory impact, and customer notifications all behave correctly before expanding to more complex scenarios like partial payments or multi-location fulfillment.

Ready to stop writing custom order import code? Galantis Connect gives you visual mapping, automatic duplicate prevention, and full audit trails for every order that flows from your ERP to Shopify. See how it works at galantis.io.

Written by
Selo A.

Unified tools. Unmatched power.

Unified tools. Unmatched power.

Sync your marketplace, ERP, shipping, and finance tools — no more manual updates or errors.

100% free, no strings attached.

Unified tools. Unmatched power.

Sync your marketplace, ERP, shipping, and finance tools — no more manual updates or errors.

100% free, no strings attached.

Sign up and stay updated

Sign up and stay updated

English

© DigiFist 2026. All rights reserved.

Built by DigiFist • Leading Shopify Premier Partner powering 5,000+ Merchants • 3 Global Offices