Importing Customers

The Customers import creates and updates customers in your Shopify store — from a CSV/Excel file, a Google Sheet, or directly from another of your connected stores. Rows are matched by email (phone as a fallback), so running the same file twice updates the same customers instead of creating duplicates.

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

Operations

Step 1 of the wizard picks what the file does:

  • Create — new customers only; a row that matches an existing customer (by email, then phone) fails so you don't overwrite by accident.
  • Update — existing customers only; a row that matches nothing fails.
  • Upsert (the default) — creates or updates as needed. Re-runs are safe.
  • Delete — permission-gated and irreversible; see Deleting customers.

Columns

ColumnNotes
EmailThe customer's identity — how rows match existing customers.
PhoneE.164 format with country code (e.g. +4915112345678). Identity fallback when there's no email.
First Name, Last Name
NoteInternal note shown in Shopify admin.
TagsComma-separated. Replaces the customer's full tag list when provided; leave blank to keep existing tags.
Tax Exempttrue / false.
LanguageLocale code such as en or de.
Email Marketing: Statussubscribed, unsubscribed, or pending — see Marketing consent.
SMS Marketing: Statussubscribed or unsubscribed; requires a Phone on the same row.
Address …Address Line 1/2, Address City, Address Zip, Address Country Code, Address Province Code, Address Company, Address Phone, Address First/Last Name.

Shopify CSV and other common export headers are recognized automatically (First Name, Address Line 1, Email Marketing: Status, …) — files exported from those tools map without manual work.

Multiple addresses — one per row

Extra addresses go on follow-up rows that repeat the same Email, with only the address columns filled:

EmailFirst NameAddress Line 1Address City
jane@example.comJaneHome St 1Berlin
jane@example.comOffice Ave 2Hamburg

Rows for the same customer must be contiguous (right after each other).

Good to know: when a row group supplies any address, the customer's address list is replaced with exactly the addresses in the file. Rows with no address columns leave the existing address book untouched — so a profile-only update (say, just fixing tags) never deletes addresses.

Consent has legal weight, so the import is deliberately conservative:

  • Consent changes only when the file supplies an explicit status value. Blank cells never touch it.
  • Shopify only accepts subscribed, unsubscribed, or pending (email) and subscribed or unsubscribed (SMS) as written values. Export-side states like not_subscribed can't be written back — such rows are reported as errors rather than silently changed to something else.
  • SMS consent requires a Phone value on the same row.
  • An optional Email Marketing: Level column (single_opt_in, confirmed_opt_in) records how consent was collected; pending pairs with confirmed_opt_in automatically.

Importing from another store

On the wizard's Source step, pick From another store to use a connected store's synced customers as the rows — no file needed. You get a tag filter and a name/email/phone search, plus a live "N customers match" count that is computed by the exact same query the import will run.

  • Profiles, all addresses, tags, and writable marketing consent transfer.
  • Matching is still by email, so this doubles as a recurring one-way customer sync when combined with a schedule.
  • The rows come from EcomSolo's synced data for the source store — if the source store synced a while ago, sync it first for the freshest picture.

Dry run and results

The dry run classifies every row as create or update (based on whether the email already exists in the target store) and reports row errors before anything is written. After the run, the target store's Customers dashboard refreshes within seconds.

Sample file

A ready-to-run sample lives at features/importing/examples/customers-sample-wowstore.csv:

Email,First Name,Last Name,Tags,Email Marketing: Status,Address Line 1,Address City,Address Zip,Address Country Code
jane@example.com,Jane,Doe,vip,subscribed,Home St 1,Berlin,10115,DE
jane@example.com,,,,,Office Ave 2,Hamburg,20095,DE
ben@example.com,Ben,Miller,wholesale,,Main Rd 5,Munich,80331,DE

Dry run: will create 2 (Jane's second row is her second address).

Deleting customers

Pick the Delete operation in Step 1 (permission-gated) and upload a file with just the identity column(s) — matching works exactly like updates (Email first, Phone as the fallback). No other columns are needed.

The dry run shows a red "Will delete N"; rows that match no customer are skipped (no-ops), so re-running the same delete file is safe. Deleting a customer permanently removes them from Shopify — this cannot be undone. Shopify only deletes customers with no order history; a customer who has placed an order is reported as a per-row error rather than deleted (redact or anonymize them in the Shopify admin instead).

Troubleshooting

Error in the reportWhat it means / what to do
row requires an Email or Phone to identify the customerEvery row (or row group) needs one of the two identity columns filled.
marketing status '…' can't be writtenOnly subscribed / unsubscribed (/ pending for email) can be imported — see Marketing consent.
SMS marketing consent requires a Phone column valueAdd the customer's phone number to the row, or clear the SMS status cell.
Email has already been takenAnother customer in the store already uses that email with a different identity — check for near-duplicates in Shopify.
Phone … is invalidUse E.164 format: + country code, then the number, no spaces.

FAQ

Will re-importing create duplicates? No — rows are matched by email (then phone), and the underlying Shopify operation is an upsert. Re-runs update in place.

Does it delete customers? Only if you choose the Delete operation, which is permission-gated and irreversible — see Deleting customers. The default Upsert never deletes.

Are order history or spend totals affected? Never — those come from the customer's actual orders and can't be imported.