Kiedy klient pyta mnie "ile trwa migracja sklepu", staram się odpowiedzieć uczciwie zanim powiem jakąkolwiek liczbę. Bo "migracja sklepu" to jedno z tych wyrażeń, które brzmią jak pojedynczy projekt, a w rzeczywistości są zestawem kilkunastu osobnych problemów technicznych — każdy z własnym poziomem trudności, własnym ryzykiem i własnym oknem na złe decyzje, których skutki wychodzą tygodniami po go-live.
Nie piszę tego jako ostrzeżenie. Piszę to dlatego, że po kilkunastu latach robienia migracji — Shoptet do PrestaShop, WooCommerce do PrestaShop, Magento do WooCommerce, stary sklep na domowym rozwiązaniu do czegokolwiek nowoczesnego — mam dość sytuacji, w której klient dowiaduje się o komplikacjach dopiero gdy je obaj widzimy w produkcji.
Bazy danych, które wyglądają podobnie, ale nie są
Każda platforma e-commerce ma własny model danych. Nie chodzi o format pliku ani o to, że jedna używa MySQL a druga PostgreSQL. Chodzi o to, że ten sam koncept — produkt, zamówienie, klient, kategoria — jest w różnych platformach zmodelowany inaczej na poziomie relacji między tabelami, typów pól, hierarchii zależności i logiki biznesowej zakodowanej bezpośrednio w strukturze bazy.
WooCommerce przechowuje atrybuty produktów jako meta pola w wp_postmeta — płaska tabela klucz-wartość ze zserializowanymi danymi PHP. Jeden produkt z pięcioma wariantami to kilkadziesiąt wierszy w tej tabeli, z których część zawiera zserializowane tablice PHP niemające bezpośredniego ekwiwalentu w żadnym innym systemie. PrestaShop przechowuje produkty w osobnych tabelach: ps_product, ps_product_lang (tłumaczenia), ps_product_attribute (kombinacje), ps_product_attribute_combination (powiązania atrybutów z kombinacjami), ps_stock_available (stany per kombinacja per magazyn). Magento idzie jeszcze dalej — model EAV (Entity-Attribute-Value) oznacza, że każdy atrybut produktu żyje w osobnej tabeli, a zapytanie o kompletny produkt to JOIN przez kilkanaście tabel.
Migracja danych produktowych między tymi systemami to nie konwersja CSV. To transformacja modelu danych — tłumaczenie jednej ontologii na drugą. Przy prostym katalogu płaskich produktów bez wariantów idzie względnie sprawnie. Przy tysiącu produktów konfigurowalnych, z atrybutami wielowariantowymi, cenami per grupa klientów, z powiązanymi produktami i cross-sellami — każda kategoria danych wymaga osobnego mapowania, osobnego skryptu transformacji i osobnego zestawu przypadków brzegowych.
I nie chodzi tylko o mapowanie jeden-do-jednego. Niektóre koncepcje w platformie źródłowej po prostu nie istnieją w platformie docelowej w tej samej formie. Shoptet ma "parametry produktu" — system atrybutów wyszukiwalnych zintegrowany z filtrowaniem kategorii. PrestaShop ma własny system cech (features) i atrybutów (attributes) z inną logiką podziału. To nie jest kwestia mapowania pola na pole — to decyzja architektoniczna: jak chcesz, żeby ta struktura działała w nowym systemie? I ta decyzja wymaga rozumienia obu platform, nie tylko jednej.
Konta klientów: hasła, których nie masz
To jest problem, o którym klienci dowiadują się najczęściej zbyt późno, i który generuje więcej frustracji niż cokolwiek innego w całej migracji.
Hasła klientów są hashowane. Każda platforma używa własnego algorytmu — WooCommerce używa PHPass (własna implementacja bcrypt z solą), PrestaShop używa MD5 lub własnego wariantu w starszych wersjach, nowsze bcrypt lub argon2i, Magento własnego algorytmu z solą per użytkownik. Gdy migrujesz bazę klientów, masz tabele z hashami haseł — ale hashe z systemu źródłowego są bezużyteczne w systemie docelowym, bo docelowy nie wie jak je weryfikować.
Technicznie jest kilka podejść, żadne nie jest idealne.
Pełny reset haseł — wysyłasz e-mail do każdego klienta z informacją o migracji i linkiem do ustawienia nowego hasła. Proste, bezpieczne, transparentne. Ale wymaga przygotowania komunikacji, wymaga obsługi klientów którzy nie dostali maila albo go zignorowali jako phishing, i generuje skumulowany load supportu w pierwszych dniach po go-live. Przy bazie 5000 klientów, z których 10–15% będzie miało problemy z resetem — to realna praca przez kilka dni.
Migracja z podwójną weryfikacją — przy pierwszym logowaniu po migracji system próbuje zweryfikować hasło starym algorytmem, po sukcesie hashuje je na nowo własnym. Technicznie eleganckie, niewidoczne dla klienta. Problem: wymaga niestandardowego kodu w systemie docelowym, który musi działać poprawnie przez cały okres przejściowy, i musi być potem usunięty. Przy platformach SaaS ten wariant nie wchodzi w grę — nie masz dostępu do logiki autoryzacji.
Wymuszony reset przy pierwszym logowaniu — kompromis. Klient istnieje w nowym systemie, ma całą historię zamówień dostępną po zalogowaniu, ale musi przez reset przejść.
We wszystkich wariantach jest jeden wspólny mianownik: klienci muszą zostać o migracji poinformowani. I to poinformowani dobrze — nie jednolinijkowym systemowym "twoje hasło zostało zresetowane", ale komunikacją która wyjaśnia co się zmienia, dlaczego, i co klient ma zrobić. Źle przeprowadzona komunikacja migracyjna generuje fale negatywnych opinii na Allegro i w Google niezwiązanych z jakością nowego sklepu — tylko z dezorientacją klientów.
Historia zamówień: co zabrać, a czego nie da się przenieść
Historia zamówień to dane, które klienci uważają za swoje — i mają rację. Zamówienie złożone dwa lata temu, które klient chce zobaczyć dla celów gwarancyjnych, powinno być dostępne po migracji.
W praktyce to jeden z najtrudniejszych elementów. Zamówienie w systemie e-commerce to nie prosty rekord — to graf zależności: zamówienie → pozycje zamówienia → produkty (które mogły zmienić się lub zostać usunięte) → klient → adres dostawy → adres faktury → metoda płatności → metoda dostawy → historia statusów z timestampami → faktury → notatki → zwroty. Każdy element musi być poprawnie zmapowany, przy czym część może nie mieć bezpośredniego odpowiednika w nowym systemie.
Produkty usunięte ze sklepu nadal figurują w historycznych zamówieniach. W systemie źródłowym są zazwyczaj zachowane jako snapshot ceny i nazwy w tabeli order items. W systemie docelowym trzeba zdecydować: czy tworzysz placeholderowe produkty "archiwalne" żeby historia była kompletna, czy akceptujesz że część pozycji będzie wyświetlać się bez pełnych danych?
Statusy zamówień są specyficzne dla platformy. "Zrealizowane" w Shoptecie nie jest tym samym co "completed" w WooCommerce czy "Livré" w PrestaShop, nawet jeśli semantycznie znaczą to samo. Przy migracji historycznych statusów trzeba zadecydować jak mapować stany pośrednie — zamówienia otwarte w momencie migracji, zamówienia częściowo zrealizowane, zamówienia ze zwrotem części pozycji.
Metody płatności i dostawy zmieniają nazwy. Bramka płatnicza z trzech lat temu mogła zmienić nazwę albo przestać istnieć. Można migrować nazwy dokładnie — co skutkuje historią z metodami których nowy sklep nie obsługuje — albo mapować na obecne, co jest mniej precyzyjne ale bardziej użyteczne.
Opinie o produktach: problem z wiarygodnością
Opinie zebrane w starym sklepie to jeden z najbardziej wartościowych zasobów — i jeden z najtrudniejszych do poprawnej migracji.
Technicznie przeniesienie treści jest względnie proste: tabela z tekstem, oceną, datą, autorem. Tu zaczyna się problem wiarygodności.
Większość platform weryfikuje opinie na poziomie systemu — przed wyświetleniem sprawdza czy istnieje powiązanie między użytkownikiem który ją wystawił a zamówieniem produktu, którego dotyczy. To mechanizm antyspamowy i sygnał zaufania dla kupujących. Po migracji te powiązania mogą być uszkodzone: IDs klientów zmieniają się przy migracji, IDs produktów zmieniają się, historyczne zamówienia mogą nie być poprawnie powiązane z kontami.
Jeśli migrujesz opinie bez zachowania tych powiązań — nowy system może je wyświetlać jako "niezweryfikowane" albo w ogóle odfiltrować jako potencjalny spam. Jeśli migrujesz je ze sztucznymi powiązaniami — ryzykujesz że platforma docelowa uzna je za manipulowane. Ma to znaczenie szczególnie przy Allegro i innych marketplace'ach gdzie integracja opinii sklepowych wpływa na pozycję ofert.
Ekosystem opinii zewnętrznych — Trusted Shops, Google Reviews, Ceneo, Heureka — jest jeszcze bardziej skomplikowany. Opinie wystawione przez klientów na tych platformach są związane z domeną i profilem sklepu. Zmiana struktury URL-i, zmiana layoutu stron produktów, zmiana domeny — wszystko to może wpłynąć na widoczność ocen i ich wyświetlanie w wynikach wyszukiwania.
Flow zamówień: zakodowana logika biznesowa
To jest element, który sprawia że estymacja czasu jest najtrudniejsza — bo jest całkowicie różny dla każdego klienta.
Flow zamówienia w "standardowym" sklepie to: koszyk → checkout → płatność → potwierdzenie → realizacja → wysyłka → dostarczone. Żaden sklep z kilkuletnim stażem nie ma jednak "standardowego" flow. Każdy przez lata dostosowywał procesy do własnych potrzeb — poprzez modyfikacje kodu, własne moduły, integracje z zewnętrznymi systemami. I ta logika biznesowa nie istnieje w żadnym pliku eksportu — istnieje w kodzie źródłowym starego sklepu, w dokumentacji której nikt nie pisał, i w głowach osób które z tym sklepem pracują.
Niestandardowe metody dostawy — sklep który sprzedaje wyłącznie palety do firm ma zupełnie inną logikę obliczania kosztów dostawy niż "standardowy" sklep paczkowy. Reguły "jeśli zamówienie waży więcej niż X ton albo wartość jest wyższa niż Y, zadzwoń po wycenę" są zakodowane w jakimś module, który trzeba przepisać od nowa lub znaleźć odpowiednik w nowej platformie.
Niestandardowe statusy zamówień — sklep który sam produkuje towar ma statusy "Przyjęte do produkcji", "W trakcie produkcji", "Gotowe do wysyłki" których żadna standardowa platforma nie ma. Wszystkie powiadomienia e-mail do klientów, wszystkie reguły automatyzacji w Base.com, wszystkie integracje z ERP są podpięte pod te statusy.
Niestandardowe reguły cenowe i rabaty — sklep który ma program lojalnościowy, ceny per grupa klientów, rabaty ilościowe, ceny negocjowane per klient B2B — każda z tych reguł musi być odtworzona. Platformy mają różne możliwości w tym zakresie, co wymaga kompromisów lub niestandardowego kodu.
Integracje z zewnętrznymi systemami — ERP, system magazynowy, program księgowy, Base.com, Brevo, firma kurierska z własnym API. Każda integracja musi być przetestowana od nowa w nowym środowisku. Zmiany w strukturze danych (nowe IDs produktów, zamówień, klientów) wymagają aktualizacji po stronie zintegrowanych systemów. Mapowania statusów które działały latami muszą być zrekonfigurowane.
Dlaczego "mamy backup" nie rozwiązuje problemu
Jednym z częstszych argumentów jest "w razie czego zawsze możemy wrócić do starego sklepu". Technicznie prawda. Praktycznie — nie.
Przez czas kiedy nowy sklep działa, nawet przez kilka dni, pojawiają się nowe zamówienia. Te zamówienia istnieją tylko w nowym systemie. Powrót do starego oznacza ich utratę, albo ręczne przepisywanie, albo uruchomienie obu systemów jednocześnie — co jest technicznie możliwe ale operacyjnie koszmaryczne.
Każde zamówienie złożone po go-live jest transakcją realną — klient zapłacił, czeka na towar. Nie ma "testowego trybu produkcyjnego".
Co realnie robi różnicę
Nie piszę tego żeby odstraszać od migracji. Piszę to żeby migracja była przeprowadzona z otwartymi oczami.
Migracja zrobiona dobrze wygląda tak: dwa do czterech tygodni analizy zanim zostanie napisana jedna linia kodu migracyjnego. Inwentaryzacja wszystkich niestandardowych funkcjonalności starego sklepu. Decyzja co migrować, co przepisać od nowa, a co porzucić jako przestarzałe. Środowisko staging gdzie migracja jest przeprowadzana i testowana wielokrotnie — nie raz, ale kilkanaście razy z różnymi zestawami danych. Skrypty migracyjne które są idempotentne — można je uruchomić wielokrotnie i zawsze dostaje się ten sam wynik. Komunikacja do klientów przygotowana i wysłana przed, nie po go-live. Plan obsługi supportu na pierwsze 48 godzin.
I harmonogram który nie mówi "migracja zajmie 2 tygodnie", ale "migracja produktów i kategorii zajmie tydzień, migracja klientów z komunikacją zajmie dwa tygodnie, odtworzenie logiki flow zamówień zajmie tyle ile zajmie po inwentaryzacji".
Klient który rozumie ten proces i jest gotowy przez niego przejść — ma szansę na migrację która nie kończy się dwutygodniowym kryzysem po go-live. Klient który chce "szybkiej migracji" — dostaje ją, ale płaci za nią przez następne miesiące.