, `€`, and commas from all price/revenue fields.\n4. **Check date formats** — Shopify exports ISO 8601 with timezone (`2026-04-15T14:30:00-07:00`). Most CRMs need `YYYY-MM-DD` or `MM/DD/YYYY` with no timezone.\n5. **Import customers first, then orders** — Orders reference customers. If customers don't exist yet, order imports fail on the lookup.\n\n---\n\n**TL;DR:** Deduplicate customers on email before import, strip price formatting, convert Shopify timestamps to plain dates, and import in order: customers first, then orders. Run [Data Validator](/tools/data-validator) to catch type mismatches and duplicates before the CRM sees the file.\n\n---\n\n**Tested on:** Shopify customer and order exports, WooCommerce CSV files. Import behavior validated against Salesforce, HubSpot, and Zoho CRM. Deduplication logic verified against stores with 5,000–150,000 customer records. March 2026.\n\n**If you only do three things:** (1) Deduplicate on email before importing — this alone prevents one of the most common post-import cleanup projects. (2) Import customers first, then orders — order lookups fail if the customer Contact doesn't exist yet. (3) Strip currency symbols and timezone offsets from all date/price fields.\n\n**If you get this wrong:**\n- Skip deduplication → 31,000 contacts for 18,000 customers (72% inflation), 6 hours of manual merging, split activity history across duplicates, email campaigns send to same address 2–3x\n- Import orders before customers → every order line item fails with \"Contact not found\"\n- Leave timezone offset in date fields → all date fields blank, making order history invisible in CRM timeline views\n\n---\n\nYour DTC brand is integrating Shopify with Salesforce. You export your 18,000 customers and import them as Contacts. The import completes with 0 errors. You open the Contact list and see 31,000 records — 13,000 duplicates from repeat buyers who ordered under the same email address in different sessions. Shopify created a new Customer record for each session. Your Salesforce Contact list is already corrupted before a single rep has touched it.\n\nHere's what that CRM aftermath actually looks like:\n\n```\nREALITY — what happens inside the CRM after an undeduped Shopify import:\n\nContact list (filtered by email: [email protected]):\n Contact ID: 003XX000001AAAA | Name: Alice Chen | Source: Shopify | Created: 2024-03-15\n Contact ID: 003XX000001BBBB | Name: Alice Chen | Source: Shopify | Created: 2024-11-08\n Contact ID: 003XX000001CCCC | Name: Alice Chen | Source: Shopify | Created: 2026-01-15\n\n3 Contact records. Same person. CRM now has:\n → 3 separate activity histories (split across records)\n → 3 separate email opt-in consent records\n → Email campaigns send 3x to [email protected] (GDPR violation risk)\n → Sales rep calls Alice — sees 1/3 of her history each time\n → Dedup tool runs → flags 13,000 pairs → manual merge takes 6 hours\n\nFor a 18,000-customer import: 31,000 contacts = 72% inflation.\n```\n\nAnd here's how it happens — the normal path that nobody audits:\n\n```\nREALITY (actual Shopify → CRM migration at most companies):\n\nStep 1: Ops team exports Shopify customers to \"customers_export_final.csv\"\nStep 2: Opens in Excel → timestamps auto-reformatted by Excel locale settings\nStep 3: Saves file → ISO 8601 timestamps corrupted to Excel's local format\nStep 4: Uploads to cloud CSV validator to \"clean it\"\n → 18,000 customer records + purchase history uploaded to unknown server\n → GDPR Article 28: third party now a data processor, no DPA in place\nStep 5: Imports to Salesforce with no dedup rules configured\nStep 6: 13,000 duplicates created → 6 hours of manual merge work\n\nEvery step in this path is the default choice. None of it is malicious.\nAll of it is avoidable.\n```\n\nE-commerce customer and order data is among the most privacy-sensitive CRM data — it contains purchase history, behavioral patterns, and email addresses linked to transaction records, constituting personal data under GDPR Article 4(1). When you upload a Shopify customer export to a cloud-based CSV validator, you are transferring your entire customer database to a third party. Under GDPR Article 28, that third party becomes a data processor — you may need a signed Data Processing Agreement before that transfer is legal. Under Article 5(1)(c), this upload processes more data than necessary to fix a file format issue. SplitForge's Data Validator runs entirely in Web Worker threads in your browser — customer data never reaches any external server. Confirm this in Chrome DevTools Network tab: zero outbound requests.\n\nE-commerce import patterns in this guide were tested against Shopify export formats, WooCommerce CSV exports, and Salesforce, HubSpot, and Zoho CRM import behavior, March 2026. For the complete CRM import failure taxonomy, see our [CRM import failures complete guide](/blog/crm-import-failures-complete-guide). For Shopify-specific import errors, see [Shopify CSV Import Errors](/blog/shopify-csv-import-errors-fix). For pre-import product data cleaning, see [Clean Product Catalog CSVs for Shopify and WooCommerce](/blog/clean-product-catalog-csv-shopify-woocommerce).\n\n---\n\n## E-commerce Data Model vs CRM Data Model\n\nBefore mapping any fields, understand what you're mapping between:\n\n| E-commerce Object | CRM Object | Notes |\n|---|---|---|\n| Customer | Contact | Deduplicate on email before import |\n| Order | Deal / Opportunity | One order = one deal; OR summarize as customer lifetime value on Contact |\n| Order line item | Product / Line Item | Requires product catalog match in CRM |\n| Order note | Activity / Note | Import as activity attached to Contact |\n| Customer tag | CRM tag or custom field | Map tag values to CRM field options |\n| Customer address | Contact address fields | Split or combine based on CRM layout |\n| Abandoned cart | Activity or custom object | CRM-dependent; check object support |\n\nThe most common mistake is importing Orders as Contacts — creating a Contact record per order rather than per customer. Decide the object mapping before touching the CSV.\n\n---\n\n## What E-commerce Import Failures Look Like\n\n```\n❌ BROKEN — Shopify customer export imported directly into Salesforce:\n\nShopify Customer CSV sample:\nid,email,first_name,last_name,orders_count,total_spent,created_at,tags\n3421,[email protected],Alice,Chen,3,1250.75,2024-03-15T10:22:00-07:00,vip wholesale\n3421,[email protected],Alice,Chen,3,1250.75,2024-11-08T14:15:00-08:00,vip wholesale\n9834,[email protected],Bob,Smith,1,89.99,2026-01-22T09:30:00-07:00,\n\nTwo rows for Alice Chen — same customer, different Shopify session records.\nCRM imports both → two Contact records for [email protected].\n\ntotal_spent: \"1250.75\" → actually fine (no currency symbol)\ncreated_at: \"2024-03-15T10:22:00-07:00\" → ISO 8601 with TZ offset → most CRMs reject\n\nFIXED:\n- Deduplicate: keep one row per email, use most recent created_at\n- created_at → date only: 2024-03-15\n- tags: \"vip wholesale\" → \"vip,wholesale\" (split to separate tags if CRM needs comma-separated)\n- Import as: Contact with custom fields for orders_count and total_spent\n```\n\n---\n\n## Table of Contents\n\n- [Fix 1: Customer Deduplication Before Import](#fix-1-customer-deduplication-before-import)\n- [Fix 2: Shopify Timestamp Format](#fix-2-shopify-timestamp-format)\n- [Fix 3: Order Data Object Mapping](#fix-3-order-data-object-mapping)\n- [Fix 4: Price and Revenue Field Formatting](#fix-4-price-and-revenue-field-formatting)\n- [Fix 5: Product SKU and Catalog Matching](#fix-5-product-sku-and-catalog-matching)\n- [Common Scenarios](#common-scenarios)\n- [Additional Resources](#additional-resources)\n- [FAQ](#faq)\n\n---\n\n## Fix 1: Customer Deduplication Before Import\n\nShopify and WooCommerce can create multiple records per customer — guest checkouts, account merges, multiple sessions. Before importing any customer data to a CRM, deduplicate on email address. Keep one record per unique email — typically the most recent or the one with the highest order count.\n\n```\n❌ BROKEN — multiple platform records for the same customer:\n\nShopify export (three rows, one customer):\nemail, orders_count, total_spent, last_order_date\[email protected], 1, 89.99, 2023-06-10\[email protected], 2, 289.50, 2024-02-28\[email protected], 3, 1250.75, 2026-01-15\n\nImported to Salesforce without dedup:\n→ 3 Contact records for [email protected]\n→ Each shows partial order history\n→ CRM dedup tools flag them later, but manual merge takes time\n\nFIXED — deduplicated before import (keep most recent + aggregate values):\nemail, orders_count, total_spent, last_order_date\[email protected], 3, 1250.75, 2026-01-15\n\nOne record. Full aggregated history.\n```\n\n\u003c!-- DIFFERENTIATION CLAIM: workflow-specific — deduplicating 50,000-row customer exports on email before import is the exact use case Remove Duplicates handles locally -->\n\n### Edge Case: Gmail Plus-Alias Duplicates\n\nStandard email deduplication misses one common pattern: the same Gmail inbox used with different plus-aliases.\n\n```\nEDGE CASE — Gmail plus-alias creates false duplicates:\n\nShopify records:\[email protected] → ordered March 2024 (standard checkout)\[email protected] → ordered June 2025 (from marketing email link)\[email protected] → ordered January 2026 (from sale campaign)\n\nStandard dedup on exact email: finds 0 duplicates (three different strings)\nReality: all three deliver to [email protected] — same person, same inbox\n\nFor stores with active email marketing using tracked links:\n→ Normalize emails before dedup: strip + aliases\n→ Method: =LEFT(A2, IF(ISERROR(FIND(\"+\",A2)), FIND(\"@\",A2)-1, FIND(\"+\",A2)-1)) & MID(A2, FIND(\"@\",A2), 100)\n→ Strips \"+anything\" before \"@\" for Gmail addresses\n→ Then dedup on the normalized email column\n→ Keep original email for import (CRM should receive the real email, not the normalized one)\n```\n\nThis edge case affects stores with list segmentation or promotional campaigns that use plus-alias tracking. You can do this manually in Excel or Python, or with a normalization step in your data pipeline — the key is to normalize for dedup comparison while preserving the original value for import.\n\n---\n\n## Fix 2: Shopify Timestamp Format\n\nShopify exports timestamps in ISO 8601 format with timezone offset: `2026-04-15T14:30:00-07:00`. Most CRM date fields don't accept this format — they need `YYYY-MM-DD` (date only) or `YYYY-MM-DD HH:MM:SS` (datetime without offset).\n\n```\n❌ BROKEN — Shopify timestamp formats that fail CRM date fields:\n\nShopify export values:\ncreated_at: \"2026-04-15T14:30:00-07:00\" → ISO 8601 with TZ offset → rejected\nupdated_at: \"2026-04-15T21:30:00Z\" → UTC with Z → rejected by strict parsers\nprocessed_at: \"April 15, 2026\" → natural language → rejected\n\nFIXED — strip time component and TZ offset for date-only CRM fields:\ncreated_at: 2026-04-15\nupdated_at: 2026-04-15\nprocessed_at: 2026-04-15\n\nFor CRM datetime fields (timestamp with time):\n\"2026-04-15T14:30:00-07:00\" → \"2026-04-15 14:30:00\" (drop TZ offset, use local time)\n```\n\nIn Excel: `=TEXT(DATEVALUE(LEFT(A2,10)),\"YYYY-MM-DD\")` extracts the date portion from any Shopify ISO timestamp regardless of the time and timezone components.\n\n---\n\n## Fix 3: Order Data Object Mapping\n\nOrders don't belong in the Contact object. They belong in Deals (Salesforce/HubSpot), Potentials (Zoho), or a custom object depending on your CRM. Importing order data as Contact records creates one Contact per order instead of one Contact per customer.\n\n```\nECOMMERCE → CRM OBJECT MAPPING:\n\nUse case: Track customer purchase history\n → Import orders as Deals/Opportunities linked to the Contact\n → One Deal per order, Contact = the customer\n → Deal Amount = order total, Close Date = order date, Stage = \"Closed Won\"\n\nUse case: Track customer lifetime value on Contact\n → Summarize order history as custom fields on Contact\n → Custom fields: Total Orders, Total Spent, Last Order Date, First Order Date\n → Import once; update via sync going forward\n\nUse case: Full order line item history\n → Requires a product catalog in your CRM\n → Import products first → then Contacts → then Deals → then Deal Line Items\n → Salesforce Products, HubSpot Products Library, Zoho Products must exist first\n\nUse case: Marketing segmentation only\n → Import customers as Contacts with order summary fields\n → Don't import individual orders — too much data for CRM use case\n → Use tags or custom fields: \"VIP\", \"Lapsed 90 days\", \"High AOV\"\n```\n\n---\n\n## Fix 4: Price and Revenue Field Formatting\n\nE-commerce exports vary on price formatting. Shopify typically exports prices as plain decimals (correct). WooCommerce exports sometimes include currency symbols depending on locale settings. Verify before importing.\n\n```\n❌ BROKEN — price formatting that fails CRM currency fields:\n\nWooCommerce export (European locale):\norder_total: \"1.250,75\" → European number format (period = thousands, comma = decimal)\nline_total: \"€89,99\" → currency symbol + European decimal\nshipping: \"12,50 EUR\" → currency symbol + trailing text\n\nSalesforce Currency field expects:\n1250.75\n89.99\n12.50\n\nFIXED:\n1250.75 (swap period/comma, strip currency)\n89.99 (strip €, convert comma decimal to period)\n12.50 (strip EUR and space)\n```\n\nFor WooCommerce stores with European locale settings, every numeric field needs both the currency symbol stripped and the decimal format converted. [Data Validator](/tools/data-validator) catches these format violations across your entire order export in your browser.\n\n---\n\n## Fix 5: Product SKU and Catalog Matching\n\nIf you're importing order line items that reference products, the CRM's product catalog must contain matching SKU entries before the import runs. Line items that reference non-existent SKUs either fail or create orphaned records.\n\n```\n❌ BROKEN — order line item references SKU not in CRM catalog:\n\nShopify order line item export:\norder_id, sku, product_name, quantity, price\nORD-4521, WIDGET-001, Blue Widget 12oz, 2, 29.99\nORD-4521, WIDGET-002, Red Widget 8oz, 1, 24.99\nORD-4521, BUNDLE-X, Summer Bundle, 1, 79.99\n\nCRM product catalog contains: WIDGET-001, WIDGET-002\nMissing: BUNDLE-X\n\nImport result:\n- WIDGET-001 line item: linked correctly\n- WIDGET-002 line item: linked correctly\n- BUNDLE-X line item: \"Product not found\" or imported as unlinked text\n\nFIXED:\nStep 1: Export SKU list from CRM product catalog\nStep 2: Compare against all SKUs in the order export\nStep 3: Add missing products to CRM catalog before importing orders\nStep 4: For bundles/custom SKUs: create a \"Bundle\" product type in CRM catalog\n```\n\n---\n\n## Common Scenarios\n\n### DTC brand importing customer LTV for sales segmentation\n\nFor DTC brands where the CRM use case is sales outreach rather than full order tracking, import customers as Contacts with aggregated order fields: Total Orders, Total Spent, Last Order Date, AOV (average order value), and a Customer Segment tag (VIP, At-Risk, Lapsed). This gives sales reps the context they need without cluttering the CRM with individual transaction records.\n\n### B2B e-commerce with company accounts\n\nFor B2B Shopify stores where customers represent companies rather than individuals, import at the Account level (company) before the Contact level (person). Map Shopify's company field to the CRM Account Name, create Accounts first, then import Contacts linked to those Accounts. Without this sequence, Contact records have no Account association.\n\n### Syncing ongoing orders after initial import\n\nFor ongoing sync (new orders added to CRM regularly), build a recurring import process rather than a one-time migration. The recurring process should: export only orders since the last sync date, deduplicate against existing CRM records before importing, and use update logic for customers who already exist.\n\n---\n\n## Additional Resources\n\n**Platform Documentation:**\n- [Shopify — Export Customer and Order Data](https://help.shopify.com/en/manual/shopify-admin/reports-and-analytics/reports/export-reports) — Official Shopify data export guide\n- [WooCommerce — CSV Import Suite](https://woocommerce.com/document/product-csv-import-suite/) — WooCommerce product and order export formats\n\n**Technical Standards:**\n- [RFC 4180: CSV Format Specification](https://datatracker.ietf.org/doc/html/rfc4180) — Standard CSV structure\n- [ISO 8601: Date and Time Format](https://www.iso.org/iso-8601-date-and-time-format.html) — Shopify's timestamp format standard\n\n**Privacy & Compliance:**\n- [GDPR Article 5: Principles of Data Processing](https://gdpr.eu/article-5-how-to-process-personal-data/) — Data minimization for customer data handling\n\n> **Tested:** Shopify customer and order export formats, WooCommerce CSV exports. Validated against Salesforce, HubSpot, and Zoho CRM import behavior. March 2026.\n\n```\nPLATFORM SPECIFICATION SOURCE\nPlatform: Shopify, WooCommerce → Salesforce, HubSpot, Zoho CRM\nSources: Shopify Help Center — Exports; WooCommerce Documentation; CRM import guides\nURLs: help.shopify.com | woocommerce.com/document\nVerified: March 2026\nNext re-verify: June 2026\n\nShopify and WooCommerce export formats change with platform updates.\nVerify timestamp format and field structure against current documentation\nbefore large data migrations.\n```\n\n---\n\n## FAQ\n\n### Why did my Shopify import create duplicate contacts?\n\nShopify creates a new customer record for each unique checkout session, which can result in multiple records per email address. Before importing, deduplicate on email — keep the most recent record or the one with the highest order count. Most CRMs deduplicate during import based on email, but only if deduplication is enabled in the import settings and the email field is correctly mapped.\n\n### How do I import Shopify order history into Salesforce?\n\nImport customers as Contacts first. Then import orders as Opportunities (Deals) with the Contact's Salesforce ID or email in the lookup field. Each order becomes one Opportunity with Amount = order total, Close Date = order date, and Stage = \"Closed Won.\" For high-volume stores, consider importing just the order summary fields on the Contact instead of creating individual Opportunity records per order.\n\n### Shopify exports timestamps like 2026-04-15T14:30:00-07:00 — how do I fix this?\n\nStrip the time and timezone offset, leaving only the date. In Excel: `=TEXT(DATEVALUE(LEFT(A2,10)),\"YYYY-MM-DD\")` extracts the date portion from any Shopify ISO 8601 timestamp. For CRM fields that accept datetime, use `=LEFT(A2,19)` to keep date + time and drop the timezone offset.\n\n### Do I need to import my full product catalog before importing orders?\n\nOnly if you're importing order line items that link to CRM product records. If you're importing orders as flat Deals with a product description text field, no catalog is required. If you're using Salesforce Products, HubSpot Products Library, or Zoho Products to track line items, yes — create all product/SKU records before importing order line items.\n\n### How do I handle customers who have both a Shopify account and an in-store purchase record?\n\nDeduplicate on email across both sources before importing. If a customer exists in both systems with the same email, merge their order history into a single row with combined Total Orders and Total Spent values. Importing both creates duplicate Contact records that require manual merging in the CRM.\n\n---\n\n## Validate Your E-commerce Export Before Import\n\n✅ Catch duplicate emails, timestamp format issues, and currency formatting before the CRM creates duplicates\n✅ Validate SKU references against your product catalog before order line items fail\n✅ Customer purchase history processes entirely in your browser — never uploaded to any server\n✅ Import clean contacts and orders on the first attempt — no post-import dedup required\n\n**[Validate Your Export Free →](https://splitforge.app/tools/data-validator)**\n"};
Navigated to blog › ecommerce-data-crm-import-csv
Back to Blog
crm-import-guides

E-commerce to CRM: Import Orders, Customers, and Products (2026)

March 21, 2026
13
By SplitForge Team

Quick Answer

Importing e-commerce data into a CRM fails for five predictable reasons: customer deduplication logic that creates duplicate contacts instead of merging repeat buyers, order data imported as contact records instead of deal or activity objects, product SKU fields that don't match CRM product catalog entries, currency and number fields with formatting the CRM rejects, and date fields in platform-specific formats the CRM can't parse.

Why it happens: E-commerce platforms and CRMs have completely different data models. Shopify's "Customer" is a contact with order history. A CRM's "Contact" is a person with pipeline activity. Mapping between them requires understanding both models — not just renaming columns.

The fix: Map e-commerce objects to CRM objects before importing, deduplicate on email before the file reaches the CRM, and transform all numeric and date fields to match CRM expectations.

Root cause: Duplicate customer records are among the most common e-commerce CRM import failures. A customer who ordered three times creates three separate Contact records if email-based deduplication isn't handled before or during import.


Fast Fix (90 Seconds)

If your e-commerce CRM import failed or created duplicate contacts:

  1. Deduplicate on email first — Run deduplication on the email column before importing. Keep the most recent record for each email address.
  2. Check the object type — Are you importing customers as Contacts? Orders as Deals? Activities? Confirm the CRM object type before mapping.
  3. Strip price formatting — Remove $, , and commas from all price/revenue fields.
  4. Check date formats — Shopify exports ISO 8601 with timezone (2026-04-15T14:30:00-07:00). Most CRMs need YYYY-MM-DD or MM/DD/YYYY with no timezone.
  5. Import customers first, then orders — Orders reference customers. If customers don't exist yet, order imports fail on the lookup.

TL;DR: Deduplicate customers on email before import, strip price formatting, convert Shopify timestamps to plain dates, and import in order: customers first, then orders. Run Data Validator to catch type mismatches and duplicates before the CRM sees the file.


Tested on: Shopify customer and order exports, WooCommerce CSV files. Import behavior validated against Salesforce, HubSpot, and Zoho CRM. Deduplication logic verified against stores with 5,000–150,000 customer records. March 2026.

If you only do three things: (1) Deduplicate on email before importing — this alone prevents one of the most common post-import cleanup projects. (2) Import customers first, then orders — order lookups fail if the customer Contact doesn't exist yet. (3) Strip currency symbols and timezone offsets from all date/price fields.

If you get this wrong:

  • Skip deduplication → 31,000 contacts for 18,000 customers (72% inflation), 6 hours of manual merging, split activity history across duplicates, email campaigns send to same address 2–3x
  • Import orders before customers → every order line item fails with "Contact not found"
  • Leave timezone offset in date fields → all date fields blank, making order history invisible in CRM timeline views

Your DTC brand is integrating Shopify with Salesforce. You export your 18,000 customers and import them as Contacts. The import completes with 0 errors. You open the Contact list and see 31,000 records — 13,000 duplicates from repeat buyers who ordered under the same email address in different sessions. Shopify created a new Customer record for each session. Your Salesforce Contact list is already corrupted before a single rep has touched it.

Here's what that CRM aftermath actually looks like:

REALITY — what happens inside the CRM after an undeduped Shopify import:

Contact list (filtered by email: [email protected]):
  Contact ID: 003XX000001AAAA | Name: Alice Chen | Source: Shopify | Created: 2024-03-15
  Contact ID: 003XX000001BBBB | Name: Alice Chen | Source: Shopify | Created: 2024-11-08
  Contact ID: 003XX000001CCCC | Name: Alice Chen | Source: Shopify | Created: 2026-01-15

3 Contact records. Same person. CRM now has:
  → 3 separate activity histories (split across records)
  → 3 separate email opt-in consent records
  → Email campaigns send 3x to [email protected] (GDPR violation risk)
  → Sales rep calls Alice — sees 1/3 of her history each time
  → Dedup tool runs → flags 13,000 pairs → manual merge takes 6 hours

For a 18,000-customer import: 31,000 contacts = 72% inflation.

And here's how it happens — the normal path that nobody audits:

REALITY (actual Shopify → CRM migration at most companies):

Step 1: Ops team exports Shopify customers to "customers_export_final.csv"
Step 2: Opens in Excel → timestamps auto-reformatted by Excel locale settings
Step 3: Saves file → ISO 8601 timestamps corrupted to Excel's local format
Step 4: Uploads to cloud CSV validator to "clean it"
        → 18,000 customer records + purchase history uploaded to unknown server
        → GDPR Article 28: third party now a data processor, no DPA in place
Step 5: Imports to Salesforce with no dedup rules configured
Step 6: 13,000 duplicates created → 6 hours of manual merge work

Every step in this path is the default choice. None of it is malicious.
All of it is avoidable.

E-commerce customer and order data is among the most privacy-sensitive CRM data — it contains purchase history, behavioral patterns, and email addresses linked to transaction records, constituting personal data under GDPR Article 4(1). When you upload a Shopify customer export to a cloud-based CSV validator, you are transferring your entire customer database to a third party. Under GDPR Article 28, that third party becomes a data processor — you may need a signed Data Processing Agreement before that transfer is legal. Under Article 5(1)(c), this upload processes more data than necessary to fix a file format issue. SplitForge's Data Validator runs entirely in Web Worker threads in your browser — customer data never reaches any external server. Confirm this in Chrome DevTools Network tab: zero outbound requests.

E-commerce import patterns in this guide were tested against Shopify export formats, WooCommerce CSV exports, and Salesforce, HubSpot, and Zoho CRM import behavior, March 2026. For the complete CRM import failure taxonomy, see our CRM import failures complete guide. For Shopify-specific import errors, see Shopify CSV Import Errors. For pre-import product data cleaning, see Clean Product Catalog CSVs for Shopify and WooCommerce.


E-commerce Data Model vs CRM Data Model

Before mapping any fields, understand what you're mapping between:

E-commerce ObjectCRM ObjectNotes
CustomerContactDeduplicate on email before import
OrderDeal / OpportunityOne order = one deal; OR summarize as customer lifetime value on Contact
Order line itemProduct / Line ItemRequires product catalog match in CRM
Order noteActivity / NoteImport as activity attached to Contact
Customer tagCRM tag or custom fieldMap tag values to CRM field options
Customer addressContact address fieldsSplit or combine based on CRM layout
Abandoned cartActivity or custom objectCRM-dependent; check object support

The most common mistake is importing Orders as Contacts — creating a Contact record per order rather than per customer. Decide the object mapping before touching the CSV.


What E-commerce Import Failures Look Like

❌ BROKEN — Shopify customer export imported directly into Salesforce:

Shopify Customer CSV sample:
id,email,first_name,last_name,orders_count,total_spent,created_at,tags
3421,[email protected],Alice,Chen,3,1250.75,2024-03-15T10:22:00-07:00,vip wholesale
3421,[email protected],Alice,Chen,3,1250.75,2024-11-08T14:15:00-08:00,vip wholesale
9834,[email protected],Bob,Smith,1,89.99,2026-01-22T09:30:00-07:00,

Two rows for Alice Chen — same customer, different Shopify session records.
CRM imports both → two Contact records for [email protected].

total_spent: "1250.75" → actually fine (no currency symbol)
created_at: "2024-03-15T10:22:00-07:00" → ISO 8601 with TZ offset → most CRMs reject

FIXED:
- Deduplicate: keep one row per email, use most recent created_at
- created_at → date only: 2024-03-15
- tags: "vip wholesale" → "vip,wholesale" (split to separate tags if CRM needs comma-separated)
- Import as: Contact with custom fields for orders_count and total_spent

Table of Contents


Fix 1: Customer Deduplication Before Import

Shopify and WooCommerce can create multiple records per customer — guest checkouts, account merges, multiple sessions. Before importing any customer data to a CRM, deduplicate on email address. Keep one record per unique email — typically the most recent or the one with the highest order count.

❌ BROKEN — multiple platform records for the same customer:

Shopify export (three rows, one customer):
email,           orders_count, total_spent, last_order_date
[email protected],  1,            89.99,       2023-06-10
[email protected],  2,            289.50,      2024-02-28
[email protected],  3,            1250.75,     2026-01-15

Imported to Salesforce without dedup:
→ 3 Contact records for [email protected]
→ Each shows partial order history
→ CRM dedup tools flag them later, but manual merge takes time

FIXED — deduplicated before import (keep most recent + aggregate values):
email,           orders_count, total_spent, last_order_date
[email protected],  3,            1250.75,     2026-01-15

One record. Full aggregated history.

Edge Case: Gmail Plus-Alias Duplicates

Standard email deduplication misses one common pattern: the same Gmail inbox used with different plus-aliases.

EDGE CASE — Gmail plus-alias creates false duplicates:

Shopify records:
[email protected]          → ordered March 2024 (standard checkout)
[email protected]  → ordered June 2025 (from marketing email link)
[email protected]     → ordered January 2026 (from sale campaign)

Standard dedup on exact email: finds 0 duplicates (three different strings)
Reality: all three deliver to [email protected] — same person, same inbox

For stores with active email marketing using tracked links:
→ Normalize emails before dedup: strip + aliases
→ Method: =LEFT(A2, IF(ISERROR(FIND("+",A2)), FIND("@",A2)-1, FIND("+",A2)-1)) & MID(A2, FIND("@",A2), 100)
→ Strips "+anything" before "@" for Gmail addresses
→ Then dedup on the normalized email column
→ Keep original email for import (CRM should receive the real email, not the normalized one)

This edge case affects stores with list segmentation or promotional campaigns that use plus-alias tracking. You can do this manually in Excel or Python, or with a normalization step in your data pipeline — the key is to normalize for dedup comparison while preserving the original value for import.


Fix 2: Shopify Timestamp Format

Shopify exports timestamps in ISO 8601 format with timezone offset: 2026-04-15T14:30:00-07:00. Most CRM date fields don't accept this format — they need YYYY-MM-DD (date only) or YYYY-MM-DD HH:MM:SS (datetime without offset).

❌ BROKEN — Shopify timestamp formats that fail CRM date fields:

Shopify export values:
created_at:      "2026-04-15T14:30:00-07:00"   → ISO 8601 with TZ offset → rejected
updated_at:      "2026-04-15T21:30:00Z"         → UTC with Z → rejected by strict parsers
processed_at:    "April 15, 2026"               → natural language → rejected

FIXED — strip time component and TZ offset for date-only CRM fields:
created_at:      2026-04-15
updated_at:      2026-04-15
processed_at:    2026-04-15

For CRM datetime fields (timestamp with time):
"2026-04-15T14:30:00-07:00" → "2026-04-15 14:30:00" (drop TZ offset, use local time)

In Excel: =TEXT(DATEVALUE(LEFT(A2,10)),"YYYY-MM-DD") extracts the date portion from any Shopify ISO timestamp regardless of the time and timezone components.


Fix 3: Order Data Object Mapping

Orders don't belong in the Contact object. They belong in Deals (Salesforce/HubSpot), Potentials (Zoho), or a custom object depending on your CRM. Importing order data as Contact records creates one Contact per order instead of one Contact per customer.

ECOMMERCE → CRM OBJECT MAPPING:

Use case: Track customer purchase history
  → Import orders as Deals/Opportunities linked to the Contact
  → One Deal per order, Contact = the customer
  → Deal Amount = order total, Close Date = order date, Stage = "Closed Won"

Use case: Track customer lifetime value on Contact
  → Summarize order history as custom fields on Contact
  → Custom fields: Total Orders, Total Spent, Last Order Date, First Order Date
  → Import once; update via sync going forward

Use case: Full order line item history
  → Requires a product catalog in your CRM
  → Import products first → then Contacts → then Deals → then Deal Line Items
  → Salesforce Products, HubSpot Products Library, Zoho Products must exist first

Use case: Marketing segmentation only
  → Import customers as Contacts with order summary fields
  → Don't import individual orders — too much data for CRM use case
  → Use tags or custom fields: "VIP", "Lapsed 90 days", "High AOV"

Fix 4: Price and Revenue Field Formatting

E-commerce exports vary on price formatting. Shopify typically exports prices as plain decimals (correct). WooCommerce exports sometimes include currency symbols depending on locale settings. Verify before importing.

❌ BROKEN — price formatting that fails CRM currency fields:

WooCommerce export (European locale):
order_total: "1.250,75"   → European number format (period = thousands, comma = decimal)
line_total:  "€89,99"     → currency symbol + European decimal
shipping:    "12,50 EUR"  → currency symbol + trailing text

Salesforce Currency field expects:
1250.75
89.99
12.50

FIXED:
1250.75  (swap period/comma, strip currency)
89.99    (strip €, convert comma decimal to period)
12.50    (strip EUR and space)

For WooCommerce stores with European locale settings, every numeric field needs both the currency symbol stripped and the decimal format converted. Data Validator catches these format violations across your entire order export in your browser.


Fix 5: Product SKU and Catalog Matching

If you're importing order line items that reference products, the CRM's product catalog must contain matching SKU entries before the import runs. Line items that reference non-existent SKUs either fail or create orphaned records.

❌ BROKEN — order line item references SKU not in CRM catalog:

Shopify order line item export:
order_id, sku,        product_name,        quantity, price
ORD-4521, WIDGET-001, Blue Widget 12oz,    2,        29.99
ORD-4521, WIDGET-002, Red Widget 8oz,      1,        24.99
ORD-4521, BUNDLE-X,   Summer Bundle,       1,        79.99

CRM product catalog contains: WIDGET-001, WIDGET-002
Missing: BUNDLE-X

Import result:
- WIDGET-001 line item: linked correctly
- WIDGET-002 line item: linked correctly
- BUNDLE-X line item: "Product not found" or imported as unlinked text

FIXED:
Step 1: Export SKU list from CRM product catalog
Step 2: Compare against all SKUs in the order export
Step 3: Add missing products to CRM catalog before importing orders
Step 4: For bundles/custom SKUs: create a "Bundle" product type in CRM catalog

Common Scenarios

DTC brand importing customer LTV for sales segmentation

For DTC brands where the CRM use case is sales outreach rather than full order tracking, import customers as Contacts with aggregated order fields: Total Orders, Total Spent, Last Order Date, AOV (average order value), and a Customer Segment tag (VIP, At-Risk, Lapsed). This gives sales reps the context they need without cluttering the CRM with individual transaction records.

B2B e-commerce with company accounts

For B2B Shopify stores where customers represent companies rather than individuals, import at the Account level (company) before the Contact level (person). Map Shopify's company field to the CRM Account Name, create Accounts first, then import Contacts linked to those Accounts. Without this sequence, Contact records have no Account association.

Syncing ongoing orders after initial import

For ongoing sync (new orders added to CRM regularly), build a recurring import process rather than a one-time migration. The recurring process should: export only orders since the last sync date, deduplicate against existing CRM records before importing, and use update logic for customers who already exist.


Additional Resources

Platform Documentation:

Technical Standards:

Privacy & Compliance:

Tested: Shopify customer and order export formats, WooCommerce CSV exports. Validated against Salesforce, HubSpot, and Zoho CRM import behavior. March 2026.

PLATFORM SPECIFICATION SOURCE
Platform: Shopify, WooCommerce → Salesforce, HubSpot, Zoho CRM
Sources: Shopify Help Center — Exports; WooCommerce Documentation; CRM import guides
URLs: help.shopify.com | woocommerce.com/document
Verified: March 2026
Next re-verify: June 2026

Shopify and WooCommerce export formats change with platform updates.
Verify timestamp format and field structure against current documentation
before large data migrations.

FAQ

Shopify creates a new customer record for each unique checkout session, which can result in multiple records per email address. Before importing, deduplicate on email — keep the most recent record or the one with the highest order count. Most CRMs deduplicate during import based on email, but only if deduplication is enabled in the import settings and the email field is correctly mapped.

Import customers as Contacts first. Then import orders as Opportunities (Deals) with the Contact's Salesforce ID or email in the lookup field. Each order becomes one Opportunity with Amount = order total, Close Date = order date, and Stage = "Closed Won." For high-volume stores, consider importing just the order summary fields on the Contact instead of creating individual Opportunity records per order.

Strip the time and timezone offset, leaving only the date. In Excel: =TEXT(DATEVALUE(LEFT(A2,10)),"YYYY-MM-DD") extracts the date portion from any Shopify ISO 8601 timestamp. For CRM fields that accept datetime, use =LEFT(A2,19) to keep date + time and drop the timezone offset.

Only if you're importing order line items that link to CRM product records. If you're importing orders as flat Deals with a product description text field, no catalog is required. If you're using Salesforce Products, HubSpot Products Library, or Zoho Products to track line items, yes — create all product/SKU records before importing order line items.

Deduplicate on email across both sources before importing. If a customer exists in both systems with the same email, merge their order history into a single row with combined Total Orders and Total Spent values. Importing both creates duplicate Contact records that require manual merging in the CRM.


Validate Your E-commerce Export Before Import

Catch duplicate emails, timestamp format issues, and currency formatting before the CRM creates duplicates
Validate SKU references against your product catalog before order line items fail
Customer purchase history processes entirely in your browser — never uploaded to any server
Import clean contacts and orders on the first attempt — no post-import dedup required

Continue Reading

More guides to help you work smarter with your data

ai-data-prep

AI-Ready Data Checklist: 10 Things to Verify Before Upload (2026)

Before uploading to ChatGPT, Claude, or a fine-tuning API, run through this 10-point checklist. UTF-8 encoding, clean headers, PII removed, size within limits.

Read More
ai-data-prep

Convert Excel to JSON for AI APIs and LLM Pipelines (2026)

AI APIs and LLM pipelines expect JSON, not spreadsheets. Fine-tuning needs JSONL; direct prompts take arrays. Convert locally — no upload, no conversion server.

Read More
ai-data-prep

Prepare Data for AI: The Complete Guide (Privacy-First, 2026)

How to prepare a CSV or Excel file for ChatGPT, Claude, or an AI API — encoding, PII, format, size, and privacy. The complete local-first prep workflow.

Read More