Розробка сервісу купонів та знижок

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.
Розробка та обслуговування будь-яких видів сайтів:
Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка сервісу купонів та знижок
Середня
~1-2 тижні
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Розробка сервісу купонів та скидок

Купони та скидки — це не просто поле «введіть промокод» на сторінці чекауту. Це система правил, яка управляє ціноутворенням: кому, коли, на що та у якому розмірі надавати скидку. Погано спроектована система перетворюється в дири для злоупотреб та хаос в аналітиці. Добре спроектована — в інструмент точкового маркетингу.

Типологія скидок

Перш ніж писати код, потрібно зафіксувати модель:

Купони (промокоди) — користувач вводить код вручну або посилання застосовує його автоматично. Код унікален або багаторазовий, привязаний до правила скидки.

Автоматичні скидки — застосовуються без кода при виконанні умов: «всі товари категорії X зі скидкою 15% у п'ятницю», «скидка 500 руб. від замовлення на 3000».

Накопичні програми — скидка залежить від історії покупок клієнта (кешбэк, бали, рівні лояльності).

Скидки по групах — оптові ціни для B2B-клієнтів, скидки для сотрудників, партнерські умови.

Модель даних

discount_rules (
  id, name, type,              -- coupon | automatic | loyalty
  discount_type,               -- percentage | fixed_amount | free_shipping | bxgy
  discount_value NUMERIC,
  min_order_amount NUMERIC,
  min_qty INT,
  max_uses INT,                -- NULL = без обмежень
  max_uses_per_user INT,
  starts_at TIMESTAMPTZ,
  ends_at TIMESTAMPTZ,
  is_active BOOLEAN,
  stackable BOOLEAN            -- можна ли комбінувати з іншими
)

discount_conditions (
  id, rule_id,
  condition_type,              -- product | category | tag | user_group | first_order
  condition_operator,          -- in | not_in | gte | lte
  condition_value JSONB
)

coupons (
  id, rule_id, code VARCHAR(32),
  usage_count INT DEFAULT 0,
  is_single_use BOOLEAN
)

coupon_uses (
  id, coupon_id, order_id, user_id, used_at,
  discount_amount NUMERIC      -- записана у момент застосування
)

Розділення discount_rules та coupons дозволяє одному правилу мати много кодів (bulk generation для email-кампаній) або один код з різними обмеженнями.

Генерація купонів пачками

Для email-розсилок потрібні унікальні коди — по одному на кожного одержувача:

function generateCouponBatch(int $ruleId, int $count): array {
    $codes = [];
    while (count($codes) < $count) {
        $code = strtoupper(Str::random(8)); // A-Z0-9, 8 символів
        if (!Coupon::where('code', $code)->exists()) {
            $codes[] = ['rule_id' => $ruleId, 'code' => $code, 'is_single_use' => true];
        }
    }
    Coupon::insert($codes);
    return array_column($codes, 'code');
}

Для великих розсилок (100 000+ кодів) генеруйте заздалегідь з перевіркою унікальності через індекс, а не SELECT EXISTS в циклі.

Валідація та застосування купона

При вводі кода в чекауті перевірте:

  1. Код існує та активен
  2. Дата початку/закінчення
  3. Ліміт використань не перевищен (max_uses)
  4. Користувач не вичерпав ліміт (max_uses_per_user)
  5. Сума корзини >= min_order_amount
  6. Товари в корзині відповідають умовам (discount_conditions)

Перевірка повинна бути атомарною при застосуванні — race condition можливий, якщо два запросити одночасно застосовують останній доступний купон. Рішення:

UPDATE coupons
SET usage_count = usage_count + 1
WHERE code = :code
  AND usage_count < max_uses  -- для single-use: usage_count < 1
RETURNING id;
-- якщо 0 рядків — купон уже використаний

UPDATE ... RETURNING всередині транзакції виключає race condition.

Расчет скидки для корзини

Скидка рахується на сервері, ніколи не довіряємо клієнтскому расчету. Алгоритм:

1. Отримати застосовані правила (автоматичні + купон)
2. Для кожного правила визначити eligible позиції (з урахуванням умов)
3. Застосувати скидки у порядку пріоритету
4. Якщо stackable=false — застосуємо тільки найбільшу скидку
5. Повернути breakdown: яка скидка застосована до кожної позиції

Breakdown важливий для відображення користувачу («–500 руб. по купону SAVE500») та для аналітики.

BxGy (Buy X Get Y) — «купи 3, отримай 4-й у подарунок». Реалізується окремим типом правила: при qty >= X додаємо в корзину товар Y з нульовою ціною або знижуємо ціну N-ої одиниці.

Автоматичні скидки та пріоритети

Кілька автоматичних правил можуть спрацьовувати одночасно. Потрібна політика:

  • Перше совпавшее — застосовується правило з найвищим пріоритетом
  • Найкраща скидка — застосовується то правило, яке дає найбільшу вигоду
  • Всі сумісні — застосовуються всі правила з stackable=true

Політика прописується на рівні магазина та може відрізнятися для різних типів правил.

Аналітика та звітність

Без аналітики маркетинг летить вслід за очима. Базовий набір метрик:

Метрика SQL
Використань купона SELECT COUNT(*) FROM coupon_uses WHERE coupon_id = ?
Середній розмір скидки SELECT AVG(discount_amount) FROM coupon_uses WHERE ...
Revenue з урахуванням скидки SUM(order.total) vs SUM(order.total + discount_amount)
Конверсія з купоном vs без Порівняння CR для сесій з applied_coupon та без

Для маркетолога — дашборд з фільтрацією по періоду, типу скидки, каналу (utm_source).

Попередження злоупотреб

  • Один купон на замовлення — стандартне обмеження, але якщо дозволен стек, потрібна явна конфігурація
  • Верифікація email перед застосуванням скидки «для нових клієнтів» — інакше створять 100 аккаунтів
  • Rate limiting на endpoint застосування купона — захист від брутфорсу кодів
  • Алерти при різкому зростанні використань одного купона — можлива утечка

Кабінет маркетолога

Інтерфейс для управління акціями повинен дозволяти:

  • Створювати правила скидок з візуальним конструктором умов
  • Генерувати та виводити CSV пачки купонів
  • Переглядати статистику по кожній акції в реальному часі
  • Деактивувати акцію одним кліком (важливо при помилках в настройці)

Терміни

  • Базова система купонів (промокод, відсоток/сума, дата закінчення): 1–2 тижні
  • Повноцінна система (умови по категоріях/товарах, автоматичні скидки, BxGy, аналітика, кабінет маркетолога): 3–5 тижнів
  • Програма лояльності з балами та рівнями додає 3–4 тижні