Importing Orders

The Orders import creates and updates orders from a CSV/Excel file, a Google Sheet, or directly from another connected store. It's built for migrating historical orders — an order usually has several line items, so the import uses one row per line item: rows that share the same Name belong to the same order.

For the wizard itself — uploading, mapping, dry runs, schedules — see Importing into EcomSolo.

Imported orders are inert by design. Creating an order here never sends the customer an order confirmation, never sends a fulfillment/shipping notification, never captures payment, and never decrements inventory. Every imported order is tagged imported and carries a sourceName so it's easy to tell apart from a live checkout.

How an order is laid out

Each order is a group of consecutive rows sharing the same Name (e.g. #1001). The first row of the group carries the order-level fields (email, status, dates, addresses, note, tags); every row carries one line item.

Unlike draft orders, Name is not just a grouping column — it's the order number itself and the upsert key. orderCreate lets us set it, so a migrated order keeps its original number and a re-import matches it.

How orders are matched

Matching for updates is by Name (the order number):

  1. Name — an existing order with the same Name → update.
  2. Otherwise a new order is created with that Name.

So a file is safely re-runnable: the same Name updates in place instead of creating a duplicate. The default operation is Upsert; Create only, Update only, Merge (partial update) and Delete all match by Name the same way. See Choosing the operation for how each one behaves.

What an update can change: Shopify forbids editing line items, pricing, or status on an order that already exists — so on a re-import only the editable fields are updated: Note, Tags, Email, and PO number. Everything else (line items, financial/fulfillment status, dates) is written once, at create time.

Columns

Order-level (first row of each Name group):

ColumnNotes
NameThe order number, e.g. #1001. Required — it's the upsert key.
EmailCustomer email for the order.
Financial StatusSet on create only. One of PENDING, AUTHORIZED, PARTIALLY_PAID, PAID, PARTIALLY_REFUNDED, REFUNDED, VOIDED, EXPIRED. An unrecognized value is dropped (the order still lands).
Fulfillment StatusSet on create only. Shopify accepts only FULFILLED, PARTIAL, or RESTOCKED here — there is no UNFULFILLED; leave the cell blank (or use UNFULFILLED, which we drop) for an unfulfilled order.
Processed AtThe order's original date (ISO 8601, e.g. 2024-03-01T10:00:00Z) — so migrated history keeps its real dates.
Currencye.g. USD. Needed for custom line-item prices.
NoteOrder note (editable on re-import).
TagsComma-separated. imported is always added. (editable on re-import).
PO NumberPurchase-order number (editable on re-import).
Source NameWhere the order came from; defaults to ecomsolo-import.
Shipping / BillingFull address blocks (First/Last Name, Company, Address 1/2, City, Province Code, Country Code, Zip, Phone).

Line-item (every row):

ColumnNotes
Line: SKUA product SKU — resolved to the target store's variant automatically (the cross-store-friendly option).
Line: Variant IDThe target variant's Shopify GID — the most direct product match.
Line: TitleFor a custom line item (no product). Needs a Currency on the order to carry a price.
Line: PriceUnit price for the line.
Line: QuantityQuantity for the line (defaults to 1).

A line resolves in order: Variant ID → SKU → custom (Title + Price). A SKU that doesn't exist in the target store falls back to a custom line item if it has a Title, so the order total stays correct.

Importing from another store

On the wizard's Source step, pick From another store to copy orders from a connected store. Each source order comes across as its set of line-item rows (line items carried by SKU so the target re-matches its own variants; unmatched lines keep title + price as custom items), with financial/fulfillment status, dates, addresses, note and tags. Matched by Name. Combined with a schedule this becomes a recurring one-way order sync.

Deleting orders

Pick the Delete operation in Step 1 (permission-gated) and upload a file with just the Name column — each order number is matched exactly like an update:

Name
#1001
#1002

The dry run shows a red "Will delete N" count; a Name that matches nothing is skipped (so re-running the same delete file is safe). Deleting an order removes it from Shopify permanently — this cannot be undone. Note that Shopify only allows some orders to be deleted (for example, an order with an open or partial fulfillment is refused); those rows fail with Shopify's reason in the report while the rest of the run continues.

Results and freshness

Orders you create or update take effect in Shopify immediately, and EcomSolo's Orders dashboard refreshes within seconds of the run.

Sample file

A ready-to-run sample covering every case lives at features/importing/examples/orders-sample.csv:

Name,Email,FinancialStatus,FulfillmentStatus,ProcessedAt,Currency,Note,Tags,Shipping.FirstName,Shipping.LastName,Shipping.Address1,Shipping.City,Shipping.ProvinceCode,Shipping.CountryCode,Shipping.Zip,LineItems.SKU,LineItems.Title,LineItems.Price,LineItems.Quantity
#1001,jane@example.com,PAID,FULFILLED,2024-03-01T10:00:00Z,USD,VIP order,"wholesale,priority",Jane,Doe,1 Home St,Berlin,,DE,10115,HAT-01,,19.00,2
#1001,,,,,,,,,,,,,,,SHOE-09,,49.00,1
#1002,ben@example.com,PENDING,UNFULFILLED,2024-04-15T14:30:00Z,USD,,,,,,,,,,,Gift wrapping,15.00,1
#1002,,,,,,,,,,,,,,,MUG-03,,9.00,4
#1003,sam@example.com,PAID,FULFILLED,2024-05-20T09:00:00Z,USD,,,Sam,Lee,5 Main Rd,Munich,,DE,80331,BOOK-77,,12.00,1
#EXP-90001,leon@example.com,PAID,FULFILLED,2021-09-09T01:48:00Z,USD,Migrated order,"imported-history,vip",Leon,Meyer,10 Market Rd,Hamburg,,DE,20095,HAT-01,Wool Hat,19.00,2
#EXP-90001,,,,,,,,,,,,,,,SHOE-09,Running Shoe,49.00,1
#EXP-90002,mia@example.com,PENDING,UNFULFILLED,2021-10-01T09:00:00Z,USD,Custom services order,,,,,,,,,,Consulting fee,99.00,1

Row by row: orders #1001#1003 use classic order numbers — every Shopify store already numbers its own orders from #1001, so these match an existing order and take the update path (note/tags/email change; status and line items are locked). Orders #EXP-90001 and #EXP-90002 use non-classic names that won't exist yet, so they exercise the create path: #EXP-90001 is a full historical order (two lines, shipping address, paid & fulfilled, dated in 2021) and #EXP-90002 is a single custom-line order. Because line resolution is Variant ID → SKU → custom, #EXP-90001's lines carry both a SKU and a Title, so they land as product lines when the SKU exists on the target and fall back to custom lines when it doesn't. Re-running the file updates all five in place — it never creates a second #1001 or #EXP-90001.

Troubleshooting

Error in the reportWhat it means / what to do
row requires an order NameEvery row needs the Name column filled (or grouped under a first row that has it).
order has no line itemsNo row in the group had a Variant ID, a SKU that exists on the target, or a custom Title.
a line item couldn't be matched by SKU '…' and has no TitleThe SKU isn't on the target store; add a Line: Title so it becomes a custom line item.
no existing order named '…' to updateYou ran in Update mode but no order with that Name exists yet — run in Create/Upsert mode first.

FAQ

Will re-importing create duplicates? No — matching is by Name, so the same order number updates in place.

Can I change line items on an existing order? No. Shopify locks line items, pricing and status once an order exists — a re-import only updates note, tags, email and PO number.

Will importing an order email the customer or charge them? No. Imported orders never send notifications, never capture payment, and never move inventory.

Can I delete orders? Yes — pick the Delete operation and upload a file of order Names. See Deleting orders. It's permission-gated and irreversible, and Shopify refuses to delete some orders (e.g. ones with open fulfillments).

Can I add products by SKU? Yes — Line: SKU is resolved to the target store's variant. A SKU missing on the target becomes a custom line item (if it has a title) so the order total is preserved.