Migrating customer accounts and addresses to a custom store

Moving to a new shop raises one question before any other: what happens to my customers? In this article I give the honest, complete answer for their accounts and addresses. Most of the record, names, emails, phones, addresses, consent and order history, moves across cleanly; the password is the one field that cannot, and I explain why that is the outcome you want. Using an invented Leeds homeware shop with 40,000 customers, I walk through the export, the field mapping, the reconciliation of loyalty and store credit balances, and the reset email that turns a migration into a relaunch.

What really happens to your customers when you move shop

When someone decides to leave a rented platform and move to a custom store, the first worried question is almost never about products. It is about people. Will my customers have to register again? Will I lose their addresses, their order history, the points they have saved? Will I fall foul of data protection law by copying forty thousand records from one system to another?

The honest answer has two halves. Most of a customer record moves across cleanly, and the parts that do not are predictable, small and manageable. One thing genuinely cannot come across, the password, and I will explain below why that is the right outcome rather than a failure. The money a customer holds with you, store credit, loyalty points, a gift balance, is the one area where carelessness does real harm, so that gets the most care. This article is the complete, honest account of what moves, what does not, and the plan for each. The parent article, what moves and what does not when you migrate your shop, sets the wider picture. This one goes deep on the customer.

I build the new shop on Solidus, an open source commerce framework on Ruby on Rails, and the finished store and its data belong to the client. That ownership is the whole point, and it is the thread running through everything below.

The fields that come across cleanly

Start with the good news, because it is most of the record. A customer profile is, underneath, a set of plain fields, and plain fields copy from one system to another without drama. What takes the work is mapping them correctly, not moving them.

Here is what comes across cleanly on every migration I run.

FieldComes acrossNote
NameYesFirst and last, or a single name field
Email addressYesThe key that ties everything together
Phone numberYesBilling and delivery numbers both
Billing addressYesStreet, city, postcode, country
Delivery addressesYesA customer may have several
Company and VAT numberYesImportant for B2B accounts
Order associationYesEach order linked back to its customer
Account creation dateYesKeeps loyalty and tenure honest
Customer groups and tagsYesTrade, wholesale, VIP, and the rest
Marketing consent statusYesWith its timestamp and source, see below

Every platform exposes these, either through a spreadsheet export or through its interface for developers. Shopify's own customer export includes first and last name, email, phone, the default address with its company field, tax status, the marketing consent columns and tags.1 WooCommerce, being WordPress underneath, exposes each customer through its interface for developers with the email, the name, the account creation date, a flag for whether they have ever paid, and full billing and delivery objects carrying company, street, city, county, postcode, country and phone.2 Magento and the others are the same story in different words.

On the Solidus side these land in two models. The customer becomes a user record, and each address becomes a Spree::Address, which stores the name, two street lines, city, postcode and phone and attaches to the user and to each order.3 One detail that shows how these things drift: current Solidus keeps a single name field on the address and has retired the separate first and last name columns,3 so part of the mapping is deciding how a platform that splits the name should fill a store that joins it. None of this is hard. It is a careful translation between two data models, checked by counting.

Why passwords do not move, and why that is the outcome you want

The password is the one field that cannot come with the customer, and it helps to understand exactly why.

A well built shop never stores the password you type. It stores a one way hash of it: the password run through a deliberately slow mathematical function, with a unique random salt mixed in, so that the stored value cannot be turned back into the password even by the people who run the shop. The OWASP guidance on password storage is blunt about it: passwords should never be stored in plain text, a unique salt must be added to each one, and hashing is the right approach precisely because it is one way.4 When a customer logs in, the shop hashes what they typed and compares the two hashes. It never needs to know the real password, and that is the point.

Two consequences follow for a migration. First, the stored hash is useless to any other system, because every platform uses its own hashing scheme, its own parameters and its own salts. Shopify uses one approach, Magento stores a hash alongside its salt and a version marker and has moved over time from SHA256 to Argon2id,5 a newer scheme, and a custom store uses something modern again. A hash made by one recipe cannot be verified by another. Second, even in the rare case where you own the database and could copy a hash across, carrying an old weak hash into a new shop is poor practice. OWASP's advice for a legacy hash is to replace it with a fresh hash of the real password the next time the customer logs in,4 which you can only do once they type it.

So the clean path is not to move the password at all. On the new store every account exists with its profile, its addresses and its order history, but with no usable password, and the customer sets one on their first visit. You can do this two ways: a short welcome page that lets them choose a new password, or a sign in that emails them a one time link and skips passwords altogether. Shopify states plainly that you cannot migrate customer passwords from another shop and that you must invite customers to create new ones.1 That is true of every honest migration, not a quirk of one platform.

Framed as a loss, this sounds bad. Framed honestly, it is a gift. It is the one moment when you can retire whatever ageing hashing your old platform used and move your whole customer base onto a modern scheme in a single step, with nobody ever typing their old password into the new system. The thing to get right is not the technology, it is the warning. Customers must be told, before cutover, that the shop is moving and that they will set a new password on their first visit. A reset nobody expected feels like a breach. A reset you announced feels like a relaunch.

Store credit, loyalty points and gift balances are money, not metadata

If there is one part of a customer migration that keeps me up at night, it is not addresses or passwords. It is balances.

Store credit, loyalty points, gift card balances and wallet balances are not profile fields. They are money your customers are holding with you, and they have every right to expect it to survive the move untouched. Drop a delivery address and the customer retypes it in ten seconds. Drop two thousand loyalty points worth twenty pounds and you have taken money from someone who trusted you, which is both a complaint and, depending on how the balance was sold, a liability you still owe.

So balances get their own small project, separate from the profile import, and it runs like a stocktake. Export every balance from the old system with the customer it belongs to. Total it. Import each balance into the new store as store credit against the matching account. Total the new store. The two totals must agree to the penny before you go live, and any difference is chased down to the individual account, never rounded away or ignored. Where a balance cannot be carried across, for example a gift card tied to a scheme that does not follow you, it is settled with the customer, not quietly deleted. Then you tell people: your points, your credit and your gift balances have come with you, here is your balance, here is how to spend it. Money that moves silently and correctly still earns goodwill when you say so out loud.

Reviews and the things customers wrote

Customers leave more than money and addresses. They leave reviews, ratings, questions and answers, wish lists and sometimes photographs. This content is usually tied to a customer and a product, and it can almost always be exported and reconnected in the new store by matching on the email address or the old customer identifier, so a review keeps its author, its date and its star rating. The one snag is reviews attached to products that no longer exist, which need the same decision as old orders: map them to the product's replacement, or retire them. Reconnecting this content is worth the effort, because a product page with years of genuine reviews converts better than an empty one, and those reviews are your customers' work, not the old platform's property.

Marketing consent is the record you must not lose

Of all the fields that move cleanly, one deserves singling out, because losing it quietly is the mistake that turns a migration into a legal problem.

Marketing consent is not a yes or no flag. Under the GDPR you must be able to demonstrate that a person consented, which means keeping the record of it: that they opted in, when, through what wording and by what action.6 A bare "subscribed: true" copied into the new shop throws away exactly the evidence you would need if a regulator or the customer ever asked. So carry the whole consent record, the status, the timestamp, the source and the wording, not just the switch. Every platform that holds the consent holds these details too, and your job on migration is to keep them attached to the customer rather than flatten them into a flag. Done properly, the move actually strengthens your position, because the consent evidence that was scattered across a platform and three marketing apps now sits in one place that you own.

The law travels with the data, it does not reset

Moving customer records from one system to another feels like it should trigger a fresh round of consent and notices. Usually it does not, and understanding why keeps the move both lawful and calm.

You are still the same business, serving the same customers, for the same reasons. In data protection terms you remain the controller, the purpose of the processing has not changed, and so the lawful basis for holding the data does not change either.7 Order history kept to fulfil contracts and to meet accounting duties stays on that basis. A marketing consent stays a consent. What changes is the software, and the software is a processor acting on your instructions, which is why your platform, your host and I each need a written processing agreement with you.8 Four points make the move clean. Minimise as you go: this is the moment to drop fields you no longer need rather than haul dead data into a fresh system, which is exactly what the law's data minimisation principle asks.9 Honour any erasure request that lands mid migration, so a customer who asked to be forgotten is not quietly reborn in the new shop.10 Update the privacy notice where it names the old platform and host as recipients. And after the final export, close the old account and ask, in writing, for the old copy to be deleted.

There is a deeper advantage here, and it is the real reason to own your store. On a rented platform your customer data is spread across the platform and a row of apps, each one a separate company holding a copy. A custom Solidus store keeps it first party, in one database you control, in the UK or the EU. That is better for the law and better for you, and it is the theme of who actually owns your business data. Before you ever reach a migration, the same discipline applies to choosing who you trust with the data in the first place, which I cover in vetting vendors before they undermine your compliance.

The practical path, step by step

Put together, a customer migration is a short, well rehearsed sequence rather than a single frightening switch.

First, export. Pull the customers out of the old platform, either through a spreadsheet export or through its interface for developers. If you have a large base, plan for the fact that these interfaces are rate limited: the platform drains your requests at a fixed rate and will slow you down past it,11 so forty thousand customers come out in planned batches over hours, not in one impatient burst. Second, map. Decide how each old field fills a field in the new store, including the name question above and which tags become customer groups. Third, import into the Solidus user and address models, in batches, with the marketing consent record and the account creation date intact.3 Fourth, verify by counting: the number of customers, the number of addresses, the number of consented contacts and, above all, the balance totals must match the source before anything goes live. Fifth, run the password flow, so every account is ready for its owner to set a new password or request a sign in link. Sixth, send the message that tells customers the shop has moved and what to do on their first visit.

Saved cards are a separate matter from passwords and belong to your payment provider, not the shop, so they follow their own rules, and I deal with them in migrating payment tokens and saved cards. Do not let anyone fold "and the saved cards" into the customer import as though it were another column. It is not.

A worked example: a Leeds homeware shop with 40,000 customers

Let me make this concrete with an invented business. Calder and Rowe sells homeware from Leeds at calderandrowe.example, on Shopify, and has outgrown it. It has 40,000 customer accounts, of which about 9,000 hold loyalty points, and it runs a store credit scheme for returns. Priya owns it and is moving to a custom Solidus store so she can own her data and build a trade side for interior designers. Nobody here is real and every figure is invented to show the method.

Priya exports her 40,000 customers. Because Shopify limits how fast an app may pull data,11 her export runs in batches through an afternoon rather than all at once. The export carries names, emails, phones, addresses, the company field her trade buyers filled in, the marketing consent columns with their timestamps, tags and tax status.1 It does not carry a single password, exactly as Shopify documents,1 and Priya has planned for that from the start.

The balances are handled as their own stocktake. The old system reports 2.1 million outstanding loyalty points, redeemable at one hundred points to the pound, so a liability of £21,000, plus £6,480 of store credit held across 540 customers who had returns in progress. Both totals are exported against the individual accounts, imported into the new store as store credit, and reconciled. The new store must report £21,000 of points value and £6,480 of credit, to the penny, before launch. One account is forty pence out because of an old rounding bug, and Priya's team finds it and fixes it rather than shrugging, because forty pence wrong on one account means the method is not trustworthy on all of them.

Consent is carried in full. The 23,600 customers who opted into email keep not just the opt in but the date and the wording they agreed to,6 so Priya can still prove consent after the move. The other 16,400 keep their status too, so nobody who opted out is quietly reawakened.

On cutover, every one of the 40,000 accounts exists in the new shop with its addresses, its order history and its reconciled balance, flagged as not yet activated. A week before, Priya sent a service message to every account holder: the shop is moving to a new home, here is the date, on your first visit you set a new password, and your points and store credit have come with you. The message is information about their account, so it goes to all 40,000, not only to those who accepted marketing. On the day, the first visit leads to a short welcome page where the customer sets a password, or asks for a one time sign in link, and lands in an account that already knows them. The support inbox stays quiet, because nothing that happened was a surprise.

What to tell customers, and when

The difference between a migration customers barely notice and one that floods your inbox is almost entirely communication, and it has two strict rules.

The first rule is to separate the service message from any marketing. Telling account holders that the shop is moving and that they will set a new password is information about their account, and it may and should go to everyone, whether or not they accepted marketing. A launch voucher or a "look at our new range" is marketing, and it may go only to the people whose consent you carefully carried across. Fold the voucher into the service message and you have turned a message everyone may receive into one that most of them may not, which is the sort of self inflicted wound that gets a business reported.

The second rule is to tell people before, not after. The welcome page that sets a password should be something customers were expecting, because you told them a week earlier, not a locked door they hit when they try to log in. Said in advance, a password reset reads as a careful relaunch. Sprung without warning, the identical email reads as a security incident. The technology is the same. Only the timing differs, and the timing is the whole job.

Resets are fine, balances are sacred

If you take two things from this, take these. A forced password reset is not damage, it is hygiene, and handled with a little warning it costs you almost nothing and leaves every customer on a modern, safer footing. Balances are the opposite: they are money, they are trust, and they are the one thing a migration must never get even slightly wrong. Get the reset communicated and the balances reconciled, and the rest of the customer record, the names, the addresses, the consent, the history, follows across cleanly into a store you finally own.

Footnotes

  1. Shopify Help Center, Importing and exporting customers (customer passwords cannot be migrated by CSV, customers must be invited to create new passwords, CSV columns for name, email, phone, default address, company, tax status, marketing consent and tags), checked November 2026, https://help.shopify.com/en/manual/customers/import-export-customers ↩ ↩2 ↩3 ↩4

  2. WooCommerce, REST API documentation, Customers (customer properties including email, first_name, last_name, date_created, is_paying_customer and the billing and shipping objects, the password property is marked write only), checked November 2026, https://developer.woocommerce.com/docs/apis/rest-api/v3/customers/ ↩

  3. Solidus, core/app/models/spree/address.rb (Spree::Address stores name, address lines, city, zipcode and phone for users and orders, firstname and lastname are retired as ignored columns), solidusio/solidus on GitHub, checked November 2026, https://github.com/solidusio/solidus/blob/main/core/app/models/spree/address.rb ↩ ↩2 ↩3

  4. OWASP, Password Storage Cheat Sheet (store passwords only as salted one way hashes, never plain text, Argon2id as the first choice, replace a legacy hash with a fresh hash the next time the user logs in), checked November 2026, https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html ↩ ↩2

  5. Magento Open Source, lib/internal/Magento/Framework/Encryption/Encryptor.php (password stored as hash, salt and a version marker joined by a delimiter, hash versions include SHA256 and Argon2id), magento/magento2 on GitHub, checked November 2026, https://github.com/magento/magento2/blob/2.4-develop/lib/internal/Magento/Framework/Encryption/Encryptor.php ↩

  6. UK GDPR, Article 7 (conditions for consent: the controller must be able to demonstrate that the data subject has consented), legislation.gov.uk, https://www.legislation.gov.uk/eur/2016/679/article/7 ↩ ↩2

  7. UK GDPR, Article 6 (lawfulness of processing), legislation.gov.uk, https://www.legislation.gov.uk/eur/2016/679/article/6 ↩

  8. UK GDPR, Article 28 (processor: processing by a processor must be governed by a written contract), legislation.gov.uk, https://www.legislation.gov.uk/eur/2016/679/article/28 ↩

  9. UK GDPR, Article 5 (principles, including data minimisation: personal data must be adequate, relevant and limited to what is necessary), legislation.gov.uk, https://www.legislation.gov.uk/eur/2016/679/article/5 ↩

  10. UK GDPR, Article 17 (right to erasure), legislation.gov.uk, https://www.legislation.gov.uk/eur/2016/679/article/17 ↩

  11. Shopify, API usage: rate limits (Admin API limits enforced with a leaky bucket algorithm, requests are throttled past the sustained rate), checked November 2026, https://shopify.dev/docs/api/usage/rate-limits ↩ ↩2

Worried about what a move does to your customers, their logins or their saved points? Bring it to a free workshop and we will map exactly what moves, what resets and how to reconcile every balance. The first two weeks of work are on me.

1%of every invoice goes to a UK charity you pick.

A donation, never sponsorship. You choose the cause at onboarding.

The story behind the pledge →

Stay ahead of your competition.

The latest innovative products and services, straight to your inbox before your competitors hear about them.

Get up to 5% off your first six months: 1% per topic you pick, the full 5% when you take everything. Limited offer · ends 31 December 2026.

New clients only. Terms apply.

* Up to 5% off your first six monthly invoices, new clients only. Full terms.

Questions about pricing, contracts or how we work together?

Read the FAQ