[ Sklepy internetowe ]

Sklep spięty backendowo z marketplace’ami

Jeden stan magazynowy na wszystkie kanały, z rezerwacją po stronie sklepu — bo ten sam ostatni egzemplarz kupują dwa marketplace’y w tej samej sekundzie.

Live · 2026 · PHP · WooCommerce · MySQL · Redis · REST API · TypeScript

Potok

  1. 1

    jeden-stan

  2. 2

    mapowanie-ofert

  3. 3

    zamowienia

  4. 4

    zgodnosc

4 etapy · 2026

O projekcie

Sklep, który jest JEDNYM MIEJSCEM pracy sprzedawcy, a marketplace’y są jego kanałami — nie odwrotnie. Stan magazynowy, oferty, ceny, zamówienia, wysyłki, zwroty i dokumenty sprzedaży żyją po stronie sklepu; do Allegro, Erli, Empiku czy Amazona idzie z nich projekcja, a wraca sprzedaż. Sprzedawca nie loguje się do czterech paneli, żeby zobaczyć, ile ma towaru.

Rozstrzygnięciem całego projektu jest to, że STAN MAGAZYNOWY NIE JEST LICZBĄ, TYLKO WYŚCIGIEM. Ten sam ostatni egzemplarz potrafią kupić dwa kanały w tej samej sekundzie, a między nimi jeszcze klient w sklepie. Architektura „wysyłamy stany co pięć minut” nie jest więc synchronizacją — jest zakładem o to, że w tym oknie nikt nie kupi. Przy jednym kanale zakład zwykle wychodzi, przy czterech przestaje.

Dlatego rdzeniem jest REZERWACJA PO STRONIE SKLEPU, atomowa i wspólna dla wszystkich kanałów: zamówienie z dowolnego źródła najpierw zdejmuje sztukę z puli, a dopiero potem jest potwierdzane. Kanały dostają stan już pomniejszony o rezerwacje, a nie surowy stan półki. Liczba wysyłana na zewnątrz jest więc zawsze mniejsza od prawdy — i to jest cecha, nie strata.

Nadsprzedaż kosztuje bowiem więcej niż sprzedaż utracona, i to nie w jednym wymiarze. Anulowanie zamówienia z winy sprzedawcy wchodzi na marketplace’ach do WSKAŹNIKÓW JAKOŚCI, a te przy przekroczeniu progu kończą się obniżeniem widoczności ofert albo ich zawieszeniem. Jedna przesadnie odważna liczba w stanach potrafi więc wyłączyć kanał na tygodnie — dlatego bufor bezpieczeństwa jest parametrem kanału, nie zaokrągleniem w dół.

Druga rzecz, której nie widać z zewnątrz: PRODUKT TO NIE OFERTA. Jeden towar staje się kilkoma ofertami, a każdy kanał ma własne drzewo kategorii, własny zestaw parametrów obowiązkowych, własne wymagania co do EAN i własny model wariantów — gdzieś rozmiar jest osobną ofertą, gdzieś wariantem tej samej. Mapowanie tych różnic jest w tym projekcie pracą główną, a nie konfiguracją na jeden wieczór.

Cena też nie jest jedna. Prowizja zależy od kategorii, do tego dochodzi koszt wysyłki wliczony w ofertę i opłaty za wyróżnienie. Ta sama kwota, która w sklepie daje zdrową marżę, przy piętnastoprocentowej prowizji bywa sprzedażą poniżej kosztu. Cennik liczy więc marżę PER KANAŁ i umie odmówić wystawienia oferty, która schodzi poniżej progu — zamiast sprzedawać ze stratą w tempie kilkuset sztuk dziennie.

Po stronie zamówień obowiązuje założenie, że każda wiadomość przyjdzie dwa razy albo nie przyjdzie wcale. Webhooki gubią się, powtarzają i przychodzą w złej kolejności, więc identyfikator zamówienia z kanału jest kluczem, zapis jest wstawieniem-albo-aktualizacją, a cykliczne odpytywanie stoi obok jako siatka bezpieczeństwa. Zamówienie ma trafić do sklepu dokładnie raz — niezależnie od tego, ile razy kanał o nim opowie.

Całość jest zbudowana wokół założenia, że KANAŁ KIEDYŚ ODMÓWI WSPÓŁPRACY: zmieni wersję API, wprowadzi nowy parametr obowiązkowy albo po prostu przestanie odpowiadać. Awaria jednego kanału nie ma prawa zatrzymać pozostałych ani wstrzymać sprzedaży we własnym sklepie, a rozjazd stanów jest WYKRYWANY cyklicznym porównaniem, a nie zakładany — bo cicha rozbieżność rośnie i ujawnia się dopiero anulowaniem u klienta.

Problem

Sprzedawca prowadził sklep i trzy kanały marketplace osobno. Stany przepisywał arkuszem raz dziennie, ceny poprawiał ręcznie po każdej zmianie prowizji, a zamówienia spisywał z czterech paneli do jednego pliku. Skutki były dwa i oba kosztowne. Po pierwsze nadsprzedaż: ten sam towar sprzedawał się równolegle w dwóch miejscach, anulacje szły na konto sprzedawcy i wskaźniki zaczęły zjeżdżać w stronę progu zawieszenia ofert. Po drugie ślepota na marżę — przy kategoriach o wyższej prowizji część asortymentu schodziła poniżej kosztu, a nikt tego nie widział, bo cena w sklepie wyglądała poprawnie.

Rozwiązanie

Sklep stał się jedynym źródłem prawdy, a kanały — projekcją. Rezerwacja stanu jest atomowa i wspólna: zamówienie z dowolnego kanału zdejmuje sztukę z tej samej puli, więc równoległy zakup nie ma czego sprzedać podwójnie. Synchronizacja wyszła z crona do kolejki z priorytetami, która respektuje limity zapytań każdego kanału osobno — stany idą przed cenami, ceny przed opisami. Ceny liczy cennik kanałowy z prowizją i kosztem wysyłki, z twardym progiem marży. Zamówienia wchodzą idempotentnie, a osobna kontrola zgodności codziennie porównuje stan sklepu ze stanem w kanałach i kończy się kodem wyjścia, zamiast raportem, który nikt nie czyta.

Funkcje

  • Jedna pula stanu dla sklepu i wszystkich kanałów, z rezerwacją zakładaną atomowo przed potwierdzeniem zamówienia.
  • Bufor bezpieczeństwa jako parametr kanału — osobno dla towarów rotujących szybko i dla długiego ogona.
  • Kolejka synchronizacji z priorytetami zamiast crona: stany przed cenami, ceny przed treścią oferty.
  • Limity zapytań pilnowane per kanał, z wykładniczym odczekaniem i bez blokowania pozostałych kanałów.
  • Mapowanie produktu na ofertę kanału: drzewo kategorii, parametry obowiązkowe, EAN i model wariantów.
  • Cennik kanałowy z prowizją kategorii i kosztem wysyłki; oferta poniżej progu marży nie wychodzi.
  • Idempotentny odbiór zamówień: klucz zewnętrzny kanału, wstawienie-albo-aktualizacja, odpytywanie jako siatka.
  • Tłumaczenie statusów świadomie STRATNE i opisane — sklep nie udaje, że każdy kanał ma te same etapy.
  • Zwroty i reklamacje z terminami liczonymi według reguł kanału, nie jednym terminem dla wszystkich.
  • Jedna numeracja dokumentów sprzedaży dla wszystkich kanałów, z myślą o JPK i o tym, że to dalej ta sama firma.
  • Codzienna kontrola zgodności stanów i cen, kończąca się kodem wyjścia — rozjazd jest zdarzeniem, nie wierszem w raporcie.
  • Pomiar wskaźników sprzedawcy (anulacje z winy sklepu, spóźnione wysyłki), zanim zrobi to marketplace.

Moduły

  • rdzen-stanow

    usługa

    Jedna pula stanu z rezerwacjami — wspólna dla sklepu i każdego kanału.

    • Rezerwacja zakładana w transakcji, przed potwierdzeniem zamówienia; brak sztuki oznacza odmowę, nie ujemny stan.
    • Stan wysyłany do kanału to pula pomniejszona o rezerwacje i bufor — nigdy surowa liczba z półki.
    • Rezerwacja ma czas życia: porzucony koszyk zwalnia sztukę sam, bez sprzątania ręcznego.
    • Każda zmiana puli jest wpisem w rejestrze ruchu, więc różnicę da się prześledzić do zamówienia.
  • kolejka-kanalow

    usługa

    Porządkuje wysyłkę zmian do kanałów i pilnuje limitów każdego z nich osobno.

    • Priorytety: stan magazynowy przed ceną, cena przed treścią oferty — bo nadsprzedaż jest droższa niż stary opis.
    • Limit zapytań liczony per kanał; przekroczenie wstrzymuje TEN kanał, a nie całą synchronizację.
    • Ponowienia z wykładniczym odczekaniem i sufitem prób; zadanie, które padło trwale, ląduje w martwej kolejce z powodem.
    • Zmiany są scalane: dziesięć poprawek stanu tego samego towaru wychodzi jako jedno wywołanie.
  • mapownik-ofert

    usługa

    Zamienia jeden produkt sklepu w oferty spełniające wymagania konkretnych kanałów.

    • Mapa kategorii sklep → kanał wraz z parametrami obowiązkowymi tej kategorii.
    • Walidacja PRZED wysłaniem: brak EAN albo parametru obowiązkowego zatrzymuje ofertę u nas, z czytelnym powodem.
    • Warianty tłumaczone na model kanału — tam, gdzie rozmiar jest osobną ofertą, powstaje osobna oferta.
    • Zmiana wymagań po stronie kanału zgłasza się jako lista ofert do uzupełnienia, nie jako cicha odmowa API.
  • cennik-kanalowy

    silnik reguł

    Liczy cenę i marżę osobno dla każdego kanału, zamiast wystawiać jedną kwotę wszędzie.

    • Składniki: cena bazowa, prowizja kategorii, koszt wysyłki wliczony w ofertę, opłaty za wyróżnienie.
    • Twardy próg marży: oferta poniżej progu nie wychodzi, a sprzedawca dostaje listę takich towarów.
    • Reguły są danymi z datą obowiązywania — zmiana prowizji przez kanał nie wymaga wdrożenia.
    • Kwoty w groszach, zaokrąglenie na końcu i raz; przeliczenie tej samej pozycji zawsze daje ten sam wynik.
  • odbior-zamowien

    usługa

    Wprowadza zamówienie z kanału do sklepu dokładnie raz.

    • Identyfikator zamówienia z kanału jest kluczem unikalnym — powtórzony webhook aktualizuje, nie tworzy drugiego.
    • Odpytywanie cykliczne stoi obok webhooków jako siatka na wiadomości, które nie przyszły wcale.
    • Kolejność zdarzeń nie jest zakładana: starszy stan nigdy nie nadpisuje nowszego.
    • Zamówienie zdejmuje stan przez rdzeń rezerwacji, a nie własnym zapytaniem — jedno miejsce decyduje o puli.
  • tlumacz-statusow

    biblioteka

    Mapuje etapy zamówienia między kanałami i mówi wprost, gdzie tłumaczenie jest stratne.

    • Czysta funkcja bez dostępu do sieci i bazy, więc ma testy na każdy znany etap każdego kanału.
    • Stany, które u nas nie mają odpowiednika, są nazwane i widoczne, zamiast być spłaszczone do „w realizacji”.
    • Przejścia niedozwolone są odrzucane — zamówienie nie wraca z wysłanego do nowego, choćby kanał tak twierdził.
    • Nowy status nieznany bibliotece zatrzymuje przetwarzanie TEJ pozycji i zgłasza się imiennie.
  • zwroty-kanalowe

    usługa

    Prowadzi zwroty i reklamacje według terminów tego kanału, z którego przyszło zamówienie.

    • Termin na zwrot liczony z reguł kanału i daty doręczenia, nie z jednej wartości dla wszystkich.
    • Zwrot oddaje sztukę do puli dopiero po przyjęciu towaru, a nie po zgłoszeniu chęci.
    • Korekta dokumentu sprzedaży powstaje razem ze zwrotem, nie osobnym procesem w księgowości.
    • Reklamacje mają własną ścieżkę — spór z kupującym nie jest tym samym co zwrot towaru.
  • dokumenty-sprzedazy

    usługa

    Jedna numeracja i jeden zestaw dokumentów niezależnie od kanału sprzedaży.

    • Numeracja ciągła dla wszystkich kanałów — sprzedaż przez marketplace to dalej sprzedaż tej firmy.
    • Dane nabywcy z kanału uzupełniane o wymagania podatkowe; brak danych blokuje dokument, nie fałszuje go.
    • Korekty powiązane z dokumentem pierwotnym, z powodem i numerem zwrotu.
    • Eksport w postaci gotowej do księgowości, z rozbiciem na kanały do celów analitycznych, nie numeracyjnych.
  • kontrola-zgodnosci

    usługa

    Codziennie porównuje to, co sklep myśli, z tym, co kanał pokazuje.

    • Porównanie stanów, cen i statusu ofert; różnica jest zdarzeniem z kodem wyjścia, nie wierszem w raporcie.
    • Rozjazd próbuje się najpierw ZALECZYĆ powtórzeniem synchronizacji, a dopiero potem alarmuje.
    • Kontrola nigdy nie pisze do kanału niczego poza ponowieniem — nie „naprawia” danych, których nie rozumie.
    • Wynik zapisuje historię, więc widać, czy rozjazdy rosną, czy to był jednorazowy wypadek.
  • wskazniki-sprzedawcy

    usługa

    Mierzy to, za co marketplace karze, zanim marketplace to policzy.

    • Anulacje z winy sprzedawcy, spóźnione wysyłki i czas odpowiedzi liczone w oknach zgodnych z regułami kanału.
    • Ostrzeżenie przy zbliżaniu się do progu, a nie po jego przekroczeniu.
    • Przypisanie anulacji do przyczyny: brak towaru, błąd mapowania, awaria kanału — bo tylko pierwsza jest winą sklepu.
    • Wskaźniki widoczne razem ze sprzedażą, żeby decyzja o agresywnym stanie miała obok siebie swój koszt.
  • panel-jednego-miejsca

    panel

    Ekran, na którym sprzedawca widzi wszystkie kanały naraz i wie, co wymaga jego decyzji.

    • Zamówienia ze wszystkich kanałów w jednej liście, z oznaczeniem źródła i terminem wysyłki.
    • Oferty wstrzymane z powodem: brak parametru, cena poniżej progu, odrzucenie przez kanał.
    • Stan kolejki synchronizacji i martwa kolejka widoczne wprost — cisza nie ma wyglądać jak sukces.
    • Każda akcja masowa pokazuje skutek PRZED wykonaniem: ile ofert się zmieni i w których kanałach.

Architektura

Sklep
WooCommerce (PHP) jako źródło prawdy o towarze, cenie bazowej i zamówieniu
Integrator
Usługa w TypeScripcie, kolejka zadań, wdrożenie kontenerowe obok sklepu
Baza
MySQL — pula stanu, rezerwacje, mapowania ofert, zamówienia kanałowe, rejestr ruchu
Rezerwacja stanu
Transakcja z blokadą wiersza; brak sztuki to odmowa, nigdy stan ujemny
Kolejka
Redis; priorytety stan → cena → treść, scalanie zmian, martwa kolejka z powodem
Limity kanałów
Okno liczone osobno dla każdego kanału, wykładnicze odczekanie, sufit prób
Kanały
Allegro, Erli, Empik, Amazon — każdy przez własny adapter za wspólnym kontraktem
Odbiór zamówień
Webhooki z kluczem zewnętrznym (wstawienie-albo-aktualizacja) + odpytywanie jako siatka
Ceny
Grosze, prowizja kategorii i koszt wysyłki w regule z datą obowiązywania, twardy próg marży
Dokumenty
Jedna numeracja dla wszystkich kanałów, korekty powiązane ze zwrotem, eksport do księgowości
Kontrola zgodności
Codzienne porównanie stanów i cen z kanałami, kod wyjścia 1 przy rozjeździe
Poświadczenia
Klucze kanałów poza repozytorium, rotacja bez przestoju, każdy dostęp zapisany
Testy
Kontraktowe na adapterach (nagrane odpowiedzi kanałów) + scenariusze wyścigu o ostatnią sztukę

Technologie

  • PHP
  • WooCommerce
  • MySQL
  • Redis
  • REST API
  • TypeScript

Autor

  • Zdjęcie: Mariusz PerzyńskiMariusz PerzyńskiClient Relations & Operations

[ Kontakt ]

Chcesz podobne rozwiązanie w swojej firmie?

Opowiedz nam o swoim pomyśle — wrócimy z konkretną propozycją i wyceną.

Automatic AI

hello@automaticai.pl · automaticai.pl