Project portfolio Browse selected work

Shopify Plus: up to US$4,800 development credit

Guide

WooCommerce to Shopify Migration: Data, SEO, Cutover, and Rollback

Published: Editorial review: 2026-08-30

The conclusion: prove the move is justified before planning the move

Moving from WooCommerce to Shopify is not an export-and-import task. It is a coordinated change to commerce rules, data relationships, URLs, payments, fulfillment, applications, and team ownership. A new homepage returning 200 proves only that a storefront is reachable. A migration is complete only when customers, products, orders, inventory, money, search entry points, integrations, and operating procedures are demonstrably correct, with a named response when they are not.

Shopify’s official migration overview describes manual copy, CSV, migration apps, partners, and APIs as different routes. Its WooCommerce guide recommends importing products before customers and historical orders so that relationships can be connected. Treat that as a useful baseline, not as a promise that plugin fields, subscriptions, or payment transactions will map automatically.

OutcomeEvidence requiredMisleading substituteAction if it fails
Complete dataSource snapshot equals created, updated, skipped, quarantined, and failed rowsAn “import complete” bannerBuild a difference set and pause downstream jobs
Correct relationshipsSKU, customer, order line, location, and discount references trace end to endComparing product totals onlyRepair mappings and replay the affected batch
Operable commercePayment, refund, tax, shipping, fulfillment, and notification replayOne successful test checkoutIsolate the failing path and delay cutover
Preserved discoveryURL inventory, one-hop redirects, target pages, and sitemap checksChecking the homepage onlyRepair routes, canonicals, and links
Recoverable operationFreeze window, rollback owner, compensation steps, and read-only backupA single CSV exportPreserve the old store and rehearse recovery

This guide keeps the project-level decision and operating boundary. For API, bulk-job, and performance trade-offs, continue with the Shopify data migration engineering guide. Identity, consent, accounts, and privacy mechanics are covered in the Shopify customer data migration guide, while platform cost assumptions belong in the Shopify versus WooCommerce total-cost breakdown. For implementation coordination, see WESWOO’s migration and build services and Shopify store setup guides.

Stay on WooCommerce, repair it, or move

Write the platform choice as an evidence-based decision rather than a brand preference. If the existing WooCommerce store reliably serves the critical journeys and the problem is a replaceable extension, repairing and retaining it may be safer. If maintenance, hosting, releases, or market expansion remain measurable bottlenecks, compare the target operating model with migration risk. A migration signal never overrides an unresolved payment, tax, privacy, or integration blocker.

Decision signalStay on or repair WooCommerceReason to move to ShopifyEvidence needed
Business outcomeThe current funnel, markets, and fulfillment meet targets; fix a local defectRelease, market, team, or reliability bottlenecks remain measurableBaseline metrics, incidents, target
Data and extensionsCritical fields depend on a few maintainable extensions and tested backupsExtension coupling, upgrades, or hosting operations create recurring riskExtension register, data dictionary, restore rehearsal
Commerce and fulfillmentPayment, tax, stock, and subscription journeys repeat reliablyTarget markets require new payment, location, or operating controlsEnd-to-end replay, provider eligibility, stock reconciliation
SEO and contentExisting URLs have stable value and the migration benefit is unclearStructure, performance, or content governance requires a rebuildURL ledger, logs, organic entries, redesign plan
ReadinessThere is no freeze window, owner, or delta methodRehearsal is complete, thresholds exist, and rollback is testableGo/no-go record, timeline, rollback report

This guide absorbs the five pre-migration questions

Before choosing a tool, answer five questions: Which measurable problem should the move solve? Which data and relationships must survive? Can the required functionality and integrations be rebuilt on Shopify? How will old URLs and search signals be preserved? Can the team cut over within a controlled freeze and return safely if needed? These questions capture the preflight intent of post 9671 and turn it into inventories, mappings, tests, and acceptance gates.

The five preflight questions: make a written go/no-go decision

Do not start because WooCommerce has many plugins or because Shopify appears easier to operate. Compare three real options—keep and repair WooCommerce, migrate in stages, or cut over once—using three-year platform, hosting, extension, development, maintenance, payment, SEO, and opportunity costs. Any unanswered critical question is a blocker, not a line item labelled “to be handled later.”

Preflight questionEvidence to collectPass conditionPause signal
What problem should the move solve?Incidents, maintenance hours, release time, checkout funnel, market planOwner and post-launch metric existThe goal is only “change platforms”
What must be retained?Object list, retention rules, support and finance queries, privacy requestsEvery field has a destination“Move everything” without a field map
Can the functionality be rebuilt?Plugin behavior, workflows, APIs, quotes, failure pathsCritical journeys pass on a prototypeSubscriptions, B2B, or ERP exist only in screenshots
How will SEO continue?Sitemap, logs, analytics, Search Console, backlinks, old and new URLsEvery valuable URL has one destinationMany URLs point to the homepage
Can the cutover be controlled?Duration, delta method, freeze window, rollback rehearsalStop thresholds are signed offNobody owns the pause decision

Write stop conditions before writing the launch date

Pause if payment-entity or market eligibility lacks written confirmation, tax ownership is unclear, the ERP or WMS has not passed create/update/cancel/refund tests, the next subscription charge has no owner, high-value URLs have no mapping, or the team lacks a content, inventory, or rollback window. A pause is a risk-control decision, not a rejection of the project.

Select a migration route and freeze the scope

Shopify’s WooCommerce guide names manual copy, CSV, the first-party Store Migration app, third-party migration apps, and migration experts as separate routes. A small standard catalogue may work well with CSV. A store containing extension fields, historical orders, media relationships, continuous deltas, or strict audit requirements generally needs an app, API, or a conversion layer. Combining methods is fine, but each object type needs one defined write path; tools must not overwrite each other.

Use a scope matrix to prevent an accidental redesign

Classify each object as migrate, rebuild, archive, or retire, with a reason. Keep visual redesign, content rewriting, data cleansing, market expansion, and platform migration as distinct work packages. This prevents both blind copying of broken source structures and last-minute untested promotions or countries.

Scope objectMigration methodOwnerAcceptance evidenceTarget treatment
Catalogue facts: SKU, title, price, weight, variants, mediaProduct CSV, app, or API; hard samples firstMerchandisingSKU, variant, and media sample reportShopify products, variants, media
Customer relationships: email, addresses, tags, consent, external IDCustomer CSV plus identity/privacy workflowCustomer and privacy leadsDeduplication, consent, and activation samplesCustomer records and controlled archive
Transaction history: number, lines, money, tax, refundsMigration app/API, or read-only archiveFinanceCurrency, amount-equation, and refund reconciliationHistorical orders or read-only warehouse
Commercial rules: discounts, gift cards, subscriptions, loyaltyNative rebuild plus specialist app or retained systemOperationsRule lifecycle and balance/charge replayRebuild, specialist migration, or retain
Content and entry points: pages, posts, media, old URLsContent import, media review, and redirect ledgerContent and SEO leadsContent samples, crawl, and status reportPages, articles, files, redirects

Target operating model and gap analysis: assign ownership before import

The target is not a new set of admin menus. It is a written answer to who owns each fact, who may write it, and who handles an exception. For products, prices, inventory, orders, customers, content, payments, tax, and fulfillment, name the system of record, fallback system, tolerated delay, approver, and service objective. If customer support or finance needs manual compensation, lookups, or exports, put those actions in the SOP and training instead of assuming an app will make the decision.

Use a capability gap table to choose rebuild, replacement, or retention

Compare current WooCommerce behavior with the Shopify design by trigger, fields, permissions, notifications, failure path, reports, and retention. Classify each gap as configurable, app or middleware, custom development, manual, or not migrating. A similar-looking screen is not evidence of equivalent behavior.

CapabilityCurrent WooCommerce factShopify target designGap and decisionOwner/evidence
Products and pricesWhich extension or role changes titles, prices, and sale prices?Products, price lists, and market rules have one writerConfigurable, app, custom, or manualMerchandising sign-off
Stock and fulfillmentWarehouse, reserved, in-transit, and split-order rulesLocation inventory, fulfillment service, and WMS eventsComplete locations or retain WMSSupply-chain replay
Orders and refundsCapture, refund, cancel, and support permissionsOrder, processor, finance, and notification chainRebuild states and compensationFinance test order
Customers and consentAccounts, marketing consent, privacy requests, duplicatesCustomer accounts, consent record, controlled manual pathSeparate identity/privacy designPrivacy sample
Content and SEOPage builder, translations, shortcodes, rewrite rulesPages, articles, files, templates, canonical, redirectsClean, rewrite, or archiveContent crawl report

Inventory WooCommerce: identify source data and live extensions

WooCommerce facts live across the WordPress database, wp-content, media, themes, extension tables, order metadata, scheduled actions, and external systems. A standard product export does not necessarily include subscriptions, gift cards, composite products, memberships, reviews, custom fields, or a warehouse’s stock ledger. Freeze a plugin and version inventory with each extension’s purpose, tables, events, cron jobs, external account, licence, and shutdown impact.

The WooCommerce REST API v3 documentation covers products, variations, customers, orders, and coupons. Woo’s product import/export guide explains the built-in CSV, field mapping, and custom metadata export. Cross-check admin exports, REST API reads, a read-only database snapshot, and interviews; no single export should be treated as the complete source of truth. Test import/export on staging or a restore copy first.

Treat customer, order, and coupon CSV export as an extension boundary. WooCommerce’s official export-extension documentation describes what is available after that extension is installed; it is not a universal core guarantee, and fields also depend on custom plugins. Batch large exports and close the count and amount equation for every batch.

Build an object, count, and relationship ledger

For every object, record source ID, business key, state, created and modified times, relationships, privacy class, count, extraction method, owner, and sample method. For orders, add guest status, refunds, cancellations, partial fulfillment, tax lines, shipping lines, coupon lines, and payment transactions. For products, classify simple, variable, bundled, composite, downloadable, pre-order, and subscription types. Version the ledger and bind it to export hashes.

DomainInventory questionsMinimum outputHigh-risk example
ProductsWhere are attributes, variations, SKUs, media, categories, and custom fields?Product and relationship countsOptions exceed the target model
CustomersHow are registered, guest, duplicate-email, multi-address, and consent cases represented?Identity and consent listOne email represents two entities
OrdersAre transactions, refunds, taxes, shipping, fulfillment, and status complete?Amount equation and status distributionPartial refund in a second currency
ContentDo pages, posts, shortcodes, images, and downloads depend on extensions?URL, body, media, and template listPage-builder shortcode breaks
RuntimeWho writes through webhooks, cron, cache, search, email, and ERP?Integration topology and shutdown planDouble write or double charge

Backups, privacy, and recoverability come before the first import

WooCommerce’s backup documentation says a complete backup includes the database and the wp-content folder; WordPress XML does not contain WooCommerce orders, products, or settings. Before migration, create encrypted copies of the SQL database, wp-content and media, theme and extension versions, configuration inventory, CSV/API exports, URL ledger, DNS records, payment and shipping settings, and the migration runbook. Store one copy away from the production host.

The backup is useful only after a restore test. Restore SQL and files into an isolated environment, open products, customers, orders, media, checkout, and subscription administration, and record restore time, missing files, permissions, and database versions. Real customer, address, order, and token data should be limited to necessary personnel. Logs should use internal IDs, hashes, and error paths, never full personal data or payment credentials.

Treat the target store as an evidence-bearing system too

Shopify is hosted, but the migration still needs target theme versions, product/customer/order exports, redirect CSVs, market and translation settings, app configuration, API version, import results, and review reports. Do not assume an admin undo action is a full rollback. Generate a run_id, configuration hash, and timestamp for every execution so the team can explain which rule version wrote a record.

Field mapping: turn the source model into an auditable contract

A field map should include source path and type, target object and field, requiredness, enum mapping, null behavior, length, units, timezone, sensitivity, system of record, transformation version, and verification query. Use decimal values and currencies for money, not floating point; preserve source timezone and UTC for timestamps; sanitize shortcodes, scripts, and obsolete media from HTML. Define uniqueness separately for SKU, external order number, and email.

Use immutable IDs and semantic hashes for replay

Create an identity map from source_system + object_type + source_id to a Shopify GID, handle, or external key. SKUs can change, emails can change, and displayed order names can have prefixes, so they are useful for conflict detection but not sufficient as global primary keys. Store a normalized payload hash. On replay, compare the identity map and semantic hash before choosing create, update, skip, or quarantine. After a timeout, query for a successful write before creating anything again.

Source factShopify candidateTransformationAcceptance focus
Woo product ID and SKUProduct/Variant identity map and SKUPreserve source ID; quarantine duplicate SKUParent-child and SKU closure
Attributes and variationsOptions, variants, and metafieldsNormalize names, values, and unitsEach combination is unique and sellable
post_content and shortcodesProduct description, Page, or metaobjectSanitize HTML and replace shortcodes with componentsNo broken shortcode or media URL
User ID, email, addressesCustomer, addresses, and tagsNormalize email; adjudicate duplicatesLogin, address, consent, privacy request
Order number and linesOrder, lines, and metafieldsPreserve source number; do not recalculate historyCurrency, tax, discount, refund equation

Migrate products, variants, media, and inventory as layers

Products are not one CSV row. First map product types, attributes, options, variants, media, collections/categories, prices, inventory, and sales channels. Use the hardest examples first. Shopify’s product CSV documentation notes that CSV data affects commercial fields such as price, weight, and inventory; WooCommerce exports normally require editing to match Shopify’s template. The Shopify WooCommerce guide says its first-party Store Migration app is early access and documents a limitation for products with more than three options. If those products exist, plan an app/API, a metafield/metaobject model, or a deliberate rebuild, and reconfirm the current limitation before execution.

Shopify product CSVs have dependent fields: changing variant data requires the corresponding option columns. Missing dependencies can create a default variant or delete existing variants, so run a dry-run in an isolated store and diff the result before every production load. Multi-location stock belongs in the inventory CSV, not in one product-level Inventory quantity; prefer the all-states format for a fuller view and protection against accidental overwrites, then reconcile every SKU × location row. Define product metafields first, and use another reviewed method for variant metafields because product CSV does not support them.

Load structure before media, publication, and stock

Use a dependency order: product types and options, products and variants, media and alt text, collections/categories, prices and markets, locations and inventory, then sales-channel publication. A media upload succeeding does not prove that the asset is usable; check processing state, order, dimensions, alt text, duplicates, and page references. Shopify’s multi-location inventory guide says locations track inventory independently. Matching the total while assigning the wrong warehouse still causes promises and fulfillment failures.

Customers, orders, and accounts: preserve relationships before interfaces

Shopify’s customer CSV guide states that passwords from another store cannot be migrated by CSV; imported customers must be invited to create new passwords, and customer CSV does not import orders, Total Spent, or Total Orders. The file must be UTF-8 and is currently limited to 15 MB per file; only defined, supported customer metafields can be imported by CSV. Recheck these limits and supported fields against the target store immediately before execution. Apply the current import rules to duplicate email or phone values. Decide whether the target will use new customer accounts, legacy accounts, an identity provider, or a controlled reactivation process. Test verification email, reset, address, and order-history behavior.

Historical orders can use a migration app or API. Shopify warns that staff members who receive new-order notifications may receive an email for each imported historical order. Before importing, pause notifications, Flow, ERP, fulfillment, loyalty, and marketing actions that should not run. Restore them only from a checklist. Preserve source order number, original processing time, currency, tax, discount, payment state, fulfillment, and refund meaning; do not create a fresh live transaction by accident.

Reconcile an amount equation and customer identity

For every sampled historical order, check: line subtotal minus discounts plus shipping plus tax equals the order total, then reconcile refunds and captured amount. Preserve both shop and presentment currency where relevant. Sample guests, duplicate emails, multiple addresses, unsubscribed customers, privacy deletions, historical orders, and high-value customers. An admin record existing does not prove that consent, activation, and support access are correct.

Discounts, gift cards, and subscriptions represent future obligations

WooCommerce’s coupon management guide supports percentage, fixed-cart, and fixed-product coupons with product, category, email, minimum-spend, combination, and usage limits. Shopify’s discount documentation distinguishes code, automatic, amount/percentage, buy-X-get-Y, and free-shipping methods. Rebuild the rule, not just the code and amount: include timezone, validity, scope, stacking, usage counts, and customer context. Archive expired campaigns rather than reopening them.

The WooCommerce Gift Cards extension distinguishes prepaid gift cards from store credit and promotional coupons. Shopify’s giftCardCreate requires the relevant permission and can create a card with initial value, code, expiry, and customer association. Reconcile balance, currency, status, expiry, redeemed amount, and legal terms, then test purchase, redemption, partial use, and refund with a controlled card.

Subscriptions require a separate plan. WooCommerce Subscriptions says an agreement links a product, customer, payment gateway, and one or more orders, and that payment-token portability depends on the gateway. Shopify’s subscription contract model is app-owned around selling plans, contracts, billing attempts, and later orders. Shopify’s migration guide describes supported payment-method migration without directly moving card numbers and recommends pausing old billing to avoid double charges.

Reviews, store credit, and legal archive also need their own boundary. Retain review author, product, rating, body, creation time, moderation state, and consent basis, and confirm whether the target review app accepts historical imports. Reconcile store credit like a gift card, including balance and usage events. Completed orders’ original tax, payment, and refund facts may remain in a controlled read-only archive; finance and privacy owners approve access, retention, and deletion handling. Do not fabricate transactions to make admin counts match or treat a promotion code as spendable credit.

Split old and new subscribers into explicit paths

Preserve product/variant, interval, quantity, next charge, status, discount, delivery, consent, payment provider, and retry policy for every subscription. Existing contracts may be billed by the old gateway for a short period while new sign-ups use a Shopify subscription app; alternatively, customers can update their payment method before cutover. Test initial charge, renewal, failure retry, pause, skip, product change, cancellation, refund, tax, and notifications. Finance must approve billing pauses and compensation.

Pages, blogs, policies, and files: content needs an owner too

A successful product load does not prove that the site is complete. Register WordPress pages, blog posts, authors, dates, categories, media, downloads, policies, forms, shortcodes, navigation, and templates. Mark extension-generated content, components that need rewriting, legal approvers, and files that must remain available after the old store is retired. Business or legal owners must approve privacy, refund, shipping, and market-specific policy versions; a migration script should not rewrite them silently.

Restore content meaning before visual layout

Convert shortcodes, embeds, forms, relative image paths, download permissions, and internal links in the HTML into maintainable Shopify pages, articles, files, metaobjects, or theme blocks. Copying only a page-builder screenshot can leave an uneditable image. A stronger acceptance test is that an owner can update the content in the target admin, visitors can reach it in each required language and market, and form submissions arrive at the right handler.

Content assetSource checksTarget treatmentPass evidence
Pages/blogsAuthor, date, category, body, shortcode, draft statePage, article, blog, or rebuilt componentBody, metadata, media, author samples
Policies/legalMarket, language, version, review date, linksPolicy pages and market display rulesBusiness/legal sign-off and checkout links
Media/downloadsPath, alt, dimensions, access, reference countShopify files or controlled external storageResource state, access, no 404
Forms/navigationFields, recipient, consent copy, menu hierarchyForm app/middleware and navigationTest submission, email, internal-link crawl

SEO URL inventory: collect every entry point before designing paths

Old WooCommerce URLs come from product and category permalinks, WordPress pages, posts, media, language plugins, historical rewrite rules, sitemaps, analytics, Search Console, backlinks, and server logs. A navigation crawl misses ranking pages, ad landing pages, old campaigns, and language-prefixed paths. For each URL, record status, recent traffic, revenue, backlinks, language, intent, retention decision, and final target.

Prefer one-to-one 301 redirects over a homepage dump

Shopify’s URL redirect documentation supports admin and CSV imports but has reserved prefixes that cannot be redirected, broken-URL behavior, and plan-dependent limits. List reserved-prefix cases as explicit exceptions in the ledger. Import and test the mapping before domain cutover. A product should target the matching product, a category the relevant collection, and an article the equivalent article. Only an approved page with no useful alternative should follow a deprecation strategy. Check encoding, case, trailing slash, query parameters, loops, and chains; the intended result is one redirect followed by a 200 target.

Old URL classTarget strategyContext to preserveAcceptance
Product or variantMatching Shopify product/variant or canonical productSKU, language, market, canonical200, correct title, purchase path
Category or tagMatching collection, search, or content pageOriginal intent and internal linksNo irrelevant homepage target
Content or blogMatching page, article, or blogAuthor, media, date, structured dataBody, images, and schema work
Duplicate or parameterOne canonical page; filter parameters where neededCanonical, robots, campaign parametersNo crawl loop or soft 404
Retired with no substituteApproved deprecation responseReason and business evidenceStatus, sitemap, and links agree

Multilingual stores and Markets: test language, region, and currency together

WooCommerce multilingual plugins often combine translations, language directories, tax, pricing, and product IDs. Do not copy Chinese or English body text without mapping each country’s domain or subfolder, default language, currency, price, tax display, payment, shipping, returns, and catalogue. Shopify’s Markets documentation says a market can control currency, language, price, product availability, domain, and tax. Its domain and language guide describes subfolders, subdomains, and top-level domains.

Shopify generates hreflang, canonical, and international sitemap behavior from market and language configuration; automatic geographic redirection serves customers while crawlers are excluded so each localized URL can be crawled. Still review translation coverage, URL slugs, email, checkout, app copy, right-to-left layout, market fallback, and selectors. Do not force every visitor to one language by IP, and do not assume a product has the same price or stock in every market.

Test localization as country-by-language journeys

For each core market, sample a homepage, collection, high-revenue product, article, cart, checkout, order email, and return page. Use a local address and currency to verify price formatting, tax, payment, shipping, delivery promise, and legal copy. Then use an incognito window, different browser language, and manual selectors to verify that visitors can reach the intended market. Translation that covers product titles but misses policies and app errors is incomplete.

Payments, tax, and shipping: rebuild eligibility and rules, not screenshots

Shopify Payments is available only to eligible countries and business types. The official country list requires checking entity, bank, and verification documents; otherwise a third-party provider is needed. Shopify’s third-party payment guide says third-party transaction fees and processor charges must be checked for the target market. WooCommerce payment methods are commonly gateway plugins connected to processors, so eligibility, fees, refunds, disputes, and tokens remain provider-specific.

Tax configuration cannot replace professional tax advice. Shopify’s tax guide says the merchant remains responsible for registration, collection, filing, and remittance unless an applicable automated filing service is configured. WooCommerce’s tax setup guide likewise separates software settings from legal advice and requires decisions about tax-inclusive pricing, tax address, and shipping tax class. Preserve original tax lines for historical orders; calculate new orders under the approved target rules.

Shopify shipping zones and rates depend on markets, locations, shipping profiles, weight, dimensions, and carriers. WooCommerce shipping zones, classes, live-rate extensions, and warehouse rules must be rebuilt. Test free, flat, weight-based, price-based, remote-area, digital-product, split-order, and return shipping by market. Missing package dimensions can undercharge shipping at checkout. For cross-border flows, put duties, import taxes, customs responsibility, carrier tracking, fraud review, and order notifications in the same test matrix; payment success, order creation, or an email delivery is not fulfillment or finance reconciliation.

Rehearse payment, tax, and fulfillment as one matrix

Replay successful and failed authorization, 3DS, wallets, local methods, duplicate callbacks, partial and full refunds, disputes, tax-exempt buyers, tax-inclusive prices, discount-after-tax behavior, multiple-location stock, split fulfillment, cancellation, returns, and tracking. Payment success is not the same as an ERP order. Creation, capture, stock deduction, tax record, fulfillment, and notification must reconcile as events.

Apps and integrations: replace capabilities, not plugin names

Build a WooCommerce capability matrix for discovery/search, reviews, memberships, discounts, subscriptions, tax, payment, shipping, inventory, ERP, WMS, OMS, CRM, email, support, analytics, advertising, and privacy. For each capability mark Shopify native configuration, app, Flow/Functions, middleware, custom API, manual process, or retirement. Record permission scope, data export, performance, price, support boundary, owner, and exit procedure. A same-name app is not proof of equivalent behavior.

Shopify’s webhook guide says webhooks help with near-real-time sync but do not guarantee delivery order or completeness; it recommends periodic reconciliation, HMAC verification, and duplicate handling. WooCommerce’s webhook guide covers order, product, coupon, and customer events, logs, and automatic disabling after consecutive delivery failures. Both platforms require a reconciliation path beyond webhooks.

Draw lifecycle and dead-letter paths for every integration

For create, update, cancel, refund, delete, retry, and backfill, specify source, target, business key, direction, tolerated delay, idempotency key, dead-letter queue, alert, and human action. During cutover, one system must be the authoritative writer for products, prices, stock, orders, or customers. The other may be read-only, event-driven, or batch-fed. Before retiring an old plugin, export its data, revoke credentials, and document historical lookup.

Import architecture: let CSV, apps, and APIs do different jobs

CSV works for large basic product, customer, or inventory loads that people can review. An app may handle historical orders, reviews, media, or extension objects, but review its permissions, data residency, retries, billing, uninstall behavior, and support boundary. An API is appropriate when you need identity maps, idempotency, deltas, complex transforms, and machine reconciliation. Shopify’s Bulk Operations guide covers JSONL, staged uploads, bulk mutations, status, and result files; neither HTTP 200 nor a completed bulk job proves every row succeeded.

WooCommerce REST API v3 uses pagination and exposes total headers or Link headers. Its order endpoints support filters such as modified_after, which can help build a delta process. For a large catalogue, many orders, or a substantial media library, measure memory, latency, failure rate, and result-download behavior per batch before choosing concurrency. Never copy a fixed sleep interval as the throughput strategy.

Give every batch an input, output, and retry boundary

Persist object range, source snapshot time, payload hash, request ID, target ID, success/failure/skip counts, error code, and last verification. Separate retryable network, throttling, and temporary 5xx errors from permanent field, permission, and duplicate-key errors. Put permanent rows in quarantine and replay only those rows after fixing the rule. Encrypt input and result files, retain hashes, and delete them on the approved schedule.

Incremental sync: use high-water marks, overlap, and reconciliation

The source store continues to receive orders, customers, refunds, stock, prices, and content changes after the first full extract. A modified_at cursor alone can miss records sharing a timestamp, clock-skewed writes, deletes, merges, or independently managed inventory. Store a high-water mark plus a stable ID, query with a safe overlap window, and deduplicate using the identity map and payload hash. Advance the cursor only after submission, result persistence, and reconciliation succeed.

Treat deletes, cancellations, and refunds as deltas

Define an event or difference query for deletion, unpublishing, customer merge, unsubscribe, order cancellation, refund, gift-card redemption, inventory adjustment, and URL removal. Shopify does not guarantee complete webhook delivery, and WooCommerce webhooks can be disabled after repeated failures, so schedule reconciliation between source valid sets, target sets, event logs, and business ledgers. Resolve conflicts according to the system of record and business time; the last-arriving request must not overwrite newer information blindly.

ChangeCapture methodIdempotency keyQuality gate
New order or customerAPI high-water mark plus webhookSource type + source ID + versionOne target identity
Price or content updateOverlapping modified_after querySource ID + timestamp + hashOnly approved fields overwrite
Inventory changeWMS event or controlled snapshotSKU + location + versionLocation-level quantity matches
Cancel, refund, or deleteEvent, audit table, or tombstoneSource event IDTarget state and finance agree
Missed eventScheduled reconciliationRun ID + object rangeDifference is zero or signed off

Rehearsal: hard samples first, then two timed full runs

In a development or isolated store, start with difficult samples: three-layer variants, duplicate SKUs, special characters, missing images, long rich text, multi-address customers, guest orders, partial refunds, multiple currencies, gift cards, subscriptions, retired content, and multiple languages. Record field gaps, manual steps, notification side effects, API time, and cleanup. After rules are corrected, run a full rehearsal to measure throughput, delta catch-up, and rollback time; finish with a rehearsal that includes the intended freeze window.

Turn rehearsal results into signed gates

Every rehearsal should output source and target counts, field samples, relationship closure, amount differences, URL status, payment and fulfillment replay, sync lag, manual hours, failed rows, and cleanup instructions. P0/P1 differences must be zero. Lower-risk differences need an owner, deadline, mitigation, and business sign-off. If the run exceeds the acceptable freeze, improve batching, reduce scope, or choose staged cutover instead of taking the risk overnight.

Cutover runbook: write owners and stop conditions minute by minute

The runbook should cover change freeze, source backup, final full/delta extract, inventory and order watermarks, old-store notifications, app webhooks, payments, tax, shipping, DNS/domain, SSL, cache, robots, sitemap, monitoring, customer communications, and the first-order path. Shopify’s migration guidance recommends creating redirects before transferring the domain. Confirm that the old platform will not continue claiming the domain in a way that creates SSL or DNS conflicts.

Execute the cutover with an evidence-bearing timeline

Proceed only after the evidence at the previous checkpoint is signed. The relative times below are examples; the actual freeze length must come from rehearsal rather than a universal hour promise.

TimeOwnerDependencyEvidence to retainRollback trigger
T−30 to T−14 daysProject leadScope, method, and owners approvedGo/no-go, object ledger, rehearsal reportCritical object has no destination
T−7 daysData/SEO leadsTarget structure and URLs stableFinal field map, redirect ledger, restore recordValuable URL or field remains unmapped
T−1 dayOperations/financePayment, tax, shipping, notification replay passesIntegration matrix, stock watermark, pause listPayment or fulfillment still has a P1 gap
T−0 freezeMigration leadStaff online; snapshot hashes matchFreeze time, final delta, write-lock recordDelta cannot catch up or snapshot differs
T+0 to 2 hoursStore/payment leadsDomain, SSL, redirects, checkout readyFirst order, payment, stock, ERP, email replayCheckout or capture keeps failing
T+1 dayBusiness/SEO/financeMonitoring and support queues ownedReconciliation, 404/301 logs, sign-offOrder, amount, or stock gap exceeds threshold

Freeze relationship-changing writes, not every conversation

Announce exactly which product, price, SKU, stock, discount, content, plugin, and setting changes are frozen, and who may approve an exception. If the old store cannot fully stop writing, use a high-water mark and delta queue to shorten the window. After cutover, validate a test or small real order through checkout, payment, ERP, inventory, fulfillment, and notification before releasing advertising and email traffic.

Acceptance: collect business-journey evidence, not just counts

Acceptance has five layers: count, field, relationship, value, and behavior. Count means source valid records close; fields include title, price, weight, address, status, time, and custom data; relationships connect customer, order, line, variant, and location; value covers currency, tax, discount, shipping, payment, refunds, gift-card balance, and stock; behavior covers browsing, search, cart, checkout, failed payment, fulfillment, return, login, email, and support lookup.

Risk-weight the sample instead of sampling randomly only

Prioritize highest-revenue products, hardest variants, oldest and newest orders, largest totals, multiple currencies, subscriptions, refunds, guest customers, duplicate identities, multiple addresses, special characters, primary languages, and every market. Capture request IDs, order numbers, timestamps, and environment along with screenshots; a screenshot is not the only evidence. Every difference needs severity, root cause, remedy, retest, and approver.

Acceptance layerRepresentative checksPass definitionEvidence
CountsProducts, variants, customers, orders, media, URLsDifferences are explained and within thresholdReconciliation report
FieldsPrice, weight, address, state, language, SEORequired fields match source or contractField samples
RelationshipsOrder lines to variants, customers to orders, SKU to locationNo critical orphan recordsRelationship query
ValueTotals, tax, discounts, refunds, gift cards, inventoryEquations and balances passFinance and stock sign-off
BehaviorCheckout, payment, fulfillment, return, account, searchCritical journeys repeat successfullyReplay record

Use one reconciliation matrix for counts, money, and locations

Use the same keys and definitions for every full load, delta, and post-cutover check. Zero is the default tolerance. Any non-zero difference needs a cause, compensation, owner, and due date; rounding or a global total must not conceal differences by location, currency, or state.

Reconciliation objectSource count/valueTarget count/valueToleranceOwner
Products and variantsValid SKU count / sale-price viewShopify SKU count / target-price viewCount 0; price per approved ruleMerchandising
Customer identitiesCustomer count / mailable-consent countCustomer count / mapped-consent countIdentity 0; activation pending listedCustomer and privacy
Historical ordersOrder count / totals by currencyOrder count / totals by currencyCount 0; amount 0 by currencyFinance
Refunds and gift cardsRefund count/value / balances and usageTarget refunds/balances / usageWithin finance-approved roundingFinance
SKU × location stockSellable, reserved, in-transit by locationTarget quantity and state by locationDefault 0; WMS explanation signedSupply chain
URL entry pointsValuable old URL count / traffic-revenue tierRedirect/200/deprecation destinationsUnmapped 0; exceptions approvedSEO

Rollback: restore continuity, do not simply delete Shopify data

Separate domain rollback, continued operation on the old store, compensation for target writes, and payment/finance reversal. If cutover has already produced orders, refunds, stock deductions, or registrations, pointing DNS back does not erase those facts. Lock writes, export post-cutover events, identify the authoritative system, backfill the old store or keep the target read-only, and require finance approval for refunds or recharges.

Set a trigger threshold for every serious failure class

Examples include sustained checkout failure, a mismatch between captured payments and orders, unexplained negative stock at a location, missing orders over threshold, mass 404s on valuable URLs, an integration queue that cannot catch up, or an access-control error involving personal data. Put thresholds in the runbook before cutover. When one fires, pause traffic and downstream automation, preserve evidence, then run the smallest compensation. Do not hide differences by importing the entire dataset again.

The first 30 days: retain evidence while retiring the old stack carefully

During days 1–3, watch checkout success, payment failures, order lag, stock differences, 404/301/5xx, email, refunds, and support issues hourly. Reconcile daily through day 7, then review markets, tax, shipping, application billing, search crawling, and rollback readiness weekly through day 30. Keep the old WooCommerce system available for controlled read-only lookup, encrypted backup, and privacy response. Do not remove the only copy of historical data before approval.

Close the stabilization period with a signed checklist

At day 30, confirm zero P0/P1 issues, signed differences, an owner for every integration, a tested backup restore, revoked legacy credentials, reviewed old app and hosting charges, completed customer communications, stable sitemap and redirects, and the first full month of payment and tax reconciliation. Business, engineering, SEO, privacy, and finance should jointly approve decommissioning the old site or moving it into long-term archive.

Frequently asked questions

Can all WooCommerce data be migrated automatically to Shopify?

There is no universal guarantee. Standard products, customers, or inventory may use official CSV or API routes, while extension fields, reviews, composite products, gift cards, subscriptions, payment tokens, historical orders, and multilingual content require separate decisions. Build the ledger and hard-sample test first, then combine CSV, an app, an API, and read-only archive as appropriate.

Must the WooCommerce store be closed during the migration?

Not necessarily for a long period, but a controlled freeze or delta process is mandatory. If the old store keeps accepting orders, registrations, refunds, or stock changes, capture those deltas and reconcile them at the final watermark. Without a reliable delta method, extend the maintenance window or narrow the cutover rather than allowing two systems to write the same fact.

Can historical orders, customer passwords, and payment cards move together?

Do not assume so. Historical orders can use a migration app or API; Shopify customer CSV cannot carry an external password, so customers normally reactivate or reset access. Card numbers and payment tokens depend on the provider, compliance controls, and subscription app. Decide which history belongs in Shopify and which stays in controlled archive, with payment and privacy approval for any token or subscription path.

Will moving to Shopify automatically preserve Google rankings?

No. One-to-one redirects, equivalent content, canonicals, hreflang, sitemaps, internal links, media, status codes, and post-launch monitoring all matter. Do not send every old product, category, and article to the homepage. Continue checking crawling, 404s, redirect chains, and organic landing pages after launch and repair high-value routes from the ledger.

When is the migration actually complete?

When data, relationships, amounts, stock, payments, tax, shipping, accounts, email, SEO, integrations, and team SOPs pass written acceptance, and rollback or compensation has been rehearsed with evidence. A working domain is a publishing step, not acceptance. During the 30-day stabilization period, the old data should remain controlled, queryable, and recoverable.

First-party sources and version note