Migrating away from osCommerce and Zen Cart to a custom Solidus store

osCommerce and Zen Cart are among the oldest open source carts still running real shops, and because they are self hosted PHP and MySQL applications you already own the database, so the data comes out cleanly. The hard part is never the export. It is the age of the software underneath: an ageing architecture, a stack of community add ons nobody has updated, security and PHP version pressure from your host, and a shrinking pool of developers who know these systems. In this article I walk through the move off osCommerce or Zen Cart onto a custom Solidus store, specifically for these platforms: what you own, what is locked, how the database and tools really work, where the traps are, and the honest plan. For the deep detail of how each kind of data travels, I link to the guides that own it.

What osCommerce and Zen Cart are, and who outgrows them

osCommerce is one of the original open source shopping carts. It began in March 2000 in Germany, written by Harald Ponce de Leon, and for years it was the default way to put a shop online without paying a licence fee.1 Zen Cart is its best known descendant: a fork that branched off the osCommerce code in 2003, took a different direction on templates and features, and grew into a project of its own.2 Both are written in PHP, both keep everything in a MySQL database, and both are software you host yourself on your own server. Neither charges you rent. Zen Cart is released under the GNU General Public License, so the source is open for you or any developer to read and change.3

These two carts still run thousands of real shops, some of them profitably, some of them barely touched in a decade. I want to be fair about that from the first line. If your osCommerce or Zen Cart store is small, stable, inexpensive to keep running and causing you no trouble, you should probably leave it alone. Age on its own is not a reason to spend money. This article is not for that shop.

It is for the long lived shop that has started to feel its age. The symptoms are specific. Your host emails to say the version of PHP your shop runs on is being switched off, and the shop does not run on the new one without work. The template was hand edited years ago by a developer you can no longer reach. The add ons that make the shop yours were downloaded from a forum in 2013 and nobody has updated them since. You went looking for someone to make a change and found that developers who know these systems well are getting harder to find and more expensive to book. The shop works, but every change feels like it might bring the whole thing down. If that is where you are, this is the honest shape of a move onto a modern, owned stack. I build that replacement on Solidus, an open source shop framework on Ruby on Rails, and I run the move.4 The result belongs to you. For the deep, platform independent detail of how each kind of data travels, I link out to the guides that own it rather than repeat them here, starting with the pillar, what moves and what does not.

What you own, and what is locked

Because both carts are self hosted, the single most important fact about leaving them is in your favour: the database is yours. Everything the shop knows lives in MySQL tables you can read directly, with names such as products, customers, orders and categories sitting right there. A plain dump with mysqldump hands you the lot, and from there the work is ordinary, careful mapping into a new model rather than a fight for access. Compare that with a hosted platform, where you only ever get the exports the vendor decides to give you, and you can see why an owned, self hosted shop is kinder to leave. On the thing that frightens people most, your data, these old carts are generous.

What is locked is not the data. It is the behaviour built around it. The table below is the honest division.

WhatHow it travelsWhere it goes
Products, options, attributes, prices, images, categories, stockClean, through a database dump or the add on import tools, as a mapping exerciseThe Solidus product model, see products and catalogue data
Customer accounts and addressesClean, but passwords are hashed and cannot be reusedRebuilt with a reset or a verify at first login, see customer accounts
Order and purchase historyAs records, for reference and customer serviceA read only history in the new shop
SEO keywords and URLsAs a list to map, not to copyA redirect table in the new shop
Payment configuration and saved cardsNot portable, each module stores it differentlyRebuilt around your own gateway account, see payment tokens
Template edits, add ons and integrationsDo not travel at allRebuilt as owned, tested code

The export and database reality

These carts were designed before rich REST APIs were a normal thing to expect, and it shows. You do not migrate off osCommerce or Zen Cart by calling a tidy interface that lists every product and order. You migrate from the database, and the sooner you accept that the smoother the project runs.

Direct database access is the real route and the strongest one. You own the server, so a full dump is always available, nothing is summarised away, and nothing is hidden behind a vendor's idea of what you should be allowed to see. For a catalogue of any size, or an orders table built up over fifteen years, this is what I actually work from.

The admin import and export tools sit on top of that, and it is worth being precise about them because people assume more is built in than really is. In Zen Cart the common way to move product data in bulk is an add on from the Plugins Library, not a core feature: tools such as DbIo and EasyPopulate read and write CSV files, and a product import is keyed on the model number of each item.5 They do a real job for catalogue work, but two cautions matter. First, they cover the standard product tables and not whatever an add on or a hand edit tucked away elsewhere, so the spreadsheet is a starting point, not the whole truth. Second, an import run against a live database can be destructive if a column is wrong, which is exactly why I reconcile everything against a direct dump. osCommerce is the same shape: the data is all in MySQL, and the clean way out is the database, not an API that was never built for a full export.

Passwords never move, and that is fine

No password comes across in a form a customer could log in with, from either cart, because neither one stores the password itself. Current Zen Cart hashes each password with PHP's own password_hash function using the default algorithm, which today is bcrypt, and older code paths used a salted scheme of their own.6 The classic osCommerce line, and older Zen Cart installs, reach further back still, to salted MD5 style hashing from an era when that was normal. In every case the stored value is one directional. It cannot be turned back into the password, so there is nothing to carry over that would let someone sign in.

This is a feature, not a loss, and the plan around it is the one the customer accounts guide sets out in full. Every account, with its name, addresses and order history, is created in the new shop. On the first visit the customer either sets a new password through a one time link, or, if you choose to carry the old hashes across, has the old hash verified once and then silently replaced with the new shop's format so they never notice. Whichever route you take, nobody ever sees a password in the clear, and the rebuilt account is attached to all of the customer's history. Carrying ageing MD5 style hashes into a brand new shop just to avoid a reset is the one thing I would not do; a clean reset on a modern scheme is the safer default for a shop this old.

The real reason to move is age, not data

Almost nobody leaves these carts because the data is trapped. They leave because the software underneath has aged, and the cost and risk of keeping a long lived shop on it have crept up year on year. There are four honest pressures, and it is worth separating them, because the two projects are not in the same state.

The first is the architecture and the templating. These carts were designed around the web of fifteen or twenty years ago. The template is a set of PHP files you edit in place, and years of small edits by different hands turn into a layer that only its last author understood. Modern expectations, a fast storefront, a clean mobile experience, structured data for search, a checkout that meets today's rules, are all reachable, but each one is retrofitted onto a frame that was not built for it.

The second is the add on ecosystem, and this is where the shop's real behaviour usually lives. A working osCommerce or Zen Cart shop of any ambition is rarely the core cart. It is the core plus a stack of community add ons downloaded over the years: a better search, layered navigation, a trade pricing module, abandoned basket emails, a reviews system, an SEO URL add on, a feed for marketplaces, a payment module or two. Each came from a different author on a different schedule, many have not been touched in years, and the knowledge of what each one really does often left with the developer who installed it. That stack is the single most valuable and most dangerous thing to understand in a migration, because it is the difference between the shop you think you have and the shop you actually have.

The third is security and PHP version pressure, and this is usually what forces the decision. These are PHP applications, and PHP itself moves on: older versions stop receiving security fixes from the PHP project on a published schedule, and hosts eventually refuse to run them.7 A shop written for PHP 5 or an early PHP 7 does not simply run on a current version; the language changed underneath it. Current Zen Cart has kept up: the 2.2.x line is built for PHP 8.2 through 8.5 and current MySQL or MariaDB, version 2.2.2 shipped on 4 April 2026, and Zen Cart was in fact the first open source shop application to earn full certification under the card industry's security standard for payment applications.89 So a Zen Cart shop that has been kept current is in a defensible place, and the pressure there is mainly the weight of old add ons. The classic osCommerce Online Merchant line is a harder story: its last widely run stable release, 2.3.4.1, dates to 2017, and while a separate, modern osCommerce rewrite exists and targets current PHP, moving the classic shop onto it is a rebuild, not an update.110 Either way, a shop stranded on an unsupported PHP version is running on a platform that no longer gets security fixes, and that is a business risk, not a developer's preference.

The fourth is people. Far fewer developers work fluently with these specific carts than a decade ago, and the ones who do are increasingly the only ones who can safely touch your particular stack of add ons. Depending on a shrinking pool of specialists for a system at the centre of your business is a quiet risk that only becomes loud at the worst possible moment.

My case for a custom Solidus store is not that Rails is fashionable. It is that you replace an ageing cart plus a tower of other people's add ons, each a dependency you do not control, with one modern application that is yours, that has tests proving it behaves, that runs on a supported language and framework, and that any competent Rails developer can maintain. Solidus is open source under the permissive BSD licence, so the shop I build carries no licence fee and no lock in of its own.4

SEO URLs and the redirect map

Both carts build page addresses from query strings by default, so a product sits at something like index.php?products_id=42 on osCommerce or index.php?main_page=product_info&products_id=42 on Zen Cart. Most long running shops added an SEO URL module at some point to turn those into readable addresses with the product or category name in them. Either way, every one of those addresses is something a customer may have bookmarked and a search engine has indexed, and on a shop that has traded for a decade they carry real ranking.

The move to a new shop is where that value is most often thrown away, and it has nothing to do with these carts specifically and everything to do with discipline. Every address that received a visit or a link in the last year has to be mapped to its new home with a permanent redirect that points straight at the final page, not through a chain. The full method, and why most ranking loss in a migration comes from missed redirects rather than from the move itself, is in the products and catalogue guide. The one platform specific note is a happy one: because your URL keywords and product identifiers live in database tables you can read directly, the first draft of the redirect map is a query, not a crawl. On the shops I build the redirects then live inside the application as an editable table, so they survive every future deploy and your own staff can add one when they spot a stray in Search Console.

Payments and saved cards

Payments are where an old cart migration stops being tidy, and they are the thing to settle first, not last. In both osCommerce and Zen Cart each gateway is a separate payment module, often an ageing one, and each stores its configuration, and any reference to a saved card, in its own way. There is no single, portable vault to hand over. What actually matters is who holds the card data, and the answer is never the cart: it is your payment provider. If your shop already charges cards through its own account with a modern provider such as Stripe, the saved cards belong to that account, and the new Solidus shop can connect to the same account so the cards simply stay where they are. If instead the cards sit inside a provider you only ever reached through an old payment module, moving them means a provider to provider transfer that the receiving processor will accept only from another holder certified to the top level of the card security standard, and that transfer never includes the subscriptions or the payment history alongside the cards.

Decide your payment provider before a line of the new shop is written, because that one decision determines whether returning customers keep their saved cards or have to enter them again. The payment tokens guide walks through every case, and if the subject makes you nervous, the hidden dangers of switching payment gateways is the cautionary version. If your shop sells anything on a repeating basis, treat that as the hardest part of the whole move and raise it on day one: the mandate that lets you charge a customer again lives with the gateway, not in the cart, so a live subscription cannot simply be exported and replayed, and sometimes the honest answer is that existing subscribers have to re authorise.

A worked example

Let me make this concrete with an invented shop. Harbourside Teas (harboursideteas.example) is a Brighton business that has sold loose leaf tea, blends and brewing kit online since 2009. It runs Zen Cart, turns over about £900,000 a year online, carries roughly 1,800 products once tin sizes and gift sets are counted, and has a modest but loyal subscription side: a monthly tea club billed through an old payment module. Over sixteen years the shop has gathered a dozen community add ons, a hand edited template, and an SEO URL module, and the trade pricing for its wholesale accounts is wired in through an add on nobody has documented.

The owner's problem is not that the shop is broken. It is that the hosting company has given notice that the PHP version the shop depends on will be switched off, the shop does not run on the current PHP without real work, and the one developer who knew the add ons has retired. The quote to drag everything onto a supported PHP version comes close to the cost of a fresh start, for no new capability. She has decided to stop patching an ageing cart and own a modern shop instead.

Here is how the move goes. The clean part comes first and reassures everyone. A full database dump, and from it the 1,800 products with their sizes, prices, stock and images map onto the Solidus catalogue over a couple of weeks of careful matching. The customer records, wholesale accounts included, come across with their addresses and order history, passwords excepted. The order history is brought in as read only reference, three years deep, with the older records kept in the archived export. The URL keywords are read straight from the database into the first draft of the redirect map, around 3,000 rows that one person then checks by hand.

Then the hard parts, which were raised in week one, not week ten. The undocumented trade pricing is reverse engineered by reading the add on and the data, and rebuilt as a real, tested feature of the new shop rather than a patch. Payments are the pivot. The old monthly tea club runs through a dated module whose provider cannot cleanly hand over the recurring mandates, so the honest plan is agreed early: new subscriptions start on the new provider from day one, and existing members are asked once, with notice, to re authorise, with a short grace period so nobody is cut off. Card payments move to the shop's own account with a modern provider so ordinary saved cards are not disturbed. Fourteen weeks after the first workshop, Harbourside cuts over on a quiet Tuesday morning in its slowest month, keeps the old Zen Cart install running untouched for thirty days as a fallback, and only then retires it. A year on, the shop is one maintained application on a supported language, with tests, no forum add ons to keep agreeing with each other, and the wholesale rules written down where the next person can read them.

The honest move plan

Stripped to its bones, leaving osCommerce or Zen Cart for a custom Solidus store runs like this. First, discovery: list every add on and template edit and write down what each one really does, pick the payment provider, settle how any subscriptions will be handled, and name the one person inside the business who owns the data. Second, the build: stand up the Solidus shop, write the import scripts, and run them again and again against a copy of the real database until the import is boring. Third, map the catalogue and the customers, and turn the hidden add on logic into tested features. Fourth, build the redirect map from the URL keyword tables and check every row. Fifth, a parallel run of a few weeks with the catalogue frozen, rehearsing the final import twice. Sixth, cut over on a quiet weekday morning, place a real test order on every payment method, check the top redirects by hand, and keep the old shop as a fallback for thirty days before retiring it.

Through all of it the principle is the one in the pillar: move the shop as it is, make it stable, and only then improve it. Turning a migration into a redesign at the same time doubles the risk and makes it impossible to tell which change caused a dip. This is also where the money question belongs, and the five year cost of moving to Solidus works the numbers honestly, while the platform comparison sets the owned route beside the rented ones.

When you should stay

I would rather lose the work than sell you a move you do not need, so here is when to stay. Stay if your osCommerce or Zen Cart shop is small, the add ons you depend on are few and still maintained, your host still supports the PHP version you run, and the bill is bearable. Stay if nothing is actually blocking you and the only complaint is a vague sense that the software is old. Stay if you cannot name the person in your business who understands the data, the trade rules and why the old product codes carry the suffixes they do, because without that person any migration, to any platform, produces a tidy new shop full of wrong data. A Zen Cart shop in particular, kept current on a supported PHP version, can be a perfectly reasonable place to stay for a while yet.

Move when the add on stack has become a tax and a risk, when your host is switching off the PHP version the shop needs and the upgrade costs as much as a fresh start for nothing new, when the rules that run your business are trapped in modules nobody can read, when the developers who know your particular setup have become hard to find, and when you want a shop you own outright, on a supported stack, that can be tested properly. Who actually owns your business data is the principle underneath it all. If you are weighing other self hosted carts in the same breath, I have written the same honest guide for leaving OpenCart and for leaving PrestaShop.

The workshop

If you run an osCommerce or Zen Cart shop and you are not sure whether you have finally outgrown it, bring it to a free workshop and the first two weeks of work are on me. Bring your add on list, whatever your host has told you about PHP, and whatever you know about the template edits and the undocumented modules. Together we read what the shop actually does, work out what moves cleanly and what has to be rebuilt, flag the payment and subscription questions first, and I tell you honestly whether a move pays off for you. Sometimes it does not, and I will say so.

Footnotes

  1. osCommerce, official project site (osCommerce V4 runs on PHP 8.3 with support from PHP 7.4 and MariaDB 10.x, described as a free open source shopping cart, with the project history dated from 2000), checked 14 November 2026, https://www.oscommerce.com/ ↩ ↩2

  2. Zen Cart, encyclopaedia overview confirming Zen Cart is a software fork that branched from osCommerce in 2003 and is written in PHP, Wikipedia, checked 14 November 2026, https://en.wikipedia.org/wiki/Zen_Cart ↩

  3. Zen Cart, licence file (GNU General Public License version 2), GitHub, checked 14 November 2026, https://github.com/zencart/zencart/blob/master/license.txt ↩

  4. Solidus, the open source ecommerce framework on Ruby on Rails under the BSD 3 clause licence, GitHub, checked 14 November 2026, https://github.com/solidusio/solidus ↩ ↩2

  5. Zen Cart documentation, EasyPopulate (an add on from the Plugins Library, alongside DbIo, that imports and exports product data as CSV files, keyed on the model number of each product), checked 14 November 2026, https://docs.zen-cart.com/user/products/easypopulate/ ↩

  6. Zen Cart source, includes/functions/password_funcs.php (zen_encrypt_password returns password_hash with PASSWORD_DEFAULT, which currently resolves to bcrypt, with a salted scheme in older code), GitHub, checked 14 November 2026, https://github.com/zencart/zencart/blob/master/includes/functions/password_funcs.php ↩

  7. PHP, Supported Versions (each PHP release line receives active and then security support on a published schedule, after which it is end of life and receives no further fixes), checked 14 November 2026, https://www.php.net/supported-versions.php ↩

  8. Zen Cart documentation, Server Requirements (Zen Cart v2.2.x is designed for PHP 8.2 through PHP 8.5, with MySQL 5.7.8 or newer or MariaDB 10.2.7 or newer), checked 14 November 2026, https://docs.zen-cart.com/user/first_steps/server_requirements/ ↩

  9. Zen Cart, README and release log (v2.2.2 released 4 April 2026, v2.2.1 on 20 March 2026 and v2.1.0 on 23 November 2024; Zen Cart described as the first open source ecommerce web application to be fully certified under the card industry payment application security standard), GitHub, checked 14 November 2026, https://github.com/zencart/zencart/releases ↩

  10. osCommerce, Online Merchant repository (the self hosted PHP and MySQL shop, with the classic 2.3.4.1 stable release dating to 2017 and a separate modern rewrite), GitHub, checked 14 November 2026, https://github.com/osCommerce/oscommerce2 ↩

If you run an osCommerce or Zen Cart shop and you are not sure whether you have finally outgrown it, bring it to a free workshop and the first two weeks of work are on me. Bring your add on list, whatever your host has told you about PHP, and whatever you know about the template edits, and together we will work out what moves cleanly and what has to be rebuilt, and whether a move pays off for you. Sometimes it does not, and I will say so.

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