Moving off a vendor's platform
The previous vendor would not hand the project over. How I took the store's data through its own admin panel and switched sales over without a day's gap.
TL;DR
The Last-mile Delivery Platform migration moved a live delivery store from its previous vendor's platform to mine, without the vendor's help. The vendor did not want to hand the project over, because the support fees would go with it. All the store had was its admin panel, and once an hour I copied the data through that panel's API into a database of my own. The move happened in parts, with a backup before every step. The old platform took its last order on 24 January 2026, and from the 25th orders were coming into the new one. Customers never noticed the move: same website address, same passwords, same order history.
How it started
In December 2025 the store ran on a platform built by another developer. The website, the admin panel, the database and the code were all on the vendor's side, and the store paid the vendor for support. When the store decided to move to a platform of its own, the vendor would not hand the project over: no database export and no code. The domain was held back until the very end as well.
Plenty of businesses know this situation. A vendor who has a store on a support contract loses money by handing the project over, so there is no hurry on their side. Meanwhile the owner has neither the database nor the code, only a login to the admin panel.
What we had
Only the store's admin panel. It ran on an API, and everything the administrator could see, that API returned: orders, customers, products, drivers, promo codes, reports. This is the store's own data, and it could be taken with the same access the store used to run its business.
The collector: a fresh copy every hour
The first thing I wrote was a collector. Once an hour it walked the admin panel's API and stored everything in a PostgreSQL database of my own. Each pass ran in five stages: orders, money, operations, reference data, wallets. Orders were requested in time windows going back a year. The copy held orders with their full status history, customers and their wallets, products with variants, brands, categories, drivers, dispatchers, promo codes, delivery areas and time slots, 30 tables in all. A full pass took about a minute. The collector ran for about a week before the switch.
A copy that refreshes itself gave the store two things. Its data no longer depended on the vendor's goodwill: had the vendor cut off access, the store would still have had a copy no more than an hour old. And the copy turned out more complete than the original: 13 orders that the old system had deleted on its side were still there.
The migration plan
The two systems' schemas had almost nothing in common. The old one used numeric IDs and the new one UUIDs. Statuses, payment methods and delivery types had different names. Some product fields did not exist in the new schema at all. So before moving anything I wrote down a plan:
- IDs go through a mapping table from old ID to new UUID, so links between records do not break and any step can be run again.
- Tables move from reference data to orders: stores, categories, brands, products, customers, staff, zones, slots, promo codes, orders, wallets, banners. Each table only refers to ones already moved.
- The old system's seven statuses collapse into six: "ordered" becomes "pending", "ready" and "assigned" become "confirmed", "accepted by driver" becomes "assigned", "on the way" becomes "picked up", "completed" becomes "delivered", and "cancelled" stays as it is.
- Customers are matched by phone number normalised to one format, or by name where there is no phone.
- The new schema gains 20 product fields that only the old one had: 13 on the product and 7 on the variant.
- Every step stays compatible with what is already running, and a copy of the new database is taken before each step.
Customers' passwords moved with them. The old system stored them as bcrypt hashes, the same algorithm the new one uses, so the hashes went in as they were. Nobody saw the passwords themselves, and no customer had to register again or reset a password.
What had to be redone
In a trial load the order lines came out duplicated: each one landed in the new database eighteen times. I did not fix them one by one. I deleted all the order lines and reloaded them from the copy in one go, because the result of a step like that is easier to check against the source.
Products were matched by name: 133 products out of 133 and 402 variants out of 427. The old system had 139 products and the new one 133. The difference came down to three duplicates and three test products; the real catalogue was the same size on both sides.
Switching over without a day's gap
While the move was going on, the old platform kept taking orders and the collector kept taking a copy every hour. The main run went through on 22 January, and orders from the following days followed into the new database. On 24 January the old platform took its last order, and on the 25th the first order arrived in the new one. Customers' history, their wallet balances and their past orders moved over with them.
The domain had to be taken back separately: the vendor held on to it until the very end. The website stayed at its old address, so nothing changed for customers: same address, same login and password, same order history and the same balance.
How long it took
- 4 January 2026: the first commit of the new platform.
- About a week before the switch: the collector copies the old system every hour.
- 22 January: the main migration run.
- 24 January: the last order in the old system.
- 25 January: the first order in the new one, three weeks after the first commit.
The result
- Not a single day without orders: the last order in the old system on 24 January, the first in the new one on the 25th.
- The old platform's history lives in the new database: 64 delivered orders with their statuses, the customers and their wallets.
- 13 orders deleted by the old system were kept.
- Customers never noticed the move: the website address, passwords, order history and balances stayed the same.
- Everything the store had in the old system was taken back, the domain included.
- Eight months later the store delivered 1,035 orders in September on the new platform. The project story tells how.
If you are in the same position
What I would check first:
- What you have right now: access to the admin panel, the database, the hosting and the domain, and what your contract with the vendor says about data and handing the project over. The domain and hosting accounts should be in your name, not the vendor's; in this project the domain had to be taken back separately.
- Start with a copy. A regular export of everything your admin panel exposes into a database you own is insurance even before you decide to move.
- Compare the copy with the original by number of orders and customers. If something disappears on the vendor's side, you already have it.
- Before the move, write down the ID and status mapping, the table order and the rule of a database copy before every step.
- Switch over once the new system has taken the migrated data and the collector is still running, so orders from the last days follow on.
Questions people ask most
Can you get your data back if the vendor won't hand over the database?
Often, yes. If you have working access to your own admin panel, its API returns everything the panel shows. A collector copies that data over the API into a database you own. It is worth starting with the contract: what it says about the data and about handing the project over.
What happens to orders during the move?
Nothing bad. The old system runs until the last day, the collector copies it every hour, and orders from the final days follow into the new database. The switch happens once everything is already in place. This project did not have a single day without orders.
Will customers have to register again?
No, as long as the old system stored passwords as hashes with a common algorithm. Then the hashes move over as they are, and customers sign in with their old passwords. That is how it went here: both systems used bcrypt, and customers never noticed the move.
How long does it take?
Here it was three weeks from the new platform's first commit to its first order, and the collector ran for about a week before the switch. The time depends on how much data there is and what the admin panel exposes. A firmer estimate is possible once the collector has taken its first copy.
What this migration did not do
- The old platform's code was not carried over: the new one was written from scratch.
- Data was taken only with the store's own access, with no one else's logins and no access to the vendor's servers.