Przejdź do treści
Procesy B2B 6 min czytania

Cenniki kontraktowe per kontrahent w sklepie B2B

Cenniki kontraktowe to nie feature - to warunek istnienia poważnego sklepu B2B. Każdy klient korporacyjny rozmawia z handlowcem o kontrakcie, podpisuje rabat 12%, dostaje progi ilościowe albo specjalne ceny na konkretne kategorie. To wszystko musi być widoczne w sklepie automatycznie, bez ręcznego stosowania kuponów albo dodawania notatek. Implementacja brzmi prosto - jest trudna.

Jakub Owsianka Autor
Zaktualizowano:
Okladka artykulu: Cenniki kontraktowe per kontrahent w sklepie B2B (kategoria: Procesy B2B)
Okladka artykulu: Cenniki kontraktowe per kontrahent w sklepie B2B (kategoria: Procesy B2B)
Spis treści (9)

W skrócie

  • 1. ERP jest źródłem cenników, sklep konsumuje przez API
  • 2. Modele cenników: indywidualny, grupowy, progi ilościowe, czasowe - najczęściej miks
  • 3. Cache Redis obowiązkowy (TTL 5-15 min), bez cache ERP umiera w peak'u
  • 4. Walidacja synchronizna przy checkoutcie (cena z koszyka mogła się zmienić)
  • 5. Antywzorzec: sklep utrzymujący własną logikę cen kontraktowych - zawsze rozjazd z fakturami

Modele cenników w polskim B2B

Z pięciu wdrożeń, te modele występują najczęściej:

Model A: Procent rabatu od cennika. Klient ACME ma -12% na wszystko. Cennik bazowy × 0.88.

Najprostszy, ale ma sufity (klient nie może mieć innej ceny na grupy / produkty).

Model B: Cenniki indywidualne per SKU. Klient ACME na SKU ABC = 12 zł. Na SKU DEF = 15 zł. Na SKU GHI = cena bazowa.

Pełna elastyczność, ale trzymanie tego w ERP wymaga dyscypliny.

Model C: Cenniki grupowe. Klienci „platynowi" (top 20 obrotem) widzą cennik X, „złoci" cennik Y, „srebrni" cennik bazowy.

Średnia elastyczność, łatwiejsze utrzymanie.

Model D: Progi ilościowe. Od 1 szt. 12 zł, od 100 szt. 11 zł, od 1000 szt. 10 zł.

Klasyka hurtu. Wymaga obliczania per ilość w koszyku.

Model E: Cenniki czasowe. Promocja od X do Y. Po przekroczeniu daty wraca cennik standardowy.

Marketing-driven, dodatek do innych modeli.

Model F: Mix. Klient ACME ma 5% rabatu na wszystko + indywidualną cenę na SKU ABC + próg ilościowy od 500 szt. + promocję czasową.

Realny model dla większych klientów.

Skąd cenniki przychodzą

Cenniki żyją w ERP. Każdy poważny ERP ma rozbudowany silnik cen:

Comarch ERP XL:

  • Cenniki bazowe, indywidualne, grupowe, progi ilościowe, promocje
  • Wywołanie API: PriceCalculation (REST/SOAP)
  • Sklep pyta: „daj cenę dla klienta X, SKU Y, ilość Z"

SAP S/4HANA:

  • Condition records (najmocniejszy silnik na rynku)
  • Pricing procedure: złożona hierarchia warunków
  • API: OData lub BAPI

Subiekt GT:

  • Cenniki indywidualne, grupowe, rabaty
  • Sfera API
  • Mniej elastyczne niż XL czy SAP

enova365:

  • Cenniki indywidualne, grupowe, progi, promocje
  • REST API
  • Solidny model

Zasada: sklep nigdy nie liczy cen sam. Zawsze pyta ERP.

Integracje z ERP - pełen pillar.

Architektura - sklep + cache + ERP

[Klient w sklepie]
    |
    | wyświetlenie produktu
    v
[Sklep]
    |
    | "daj cenę dla K001, SKU ABC, qty 5"
    v
[Cache Redis]
    |
    +-- HIT (cache świeży, < 10 min): zwróć cenę
    |
    +-- MISS: zapytaj ERP
        |
        v
    [ERP]
        |
        | zwróć cenę
        v
    [Cache Redis] (zapis z TTL 600s)
        |
        v
    [Sklep] (zwróć cenę klientowi)

TTL: 5-15 minut. Krócej = ERP zasypywany. Dłużej = klient widzi nieaktualne ceny.

Hit ratio target: >85%. Poniżej - TTL za krótkie lub niewłaściwa strategia.

Cache batch - dla PLP

Na liście produktów (PLP) 50 produktów. 50 wywołań cache = 50 cache lookups. Lepiej: batch.

GET prices for customer K001, SKUs [ABC, DEF, GHI, ..., XYZ50]
  -> Redis MGET keys ["price:K001:ABC", "price:K001:DEF", ...]
  -> 50 keys, część hit, część miss
  -> Dla miss: 1 batch call do ERP "daj ceny dla K001 na te SKUs"
  -> ERP zwraca mapę
  -> Zapis brakujących do Redis
  -> Return mapa cen

ERP call 1× zamiast 50×. Redis call 1× (MGET) zamiast 50× (GET). Znacząca różnica na PLP.

Walidacja przy checkoutcie

Cena w koszyku może się zestarzeć. Klient dodaje produkt w poniedziałek, kupuje w środę - w międzyczasie cennik się zmienił.

Strategia:

1. Soft check w koszyku. Cena z cache 10 min. Klient widzi orientacyjne wartości.

2. Hard check przy „Złóż zamówienie". Sklep pyta ERP o aktualne ceny (sync, bez cache). Porównuje z cenami w koszyku.

3. Jeśli ceny się zmieniły:

  • Mała różnica (do 1%): akceptujemy bez zatwierdzania (drobne korekty)
  • Większa różnica: pokazujemy klientowi nowe ceny, klient potwierdza

4. Po akceptacji: Zamówienie wchodzi z aktualnymi cenami. ERP wystawia fakturę zgodną z tymi cenami.

Wydajność checkoutu B2B.

Cenniki w Magento Adobe Commerce - Shared Catalogs

Adobe Commerce ma natywny mechanizm - Shared Catalogs.

Jak działa:

  • Definiujesz „Katalog A" z 1200 produktami i ich cenami specjalnymi
  • Przypisujesz „Katalog A" do 30 firm (Companies)
  • Te 30 firm widzi tylko produkty z katalogu A + ich ceny

Plusy:

  • Wbudowane, nie trzeba dorabiać
  • UI w panelu administracyjnym
  • Action workflow do tworzenia

Minusy:

  • Sztywne (ceny statyczne, nie real-time z ERP)
  • Synchronizacja z ERP - własna implementacja
  • Trudne dla bardzo wielu wariantów cenowych (każdy unique = osobny katalog)

W praktyce dla polskiego B2B: Shared Catalogs jako fasada UI + integracja z ERP która synchronizuje ceny do Magento jako cenniki katalogowe. Hybryda.

Cenniki w Shopware Enterprise B2B Suite

Shopware B2B Suite ma „Customer Specific Prices" - bardziej elastyczne niż Magento Shared Catalogs.

  • CSV import cen per klient
  • API endpoint do bulk update
  • Wsparcie dla progów ilościowych

Też wymaga integracji z ERP - wbudowane modele zapełniasz danymi z zewnątrz.

Magento Open Source bez Shared Catalogs

Magento OS nie ma Shared Catalogs. Dorabiasz:

Opcja 1: Customer groups + tier pricing. Magento OS ma tier pricing per customer group. Klient w grupie X widzi cenę dla grupy X. Ograniczone (nie da się indywidualnych cen per SKU per kontrahent), ale dla podstawowych modeli wystarcza.

Opcja 2: Modułe komercyjne.

  • Aheadworks B2B Suite - Customer-specific Pricing, Shared Catalogs (kopia Adobe Commerce)
  • Amasty B2B - podobne
  • Webkul - alternatywa

Opcja 3: Custom. Własne implementacje. Bardziej elastyczne, droższe w utrzymaniu. Pisze się dla nietypowych modeli.

Najczęstsze problemy

1. Trzymanie cenników w sklepie i w ERP równolegle. Klient zmienia cennik w ERP, sklep dalej pokazuje stary. Albo sklep ma cennik nie istniejący w ERP. Faktury się rozjeżdżają.

Rozwiązanie: sklep nigdy nie jest source of truth. Tylko cache.

2. Brak cache → ERP umiera. 50 wywołań ERP / sec w peak'u = ERP timeout, sklep też pada.

Rozwiązanie: Redis cache z TTL 5-15 min + batch fetching.

3. Cache za długi → klient widzi stare ceny. TTL 1h → klient w godzinie widzi cenę wcześniejszą.

Rozwiązanie: TTL 5-15 min + webhook z ERP przy zmianie cennika (event-based invalidation).

4. Cenniki na PLP wolne. 50 wywołań ERP per render = LCP 10s.

Rozwiązanie: batch fetching + cache. Optymalizacja PLP.

5. Brak walidacji przy checkout. Cena z koszyka != cena w fakturze. Reklamacja, dramat.

Rozwiązanie: hard validation sync z ERP przy „Złóż zamówienie".

6. Kanibalizacja kanałów. Klient B2B widzi cennik kontraktowy w sklepie B2B. Allegro widzi cennik detaliczny. Ale jeśli klient B2B znajdzie na Allegro tańsze... problem.

Rozwiązanie: separacja kanałów. Marketplace'y z cenami detalicznymi, sklep B2B z kontraktowymi (i często wyższymi przy uwzględnieniu wartości dodanej).

7. Cenniki dla NIP-osób fizycznych prowadzących DG. „Klient" = firma czy osoba fizyczna? Jednoosobowa działalność z VAT to formalnie firma.

Rozwiązanie: identyfikacja po NIP + decyzja w ERP („JDG z NIP-em otrzymuje cennik klasy X").

FAQ

Czy mogę mieć cennik kontraktowy bez zalogowania? Nie. Cennik kontraktowy = klient zidentyfikowany. Klient musi się zalogować, sklep wie kim jest, pyta ERP o jego cenę.

Co jeśli klient widzi cennik niezalogowany, a inną cenę po zalogowaniu? Klasyczny pattern: niezalogowany widzi „cena katalogowa" (sugerowana), po zaloguj - kontraktowa. Klient ma świadomość, że loguje się dla swojej ceny.

Co jeśli klient nie ma jeszcze kontraktu (nowy klient B2B)? Standardowy cennik katalogowy. Negocjacje kontraktu offline, po podpisaniu w ERP - automatycznie zaczyna widzieć swoje ceny.

Czy mogę pokazywać marżę handlowcowi w panelu? Tak - w panelu „Sales Representative". Handlowiec widzi marżę dla zamówienia, może świadomie udzielać rabatów. Klient nie widzi.

Czy cennik kontraktowy działa z BNPL (Mondu)? Tak. Cennik kontraktowy daje cenę zamówienia. BNPL przejmuje fakturę, klient płaci BNPL, dostawca dostaje pieniądze od BNPL.

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.