Promocje – logika i wyliczanie cen

Jak AMPER ocenia promocje: pozycje, warunki i grupy, pakiety, nagrody, promocje koszykowe oraz co z tego stosuje zamówienie złożone przez API.

Ostatnia aktualizacja: 26 października 2026

Artykuł opisuje, jak AMPER sprawdza, czy koszyk spełnia warunki promocji, i jakie nagrody wtedy przyznaje – tak samo w sklepie B2B, w aplikacji mobilnej i w asystencie AI. Pola, o których mowa, opisuje artykuł Promocje – struktura danych.

Co z tego potrzebujesz

Większości integracji wystarczy prezentacja promocji: oznaczenie produktów w promocji, cena stała i próg, od którego obowiązuje, gratis do zdobycia, próg rabatu koszykowego. Do tego wystarczy pierwsza część artykułu i przykłady.

Pełne odtworzenie wyliczeń (pakiety, łączenie nagród, promocje koszykowe) jest potrzebne tylko wtedy, gdy system zewnętrzny sam liczy ceny w koszyku. Przed tym sprawdź, co AMPER stosuje w zamówieniu złożonym przez API – patrz Zamówienie złożone przez API.

Dane do wyliczeń

Dane Skąd
produkty i ilości w koszyku (w jednostkach podstawowych) system zewnętrzny
cena klienta default_price z listy produktów
cena bazowa (dla promocji z start_using_default_price) list_price z listy produktów
przelicznik jednostki zbiorczej cumulative_converter z listy produktów
drzewo kategorii i przypisania produktów Kategorie produktów
promocje Promocje – struktura danych

Promocje zwykłe – kolejność oceny

Drzewo rules ocenia się od dołu: najpierw pozycje warunków, potem warunki, na końcu grupy. Nagrody grupy obowiązują, gdy grupa jest spełniona.

1. Pozycja warunku

Które produkty się liczą. Pozycja z product_id liczy ten jeden produkt. Pozycja z category_id liczy łącznie wszystkie produkty z koszyka przypisane do tej kategorii albo do dowolnej kategorii pod nią.

Ilość to suma ilości w jednostkach podstawowych. Gdy promocja ma calculate_using_cumulative_units = true, ilość jest dzielona przez przelicznik jednostki: wskazanej w unit_of_measure albo – gdy jej brak – jednostki zbiorczej produktu (cumulative_converter). Przykład: 48 szt. przy kartonie po 24 szt. to 2 kartony.

Wartość to suma ilość × cena netto. Cena to:

  • cena klienta (default_price) – domyślnie,
  • cena bazowa (list_price) – gdy promocja ma start_using_default_price = true,
  • cena stała z nagrody tej grupy dla danego produktu – gdy promocja ma use_promotion_price_for_threshold = true.

Kiedy pozycja jest spełniona – według value_type:

Kod Pozycja spełniona, gdy Ile razy spełniona (mnożnik)
1 wartość ≥ value ⌊wartość / value⌋
2 ilość ≥ value ⌊ilość / value⌋
4 ilość > 0 i jest wielokrotnością value ⌊ilość / value⌋
6 wartość jest wielokrotnością value ⌊wartość / value⌋
7 w koszyku jest co najmniej value różnych produktów z warunku liczba pełnych zestawów po value produktów
  • value_max (typy 1 i 2) to górna granica liczona na jeden pakiet: pozycja jest spełniona, gdy value × n ≤ ilość (wartość) ≤ value_max × n, gdzie n to mnożnik. 0 – bez górnej granicy.
  • Przy typie 7 produkt liczy się, gdy jego ilość jest większa od zera i – jeśli ustawiono quantity_min / quantity_max – mieści się w tym zakresie.
  • Pozycja z value = 0 (i bez value_max) jest zawsze spełniona.

2. Warunek

Warunek jest spełniony, gdy spełnione są wszystkie jego pozycje. Gdy warunek ma keep_bundle_same = true (pakiet), wszystkie pozycje muszą mieć ten sam mnożnik – np. pakiet „piwo 2 szt. + przekąska 1 szt.” spełnia koszyk 4 piwa + 2 przekąski (2 pakiety), ale nie 4 piwa + 1 przekąska.

Mnożnik warunku to najmniejszy mnożnik jego pozycji.

3. Grupa

  • relation = AND – grupa jest spełniona, gdy spełnione są wszystkie jej warunki i wszystkie grupy podrzędne. Warunki-pakiety (keep_bundle_same) w grupie bez progu łącznego muszą mieć ten sam mnożnik.
  • relation = OR – wystarczy jeden spełniony warunek albo jedna spełniona grupa podrzędna.
  • threshold większy od zera – dodatkowo suma ilości ze wszystkich pozycji warunków grupy musi go osiągnąć (produkt występujący w dwóch warunkach grupy liczy się dwa razy).

Liczba pakietów grupy mówi, ile razy grupa została spełniona – od niej zależy liczba gratisów:

  • grupa z warunkami-pakietami: największy mnożnik spośród tych warunków,
  • inna grupa z warunkami: największy mnożnik warunku, przy czym każdy jest ograniczony limitem multiply_reward grupy (albo – gdy grupa go nie ma – multiply_reward promocji); 0 oznacza brak limitu,
  • grupa bez własnych warunków: największa liczba pakietów spośród grup podrzędnych.

Gdy promocja ma replace_gratifications = true, a grupa jest spełniona, grupy pod nią nie przyznają swoich nagród – zastępuje je nagroda grupy wyższej.

4. Nagrody spełnionej grupy

Nagroda Działanie
3 cena stała produkt product_id z warunków tej grupy kosztuje price netto za jednostkę podstawową
1 upust procentowy produkty z warunków tej grupy i grup pod nią tanieją o reward_value % (cena zaokrąglona do grosza, nie mniej niż 0,01)
2 upust kwotowy od wartości każdej linii z produktem z warunków tej grupy odejmowane jest reward_value netto, rozłożone na sztuki; cena nie spada poniżej zera
4 gratis produkt product_id w ilości quantity × liczba pakietów, po cenie price
8 jeden z wielu klient wybiera jeden z produktów nagród grupy; ilość quantity × liczba pakietów
9 wiele z wielu klient wybiera kilka produktów nagród grupy i rozdziela między nie łącznie quantity × liczba pakietów sztuk
  • Gratis trafia do zamówienia jako osobna linia po cenie price (np. 0,01 zł).
  • Gdy produkt należy do kilku spełnionych grup jednej promocji, nagrody się nakładają: cena stała zastępuje cenę, upusty są stosowane kolejno.
  • multiply_reward promocji ogranicza też liczbę przyznanych gratisów.
  • can_be_used_only_once = true – klient wykorzysta promocję w jednym zamówieniu.
  • has_budget = true – promocja korzysta z budżetu promocyjnego. Po jego wyczerpaniu nagrody nie są przyznawane; API nie podaje, ile budżetu zostało.

5. Kilka promocji na ten sam produkt

Jedna linia koszyka należy do jednej promocji. Gdy produkt jest w kilku promocjach, które koszyk spełnia, korzystniejsza dla klienta jest ta z niższą ceną. Przy wycenie przez API AMPER sam wybiera dla linii promocję z najniższą ceną stałą.

Promocje koszykowe

Promocje koszykowe ocenia się po zwykłych, na cały koszyk.

Pomiar koszyka.

  • threshold_type = 1 (wartość): suma netto linii koszyka według cen klienta – obniżki z promocji zwykłych nie zmniejszają tej sumy; gratisy liczą się po swojej cenie. Produkty wyłączone z promocji też się liczą.
  • threshold_type = 2 (ilość): suma ilości linii (bez gratisów) w jednostce threshold_unit – null to jednostki podstawowe; produkt, który nie ma tej jednostki, się nie liczy.
  • Gdy counted_package_ids jest listą, liczą się tylko linie dodane w ramach tych promocji (bez gratisów, wartość według cen klienta).

Która nagroda. Kwalifikują się nagrody, których threshold jest nie większy niż zmierzona wartość. Koszyk dostaje jedną nagrodę koszykową spośród wszystkich promocji koszykowych klienta:

  1. z promocji o wyższym priority,
  2. przy równym priorytecie – z promocji nowszej (wyższe id),
  3. w ramach jednej promocji – nagrodę o wyższym progu.

Forma płatności. Nagroda z payment_variant działa tylko przy tej formie płatności. Gdy klient wybrał formę płatności, a któraś z kwalifikujących się nagród jest do niej przypisana, obowiązuje ta nagroda. Gdy najlepsza nagroda wymaga innej formy płatności niż wybrana, rabat koszykowy nie jest naliczany.

Działanie nagrody.

Nagroda Działanie
5 upust procentowy każda linia tanieje o reward_value % – linia z promocji od swojej ceny promocyjnej; nie dotyczy produktów i kategorii z excluded_product_ids / excluded_category_ids
6 upust kwotowy osobna linia rabatu na cały koszyk: −reward_value netto
7 gratis produkt product_id w ilości quantity po cenie price

Przykłady

Przykłady korzystają z promocji pokazanych w artykule Promocje – struktura danych.

Cena stała od 10 sztuk (grupa 7002). Pozycja: produkt 101, value_type = 2, value = 10; nagroda: cena stała 5.00.

  • 12 szt. – 12 ≥ 10, warunek spełniony: piwo kosztuje 5,00 zł netto za sztukę.
  • 8 szt. – warunek niespełniony: obowiązuje cena klienta default_price.

W sklepie wystarczy pokazać: „od 10 szt. – 5,00 zł”.

Gratis za każde 2 kartony (grupa 7003). Promocja ma calculate_using_cumulative_units = true; pozycja: wino 205, value_type = 4, value = 2, jednostka karton (6 szt.); nagroda: gratis 990 × 1 po 0,01 zł.

  • 24 szt. = 4 kartony – 4 to wielokrotność 2, warunek spełniony; pakiety: ⌊4 / 2⌋ = 2 → 2 kieliszki gratis.
  • 30 szt. = 5 kartonów – 5 nie jest wielokrotnością 2, warunek niespełniony. Przy typie 4 podpowiedz klientowi właściwe ilości: 2, 4, 6… kartonów.

Grupa główna 7001 ma relation = OR, więc każda z dwóch reguł działa niezależnie.

Rabat koszykowy (promocja 22960702): 3% od 1000 zł netto albo kieliszek gratis od 2500 zł netto.

  • Koszyk za 1 200 zł – kwalifikuje się tylko upust 3%; nie obejmuje produktu 317 ani produktów z kategorii 48 (i kategorii pod nią).
  • Koszyk za 2 600 zł – kwalifikują się obie nagrody, ale koszyk dostaje jedną: o wyższym progu, czyli kieliszek gratis, a nie upust 3%.

Zamówienie złożone przez API

Endpoint create-order wylicza ceny linii po stronie AMPER:

  • stosuje ceny stałe (nagroda 3) – dla każdej linii wybiera promocję z najniższą ceną stałą, której warunki spełnia całe zamówienie,
  • nie dodaje gratisów, upustów procentowych i kwotowych ani nagród koszykowych.

W trybie playground dostaniesz te ceny bez tworzenia zamówienia – to pewne źródło ceny linii w zamówieniu z API. Jeśli integracja ma przekazywać gratisy albo rabaty, uzgodnij sposób z działem IT firmy, z którą się integrujesz (np. weryfikację zamówienia w AMPER przed wysłaniem do ERP).

Potrzebujesz pomocy? Napisz na support@ampliapps.com albo zadzwoń: +48 85 6000 263.