Migrating away from PrestaShop to a custom Solidus store
TL;DR
Difficulty: Intermediate
- You already own your PrestaShop data: the MySQL database, the CSV import tool and the Webservice API all give good access, so the move is not about escaping a lock.
- The real reasons to leave are the module tower, the upgrade pain between major versions, and the cost of keeping a mature PHP install healthy.
- Passwords are hashed with bcrypt and cannot be reversed, so customers set a new password once on their first visit after cutover.
- The hardest streams are saved cards and live subscriptions, because both live with the payment gateway, not with PrestaShop; I settle them before any build.
- A lean, well maintained PrestaShop is often right to keep; the mover is the shop weighed down by modules and upgrades that wants one owned, tested Rails application instead.
What to read first
PrestaShop is an open source PHP platform you host yourself, which means your data access is already good and leaving is never about escaping a vendor's export tool. Shops outgrow it for a different reason: the weight of modules, the pain of major upgrades, and the cost of keeping a mature install healthy. In this article I stay specific to PrestaShop, how its database, CSV import and Webservice API actually hand data over, what stays locked, and the traps around modules, payments, subscriptions and URLs. For the deep detail on each data type I link the companion pieces rather than repeat them.
What PrestaShop is, and who outgrows it
PrestaShop is an open source shop platform written in PHP. You download it, run it on your own server, and it sits on a MySQL or MariaDB database that belongs to you.1 The core is released under the OSL 3.0 licence, with the native modules and the Classic theme under AFL 3.0, so nobody can switch your shop off or take a cut of your sales.2 It has been widely used across Europe for years, including here in Ireland, and for a lean shop with an ordinary catalogue it is a sensible, capable platform. If that is your shop, this is not an article telling you to leave.
The business that outgrows PrestaShop rarely leaves because the software cannot sell. It leaves because of the weight it has gathered over the years. A real PrestaShop store tends to carry a tower of modules, several of them paid, and each one has to stay compatible with the others and with the core. Major version changes have been painful: the jump from 1.6 to 1.7 rebuilt the theme architecture and started moving the back office onto Symfony, and a 1.6 theme would not run on 1.7.3 The jump from PrestaShop 8 to PrestaShop 9, released on 10 June 2025, lifted the framework from Symfony 4.4 to Symfony 6.4, dropped older PHP, removed the legacy product page and changed how product URLs are built, and the project itself warns that modules and themes may need updating.4 None of that is a scandal. It is the honest price of owning a mature PHP application that a chain of third parties also has to maintain.
So the person moving is not unhappy with selling online. They are tired of the upkeep: module licences that must all agree, an upgrade project every couple of years, the constant attention to hosting and security, and a shrinking pool of developers who still want to work on an ageing install. What they want instead is one owned, tested application they control, which is the case I make for a custom Solidus store.
This article is the honest shape of that move. The deep, platform independent detail lives in a set of companion pieces, beginning with what moves and what does not, and I link to them rather than repeat them. Here I stay specific to PrestaShop: what it hands over cleanly, what it keeps back, how its export and its API really behave, and the traps that belong to it in particular.
What you own, and what stays behind
PrestaShop's real strength as a platform to leave is the same one WooCommerce has: because you host it, you already hold the data. The database is yours, the files are yours, and nothing hides behind a vendor's export tool that can be throttled or withdrawn. Raw access to your records is therefore excellent. The difficulty is never getting the data out. It is that some of it is tied up in modules, overrides and formats that do not travel, and that a few things cannot move at all, for reasons no platform can change.
Here is the honest split for a typical PrestaShop shop.
| What moves cleanly | What needs work or is locked | How I handle it |
|---|---|---|
| Products, combinations, categories, prices, images, stock | Theme and template logic, which is PrestaShop specific | Rebuilt as a Solidus storefront. See the products spoke |
| Customers, addresses, order and invoice history | Passwords, which are hashed and never reversible | Carried as data, the password set anew once. See the customers spoke |
| SEO friendly URLs, for a redirect map | Payment configuration and saved tokens, held per module and per gateway | Mapped to 301 redirects. See the payment tokens spoke |
| Everything readable in MySQL | Business logic buried in custom modules and overrides | Reimplemented as tested Rails code |
| Subscription records, as data | Live subscription billing tied to a payment module | Rebuilt and, where needed, migrated with the gateway's help. See the subscriptions spoke |
The pattern is the one every honest migration follows. The nouns move well. The verbs, the behaviour that lived in modules and in the theme, get rebuilt. Who legally owns each of these records, and why that matters at handover and to your obligations to the Data Protection Commission, is the subject of who actually owns your business data.
The export and the API, in detail
PrestaShop gives you three honest ways to get data out, and a real migration uses all three.
The CSV import and export tools. Under Advanced Parameters there is a built in import tool that reads CSV files for a fixed set of entities: Categories, Products, Combinations, Customers, Addresses, Brands, Suppliers, Aliases, Store contacts, and supply orders when advanced stock management is enabled.5 It is a genuinely useful tool, and the shape it expects tells you a lot about the data model. It also has quirks worth knowing before you rely on it. The field separator is a semicolon, so any semicolon inside your text fights the parser. Every row must carry the same number of columns. Categories must exist before the products that reference them, so you import categories first, by ID. Each import covers a single language, so multilingual data has to be split into one file per language. Image URLs must be absolute and reachable. And there is a "delete all before import" option that does exactly what it says.5 For getting data out, the product list in the catalogue exports to CSV, and anything the screens do not cover you take from the database.
The Webservice API. PrestaShop ships a REST style Webservice, switched off by default. You enable it under Advanced Parameters, on the Webservice page, and create a key there, and that same key can be set to read only or granted rights method by method and resource by resource, so you can expose customers and orders for reading without handing out write access anywhere.6 Authentication is HTTP Basic with the key as the username and no password, which makes the key the whole secret and something to guard as one; the documentation advises sending it in an Authorization header rather than in the URL.7 The endpoint lives at /api/ at the root of the install and needs URL rewriting on the web server. Calling the root lists the resources your key can reach, among them customers, addresses, orders and order_histories.7 One detail matters for a migration script: the Webservice historically spoke XML, and you switch the output to JSON with an output_format=JSON parameter or an Output-Format header, but as of PrestaShop 8.1 the Webservice outputs only JSON and still cannot read JSON on writes.7 PrestaShop 9 adds a separate, newer Admin API built on API Platform with OAuth2 tokens, which points the way ahead but is still described by the project as a work in progress.8 There is no platform imposed rate limit of the kind a hosted platform applies: the ceiling is your own server, which in practice means pulling large resources in pages and off peak.
Direct database access. Because the entire shop sits in MySQL that you own, the most complete and reliable export is simply to read the database. For a migration I treat the database as the source of truth and the Webservice as a convenience, because the database holds everything, including the module tables the API never exposes. This is the quiet advantage of a self hosted platform, and the reason PrestaShop hands over better than any hosted rival.
Passwords, and why they reset
Here owning the database does not rescue you. PrestaShop hashes customer and employee passwords. It does not store them. Current versions hash with bcrypt, through PHP's password_hash and PASSWORD_BCRYPT, and still accept an older md5 scheme when verifying a legacy hash so that old accounts keep working.9 Since PrestaShop 8.0 there is also a password strength policy based on the zxcvbn library.10 A bcrypt hash cannot be turned back into the original password, by design, so there is nothing to carry into a new shop that would let a customer log in with their existing password unchanged.
The honest consequence: on a custom Solidus store, customers set a new password once, through a single secure link, on their first visit after cutover. Handled as a prepared service message rather than a launch day surprise, it is a non event. I set out exactly how in the customers spoke, including keeping the consent records and addresses intact so that only the password is new.
The traps that are specific to PrestaShop
Every platform has its own places where a migration loses time or money if you do not see them coming. These are PrestaShop's.
The module tower. What makes a PrestaShop shop go is rarely the core on its own. It is thirty or forty modules, several of them commercial, bought through the official PrestaShop Addons marketplace.11 Each brings its own configuration, and some hold real business logic: a pricing rule, a shipping calculation, a loyalty scheme. When you move, that logic does not export as data. It has to be read out of the modules, understood, and rebuilt. The good news is that rebuilding it as tested Rails code ends the dependency for good. The honest news is that finding all of it is the real discovery work, and a module nobody remembers buying is exactly where surprises hide.
Overrides. PrestaShop lets developers change core behaviour by dropping files into an override folder. It is a reasonable mechanism, and it is also where years of undocumented decisions pile up. Before a move I search the overrides and the custom modules for logic the business depends on and that exists nowhere else, because an override stays invisible until it breaks.
Payment configuration and tokens. Payments in PrestaShop are modules, and each payment module stores its configuration and its saved card references in its own way. There is no single, portable "saved cards" export, because the card data never belonged to PrestaShop in the first place. It sits with the payment provider. The cleanest outcome is to keep the same gateway and reconnect the new shop to the same account, so stored tokens stay valid. Where the gateway changes, saved cards generally do not travel, and I flag that at the very start, not the end. The deep version is in the payment tokens spoke, and the risks of changing gateway at all are in the hidden dangers of switching payment gateways.
Subscriptions. PrestaShop has no native recurring billing. Subscriptions come from a module, and that module is usually bound to one payment gateway that holds the mandate and runs the charges. Subscription records export as data easily enough, but the live billing relationship, the thing that actually takes money next month, is the hardest part of any migration and often needs the losing gateway's cooperation to move without interrupting customers. It is the first question I ask, not the last. The subscriptions spoke sets out the options honestly.
URLs and SEO. PrestaShop builds SEO friendly URLs, and your rankings and backlinks hang off them. PrestaShop 9 changed the default so that product URLs no longer include the category,4 a reminder that URL structure is a platform decision you have been living inside. On a custom store you decide the structure, and every old URL that earned a visit or a link gets a permanent 301 redirect to its new home. That redirect map is tedious, owned work, and skipping it is the most common way a migration quietly loses traffic. The mechanics are in the products spoke.
The honest move onto a custom Solidus store
A move off PrestaShop is not one project, it is five streams, and each maps to one of the companion pieces.
The catalogue is the easy stream: products, combinations, categories, prices and images read out of MySQL, mapped onto Solidus products and variants, and checked. Customers with their addresses and order history come across as records, with passwords reset at first login. The redirect map turns every meaningful old URL into a 301. Payments are reconnected to the same gateway wherever possible so tokens survive. Subscriptions are planned first, because they are the one stream that can hold up a launch.
What gets rebuilt, rather than migrated, is the storefront and the business logic the modules carried. That is the part that costs money in year one, and it is also the part that stops costing you afterwards, because it becomes your own tested code with no licence and no vendor between you and it. I describe how every feature ends up with an executable test, so that you can read what your own shop promises, and I put the full five year arithmetic of owning against renting in the total cost of ownership article and the platform by platform comparison in Solidus vs Shopify vs Shopware vs Magento vs WooCommerce. Because WooCommerce is the other common self hosted open source platform people weigh at the same time, its honest exit is in migrating away from WooCommerce.
A worked example
Let me make it concrete with an invented business. Claddagh Cycle Parts (claddaghcycleparts.example) is a Galway retailer selling bicycle components and consumables, with about 9,000 products and combinations, strong search rankings built over a decade, and a small but loyal subscription side: a monthly consumables club where members pay a fixed sum in euro and receive a box of chain lube, brake pads and tubes, charged through a subscription module tied to their saved card. The shop runs PrestaShop 1.7, carries forty two modules, eleven of them paid, and the owner has twice deferred the upgrade to PrestaShop 8 because the quote frightened her and two of the paid modules have no compatible version. Her developer has moved on, and the new agency wants a retainer just to keep the thing patched. She is not unhappy with selling online. She is unhappy with the upkeep.
On a first look I sort the streams by difficulty, hardest first. The consumables club is the hard one: I need to know which gateway holds the mandates and whether it will let the stored tokens move, because if it will not, members would have to enter their cards again, and that is a conversation to have before anything is built, not after. The saved cards for ordinary customers are the same question in a gentler form. Those two I flag on day one.
Everything else is reassuringly ordinary. The 9,000 products and their combinations come straight out of MySQL, far more reliably than through the Webservice, and map onto Solidus products and variants. Customers, addresses and a few years of order history come across as records, with passwords reset at first login behind a prepared message. The decade of rankings is protected by a redirect map, every old PrestaShop URL pointed at its new equivalent, which at this size is a couple of thousand rows and two careful days. The eleven paid modules are read for the logic that matters, the club pricing and a wheel builder among them, and that logic is rebuilt as tested code she will own outright.
The result is a Solidus shop that looks like her brand, carries no module licences, has the consumables club as a real feature rather than a bought bolt on, and can be handed to any Rails developer tomorrow. The build costs more in her first year than another year of PrestaShop upkeep would. From the second year on it costs far less, and the upgrade dread is gone, because a tested Rails application is maintained, not periodically rebuilt.
When you should stay on PrestaShop
I would tell several shops to stay. If your PrestaShop is lean, if it runs a handful of modules you understand and keep patched, if a developer you trust keeps it current, and if the catalogue and checkout are ordinary, then PrestaShop is doing its job and a custom build is money spent to solve a problem you do not have. The platform is genuinely good at being a self hosted, owned shop for a business that is comfortable maintaining one. The honest trigger for moving is not dislike of PrestaShop. It is the weight of modules and upgrades outgrowing the value they return, together with a real need for behaviour that a tower of modules only approximates.
If you are the shop that has outgrown it, hold on to this: your data access is already good. You are not trapped. You are weighed down, which is a far better position to move from.
How I would run your move
I build the custom Solidus store and run the migration, and you own the result, code and data alike, once it is paid for. I start with the two questions that can sink a timeline, the saved cards and the live subscriptions, and I get written answers from the gateways before a line of migration code is written. Then the ordinary streams: catalogue out of the database, customers and orders across, the redirect map built and tested, the module logic rebuilt with tests, and a rehearsed cutover with the old shop kept untouched for a month as the fallback.
If a PrestaShop you are tired of maintaining has stopped being worth the upkeep, bring it to a free workshop and the first two weeks of work are on me. I will tell you honestly which streams are easy and which are hard for your specific shop, and if the honest answer is that a lean PrestaShop still serves you, I will tell you that too.