Moving a shop from a hosted platform to WooCommerce is four migrations wearing one name, and the one everyone plans for is the easiest.
Products
Every platform exports products as a comma-separated file, and WooCommerce imports one. This part usually goes well.
Two things need attention. Variations (sizes, colours) are structured differently by every platform, and a straight import frequently produces separate products instead of one product with options. Check a variable product carefully before importing thousands.
Images are usually referenced by URL rather than included. The import can fetch them, and on a large catalogue that is slow and prone to timing out. Importing in batches is more reliable than one enormous run.
Adding and managing products walks through the structure you are importing into, and understanding it before the import saves redoing it.
Customers, and the password problem
Customer records import. Passwords cannot.
Passwords are stored in a form designed to be irreversible, and no platform can hand another platform something usable. Every customer will have to reset.
What matters is that they are told before they find out. A customer who cannot log in at checkout usually abandons the order rather than working out that a password reset is needed.
Send one clear message before launch explaining that a reset is required and why, and make the reset prominent on the login page for the first weeks.
Orders
Order history is reference data. It does not need to be live, and importing it is the most awkward part of the whole exercise, because order records reference products, customers and statuses that all changed shape.
Two workable choices. Import orders and accept that some fields will be approximate, or do not import them and keep the old platform readable for as long as you need the history.
The second is often better and is rarely considered. Ask what the history is actually for: if it is for occasional lookups and accounting, a readable archive serves that better than an imperfect import.
Addresses are where traffic is lost
Two platforms structure product URLs differently, so almost every address changes.
Every old address needs a permanent redirect to its match. Not to the shop page, to the specific product. Sending everything to the homepage or the catalogue is treated as pages that are gone rather than pages that moved.
Build the map before launch, from the old platform's sitemap and from search data so you know which pages actually have visibility. Planning redirects covers the method, and it is the same job here.
Test the checkout before anything else
Nothing else matters if orders cannot be completed.
Configure the payment gateway, place a real order with a real card, and refund it. Confirm the order appears, the confirmation email arrives, and the payment reaches the account.
Then test a failed payment, and a customer who abandons and returns. Checkout optimisation walks through what that walk-through reveals.
Tax and shipping do not import
These are configuration rather than data, and they are structured differently everywhere. Expect to rebuild them by hand.
Both are worth doing carefully rather than quickly, because errors here are financial rather than cosmetic, configuring tax settings and shipping zones and methods cover them.
Keep the old store
Do not close the old platform on launch day. Keep it accessible, and keep its data exports, for at least a full month.
That month is when you discover what did not come across: a product attribute nobody thought about, a customer note, a discount rule. Once the old system is closed, those are gone.
Plan the cutover itself as a sequence rather than a switch, planning a DNS cutover walks through the window where both are live, and backing up a store walks through protecting the new one from day one.
Match the identifiers before importing anything
An import that runs cleanly and produces a store nobody can order from is usually a mismatch in the fields that link records together.
head -1 products.csv | tr ',' '\n' | nl wp db query "SELECT COUNT(*) FROM wp_postmeta WHERE meta_key='_sku' AND meta_value != '';" wp db query "SELECT meta_value, COUNT(*) c FROM wp_postmeta WHERE meta_key='_sku' GROUP BY meta_value HAVING c > 1;"
The stock code is what connects a product to its variations, its stock level and any historical order. Duplicates in that column produce records that overwrite each other, and empty values produce products that cannot be matched at all.
Clean the file before importing rather than the database afterwards. A second import over the top of a bad first one compounds the problem, because the matching that would have updated the existing records fails again.
Images are the slowest part and the one most often wrong
Product images are usually referenced by address in the export and fetched during the import, which makes the old store a dependency.
wp db query "SELECT COUNT(*) FROM wp_posts WHERE post_type='attachment';" wp db query "SELECT COUNT(*) FROM wp_posts p WHERE p.post_type='product' AND NOT EXISTS (SELECT 1 FROM wp_postmeta m WHERE m.post_id=p.ID AND m.meta_key='_thumbnail_id');"
The second query counts products with no main image, which is the number to check immediately after any import.
If the old store is taken offline before the images have been fetched, they cannot be recovered from it later. Confirm the attachment count looks right while the source is still available, not after the cancellation.
Decide what happens to old order links
A migration changes the address of every product, and the old addresses exist in search results, emails and customer bookmarks.
curl -s https://old.example.com/sitemap.xml | grep -o 'https://[^<]*' > old-urls.txt wc -l old-urls.txt
Capture the old address list before the old store goes away. It is the only source for building redirects, and reconstructing it afterwards is not possible.
Map the ones that matter, which is usually the products that receive traffic rather than all of them. Sending the rest to the relevant category is better than sending them to the home page, and both are better than an error. Redirecting a domain or page deals with writing them.