Przejdź do treści
Wydajność 4 min czytania

Wydajność checkoutu B2B - limit kredytowy, walidacje, finalizacja zamówienia

Checkout to ostatnia ścieżka klienta przed kupowaniem. Wolny checkout = porzucenia koszyka, frustracja, telefony do biura obsługi „mi się sklep zaciął". W B2B checkout jest dłuższy niż w B2C - kilka kroków, walidacje, czasem workflow akceptacji. Każdy krok musi być szybki, każda walidacja musi mieć timeout, każda awaria musi mieć recovery. Bez tego nawet dobry sklep traci konwersję na finiszu.

Jakub Owsianka Autor
Zaktualizowano:
Okladka artykulu: Wydajność checkoutu B2B - limit kredytowy, walidacje, finalizacja zamówienia (kategoria: Wydajność)
Okladka artykulu: Wydajność checkoutu B2B - limit kredytowy, walidacje, finalizacja zamówienia (kategoria: Wydajność)
Spis treści (8)

W skrócie

  • 1. Target: każdy krok checkoutu < 1.5s, finalizacja < 2.5s
  • 2. Walidacja w koszyku (soft): cache 5-10 min, klient widzi info wcześnie
  • 3. Walidacja finalna (hard): synchroniczna, na ostatnim kroku
  • 4. Async po zamówieniu: email, SMS, push do BaseLinker, fakturowanie
  • 5. Idempotency obowiązkowe: klient kliknie 2× „Złóż zamówienie" - tylko jedno trafia do ERP
  • 6. Recovery z błędów: klar komunikat, możliwość retry, nie ginące dane koszyka

Walidacje w B2B - co konkretnie

Checkout B2B sprawdza więcej niż B2C:

1. Stan magazynowy. Czy produkty wciąż dostępne (klient mógł je dodać tydzień temu).

2. Cena kontraktowa. Czy cennik się nie zmienił między dodaniem a kupnem.

3. Limit kredytowy. Czy saldo + limit pozwalają na to zamówienie.

4. Workflow akceptacji. Czy klient ma prawo zamówić powyżej swojego progu.

5. Adres dostawy. Czy adres jest poprawny (NIP, kod pocztowy, kraj).

6. Metoda płatności. Czy klient ma prawo do tej metody (np. nie wszystkie firmy mają BNPL).

7. Magazyn źródłowy. Czy klient ma dostęp do produktów z preferowanego magazynu.

8. Promocje i kupony. Czy kupon wciąż ważny, czy nie został użyty.

Każda walidacja = potencjalne wywołanie do ERP / WMS / silnika cen.

Soft vs. hard validation

Soft validation (w koszyku):

  • Cache friendly (TTL 5-10 min)
  • Info dla klienta: „uwaga, przekroczysz limit o X zł"
  • Klient może iść dalej (sprawdzimy ostatecznie przy potwierdzeniu)

Hard validation (na ostatnim kroku):

  • Bez cache, synchronicznie
  • Blokująca: błąd = klient nie zamawia, dostaje konkretny komunikat
  • Po sukcesie: zamówienie wchodzi do systemu

Praktyka:

Klient w koszyku:
  -> Soft check stan (Redis cache 60s)
  -> Soft check cena (Redis cache 10 min)
  -> Soft check limit (Redis cache 5 min)
  -> Wyświetl uwagi (jeśli)

Klient klika "Przejdź do podsumowania":
  -> Wszystko wciąż soft check (te same cache)

Klient klika "Złóż zamówienie":
  -> Hard check stan (synchronizny call ERP)
  -> Hard check cena (synchronizny call ERP)
  -> Hard check limit (synchronizny call ERP)
  -> Idempotency check (czy już nie zamawiał)
  -> Utwórz zamówienie w DB (transakcja)
  -> Sukces → przekierowanie na potwierdzenie
  -> Async: send email, push do ERP, etc.

Async po zamówieniu

Klient nie czeka na:

  • Email z potwierdzeniem
  • SMS z numerem zamówienia
  • Push zamówienia do ERP (faktura, dokumenty)
  • Push do BaseLinkera / marketplace'ów
  • Generowanie PDF faktury proforma
  • Update Google Analytics, Facebook Pixel
  • Webhook do CRM / marketing automation

Wszystko to do kolejki (RabbitMQ / Redis Streams). Klient dostaje natychmiast „Zamówienie złożone, numer XYZ", reszta dzieje się w tle.

Konsekwencja: czas od „Złóż zamówienie" do potwierdzenia = 1-2.5s (nie 8-15s jak gdyby wszystko sync).

Kolejki RabbitMQ / Redis.

Idempotency - must-have

Klient kliknie 2× „Złóż zamówienie" (frustracja po pauzie). Bez idempotency: dwie zamówienia, dwie faktury, telefon do obsługi.

Strategia:

1. Idempotency token w formularzu. Generujesz unikalny token przy load strony checkoutu. Wysyłasz z każdym żądaniem. Backend sprawdza: ten token już użyty? Zwracam to samo zamówienie.

<form action="/checkout/place-order" method="post">
  <input type="hidden" name="idempotency_token" value="abc123def456">
  <!-- pola formularza -->
</form>
public function placeOrder(Request $request): Response {
    $token = $request->get('idempotency_token');
    $existingOrder = $this->orderRepo->findByIdempotencyToken($token);
    if ($existingOrder) {
        return $this->redirectToOrderConfirmation($existingOrder->getId());
    }
    // Złóż zamówienie...
    $order->setIdempotencyToken($token);
    return $this->redirectToOrderConfirmation($order->getId());
}

2. Disable submit button po kliknięciu. Klasyczny UX trick. JS po kliknięciu wyłącza button. Browser side defense.

3. Server-side rate limiting per session. Max 1 zamówienie / 5 sekund per session. Pomoże nawet jeśli token jest podmieniony.

Recovery z błędów

Co jeśli walidacja zwróci błąd?

Scenariusz 1: Produkt niedostępny.

  • Komunikat: „Produkt X jest niedostępny. Pozostałe pozycje czekają w koszyku."
  • Akcja: usuń produkt z koszyka lub zamień na alternatywę (recommendations)
  • Klient idzie dalej z koszykiem

Scenariusz 2: Cena się zmieniła.

  • Komunikat: „Cena produktu X zmieniła się z 100 zł na 110 zł. Zaakceptujesz nową cenę?"
  • Akcja: klient akceptuje → aktualizujemy koszyk, klient kliknie znów „Złóż"
  • Lub: klient odmawia → wracamy do koszyka

Scenariusz 3: Przekroczony limit kredytowy.

  • Komunikat: „Limit kredytowy: 5000 zł, saldo: 4500 zł, ten koszyk: 800 zł. Brakuje 300 zł."
  • Akcja: opcje (zamów mniej, zapłać kartą, wybierz BNPL, skontaktuj się z opiekunem)

Scenariusz 4: Konieczna akceptacja przełożonego.

  • Komunikat: „Zamówienie powyżej Twojego progu. Wymaga akceptacji szefa zakupów."
  • Akcja: zamówienie w stanie pending, email do akceptującego, klient widzi „Wysłane do akceptacji"

Scenariusz 5: ERP nie odpowiada (timeout).

  • Komunikat: „Mamy chwilowy problem z systemem. Próbujemy ponownie..."
  • Akcja: retry × 3 z exponential backoff, jeśli wciąż błąd - zapisz zamówienie w stanie „pending_sync", powiedz klientowi że dostanie potwierdzenie mailem, async sync później

Wydajność per krok

Krok 1: Koszyk.

  • Soft validations w Redis cache
  • Target: <800ms initial render, <300ms quantity update

Krok 2: Adres dostawy.

  • Walidacja kodu pocztowego, NIP
  • Auto-fill z poprzedniego zamówienia
  • Target: <1s

Krok 3: Metoda płatności + dostawa.

  • Dostępne metody zależne od koszyka, klienta, kwoty
  • BNPL decyzja kredytowa (Mondu): 2-10s - to jest ich SLA, nie nasz
  • Target: <1.5s (bez BNPL)

Krok 4: Podsumowanie.

  • Pełna kalkulacja (cena, VAT, dostawa, rabaty)
  • Soft validation cen kontraktowych
  • Target: <1.5s

Krok 5: Finalizacja.

  • Hard validation (sync)
  • Idempotency
  • Async: email, ERP push, etc.
  • Target: <2.5s

Razem: cały checkout < 8s aktywnego czasu klienta. Ale rozłożone na 5 kroków, każdy kontrolowanie szybki.

One-page checkout vs. multi-step

Multi-step:

  • Klasyczne 4-5 kroków
  • Plus: każdy krok prosty, walidowany osobno
  • Plus: łatwiej analizować drop-off
  • Minus: więcej kliknięć

One-page:

  • Wszystko na jednej stronie
  • Plus: szybsze dla returning customers
  • Plus: lepsze conversion w B2C
  • Minus: longer page, więcej do walidacji, trudniej UX-em

Dla B2B z 5-7 walidacjami przy każdym kroku - multi-step zazwyczaj lepiej. Klient B2B i tak nie kupuje impulsywnie.

Najczęstsze błędy

1. Wszystko sync na finalizacji. Walidacje + ERP + email + analytics → 10-15s. Klient czeka, klient zniecierpliwiony, klient klika powtórnie → duplikat.

2. Brak idempotency. Klient kliknął 2× → dwa zamówienia.

3. Komunikaty błędów techniczne. „Error code 500" zamiast „Brak dostępności, produkt X usunięty z koszyka".

4. Ginące koszyki po błędzie. Klient ma 30 pozycji, error przy walidacji, klient wraca do koszyka - pustego.

5. Brak save before logout. Klient kupuje, sesja wygasa, koszyk znika.

6. Walidacje hard za wcześnie. Cena kontraktowa walidowana w koszyku synchronicznie → każde dodanie = call ERP, koszyk wolny.

7. Brak monitorowania checkout. Drop-off na konkretnym kroku - bez analytics nie wiesz. Sklep traci konwersję.

FAQ

Czy mogę zrobić one-page checkout w Magento? Tak, są moduły (Aheadworks One Step Checkout, Mageworx). Domyślny Magento checkout jest multi-step.

Czy walidacja limitu kredytowego musi być synchronizna? Hard walidacja - tak. Klient musi wiedzieć przed potwierdzeniem czy zamówienie wejdzie. Soft walidacja w koszyku - cache jest ok.

Co jeśli ERP padnie podczas finalizacji? Strategia: zamówienie w stanie pending_sync zapisane w sklepie, klient dostaje numer i info „dostaniesz mail po sync z ERP", async job retry'uje sync.

Czy mogę użyć BNPL bez B2B credit limit z ERP? Tak - to dwie osobne metody. BNPL bierze decyzję u dostawcy (Mondu/Billie). Klient bez kontraktu może kupić z BNPL.

Czy guest checkout ma sens w B2B? Rzadko. B2B prawie zawsze wymaga login + NIP. Wyjątek: małe sklepy z mieszanym B2C/B2B, gdzie część klientów to mali B2B (sole proprietor).

Co dalej

O autorze

Jakub Owsianka

Architekt rozwiązania w WiseB2B - silniku platform B2B. Zaczynał po stronie biznesu (własne sklepy), potem deweloper, dziś projektuje wdrożenia dla sklepów z katalogami w dziesiątkach tysięcy SKU. W ostatnich latach wdrożył AI-development w zespole i funkcjonalności oparte o AI bezpośrednio w silniku sklepu.

Masz pytanie do tego artykułu?

Dodatkowy kontekst, problem z własnym wdrożeniem, druga opinia - napisz wprost. Odpowiadam osobiście w 1-2 dni robocze.