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 mastart_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(typy1i2) to górna granica liczona na jeden pakiet: pozycja jest spełniona, gdyvalue× n ≤ ilość (wartość) ≤value_max× n, gdzie n to mnożnik.0– bez górnej granicy.- Przy typie
7produkt liczy się, gdy jego ilość jest większa od zera i – jeśli ustawionoquantity_min/quantity_max– mieści się w tym zakresie. - Pozycja z
value=0(i bezvalue_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.thresholdwię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_rewardgrupy (albo – gdy grupa go nie ma –multiply_rewardpromocji);0oznacza 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_rewardpromocji 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 jednostcethreshold_unit–nullto jednostki podstawowe; produkt, który nie ma tej jednostki, się nie liczy.- Gdy
counted_package_idsjest 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:
- z promocji o wyższym
priority, - przy równym priorytecie – z promocji nowszej (wyższe
id), - 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
4podpowiedz 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
317ani produktów z kategorii48(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.