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
| Column | Notes |
|---|---|
| The customer's identity — how rows match existing customers. | |
| Phone | E.164 format with country code (e.g. +4915112345678). Identity fallback when there's no email. |
| First Name, Last Name | |
| Note | Internal note shown in Shopify admin. |
| Tags | Comma-separated. Replaces the customer's full tag list when provided; leave blank to keep existing tags. |
| Tax Exempt | true / false. |
| Language | Locale code such as en or de. |
| Email Marketing: Status | subscribed, unsubscribed, or pending — see Marketing consent. |
| SMS Marketing: Status | subscribed 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:
| First Name | Address Line 1 | Address City | |
|---|---|---|---|
| jane@example.com | Jane | Home St 1 | Berlin |
| jane@example.com | Office Ave 2 | Hamburg |
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.
Marketing consent
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, orpending(email) andsubscribedorunsubscribed(SMS) as written values. Export-side states likenot_subscribedcan'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;pendingpairs withconfirmed_opt_inautomatically.
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 report | What it means / what to do |
|---|---|
row requires an Email or Phone to identify the customer | Every row (or row group) needs one of the two identity columns filled. |
marketing status '…' can't be written | Only subscribed / unsubscribed (/ pending for email) can be imported — see Marketing consent. |
SMS marketing consent requires a Phone column value | Add the customer's phone number to the row, or clear the SMS status cell. |
Email has already been taken | Another customer in the store already uses that email with a different identity — check for near-duplicates in Shopify. |
Phone … is invalid | Use 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.