Kupony (pule kodów)
Kupon w Zevio to pula kodów (cpn_…) należąca do organizacji. Każdy kod (code_…) ma własne limity użyć. Tworzenie: Promocje → Kupony → Nowa pula (/dashboard/promotions/coupons/create). Szczegóły: /dashboard/promotions/coupons/[couponId]. Po utworzeniu pulę przypinasz do oferty w Oferta → Promocje. Rabat jest grantowany po SUCCESS.
Nazwa puli
Wymagana, 1-120 znaków. Widoczna tylko w panelu i przy multipicku na ofercie - klient widzi sam kod, nie nazwę puli.
Typ rabatu
- Procent (`percent`) - wartość całkowita 0-100. W podglądzie checkoutu staje się
generalDiscounti zastępuje zniżkę ogólną oferty; trial oferty zwykle zostaje. - Stała cena brutto (`fixed_gross`) - kwota ≥ 0 z dokładnością do 0,01. Mapuje się na
trialAccess-podobne zachowanie w merge i przy aktywnym grancie wypiera bazowe promocje oferty na cyklach.
Typ trwania rabatu
- Jednorazowo (`once`) - tylko płatność, na której użyto kodu; grant
consumedna tympay_…. - Liczba płatności (`repeating_payment_count`) - N cykli (1-999); po starcie
paymentsAppliedrośnie z każdym SUCCESS. - Powtarzający się interwał (`repeating_interval`) - od daty startu subskrypcji przez token
1D…1Ylub własny 1-999 + D/W/M/Y. Domyślnie w UI:repeating_interval. - Bezterminowo (`forever`) - do dezaktywacji / zastąpienia wpisu.
Okres ważności puli
Opcjonalne validFrom / expiresAt (datetime). Poza oknem realizacja kończy się errors.promotion.code_expired, nawet jeśli kod ma wolne użycia.
Sposób dodania kodów
- Wygeneruj automatycznie -
autoGenerateCount1-500 (domyślnie 10). Kody: 8 znaków uppercase. - Wgraj własne - lista 1-500 kodów; każdy 1-64 znaków; separatory: nowa linia, przecinek, średnik. Kody trim + uppercase. Kolizja unikalności w organizacji kończy się błędem zapisu.
Limity użyć
- Maks. użyć na kod - domyślnie 1; min. 1 gdy przełącznik nielimitowanych jest wyłączony.
- Nielimitowane użycia kodu - zapisuje sentinel
999_999_999(UNLIMITED_CODE_REDEMPTIONS). - Maks. użyć całej puli (`maxRedemptions`) - dostępne w API (nie w podstawowym UI create); po wyczerpaniu
errors.promotion.pool_exhausted.
Włączenie na ofercie
W Oferta → Promocje: Akceptuj kody kuponów + wybór co najmniej jednej puli ACTIVE. REST: PUT /promotions/coupons/{qrId} z { enabled, couponId: string[] } (tablica wymagana gdy enabled). Pule wewnętrzne powiązane z programem poleceń (coupon.referralId) nie są wybieralne jako zwykłe kupony.
Lista, szczegóły, kody
- Lista: status, liczba kodów, użycia, daty; filtr zarchiwizowanych.
- Szczegóły: podsumowanie limitów per kod (
none|unlimited|uniform|range|mixed), dodawanie kolejnych kodów, usuwanie kodów bez użyć i bezreferralLinkId. - Eksport kodów z panelu.
- Usuwanie kodu z redemptions lub powiązanego z linkiem polecającym jest pomijane / blokowane (
code_not_deletable).
Archiwizacja, przywracanie, usuwanie
- Archiwizacja → ARCHIVED +
archivedAt; w tym stanie nie dodasz/usuniesz kodów ani nie zaktualizujesz puli jak aktywnej. - Przywracanie (
restore) → ACTIVE (tylko kupony; programy poleceń nie mają restore). - Usunięcie puli tylko gdy
redemptionCount === 0; inaczejerrors.promotion.coupon_in_use. - INACTIVE blokuje nowe realizacje bez archiwizacji.
Przebieg realizacji
- Walidacja publiczna:
POST /public/promotions/validateoraz pricingPOST /public/promotions/payment-pricing(rate limit). - Po SUCCESS: PromotionRedemption + wpis na subskrypcji; webhook
promotion.redeemedzside: "coupon". - Idempotency grantu spina płatność z redeem (
redeem_{paymentId}/ równoważny klucz).
Klucze błędów
errors.promotion.code_not_found|code_expired|code_exhausted|pool_exhaustederrors.promotion.pool_inactive|pool_archived|coupon_in_use|code_not_deletableerrors.promotion.code_redemption_disabled|qr_not_eligible
Identyfikatory
- Pula:
cpn_+ 12. - Kod:
code_+ 12 (lub własny string uppercase jako wartość kodu widoczna dla klienta). - Redemption:
pred_….