Реалізація конфігуратора продукту на сайті

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, 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

Реалізація конфігуратора продукту на веб-сайті

Конфігуратор продукту — це інтерфейс, у якому покупець збирає фінальний варіант товару з набору параметрів: матеріал, розмір, колір, комплектація, гравіювання. На відміну від простого вибору варіанта (S/M/L), конфігуратор працює з комбінаторикою: кількість варіантів може досягати мільйонів, і зберігати кожний як окремий SKU неможливо. Підсумкова ціна та склад обчислюються динамічно.

Архітектурний вибір: SKU vs динамічна конфігурація

Табличні варіанти (SKU) підходять, коли комбінацій до кількох тисяч, і кожна має свій залишок на складі. Стандартний підхід для одягу.

Динамічна конфігурація потрібна, коли:

  • Кількість можливих комбінацій > 10 000
  • Кожен параметр незалежно впливає на ціну
  • Виробництво під замовлення (немає готового складу)
  • Потрібна візуалізація результату в реальному часі

Схема даних конфігуратора

CREATE TABLE configurator_products (
    id          BIGSERIAL PRIMARY KEY,
    product_id  BIGINT NOT NULL REFERENCES products(id),
    name        VARCHAR(255) NOT NULL,
    base_price  NUMERIC(12,2) NOT NULL DEFAULT 0,
    is_active   BOOLEAN NOT NULL DEFAULT true
);

CREATE TABLE configurator_option_groups (
    id              BIGSERIAL PRIMARY KEY,
    configurator_id BIGINT NOT NULL REFERENCES configurator_products(id),
    name            VARCHAR(255) NOT NULL,   -- "Матеріал", "Колір", "Гравіювання"
    type            VARCHAR(50) NOT NULL,
                    -- select | radio | checkbox | text | number | color
    is_required     BOOLEAN NOT NULL DEFAULT true,
    sort_order      INTEGER NOT NULL DEFAULT 0
);

CREATE TABLE configurator_options (
    id          BIGSERIAL PRIMARY KEY,
    group_id    BIGINT NOT NULL REFERENCES configurator_option_groups(id),
    label       VARCHAR(255) NOT NULL,
    value       VARCHAR(255) NOT NULL,
    price_modifier      NUMERIC(12,2) NOT NULL DEFAULT 0, -- абсолютна надбавка
    price_modifier_pct  NUMERIC(5,2) NOT NULL DEFAULT 0,  -- відсоткова надбавка
    modifier_type       VARCHAR(20) NOT NULL DEFAULT 'add', -- add | multiply | fixed
    sku_suffix  VARCHAR(50),          -- для формування SKU
    is_available BOOLEAN NOT NULL DEFAULT true,
    image_url   VARCHAR(500),         -- попередній перегляд опції
    sort_order  INTEGER NOT NULL DEFAULT 0
);

-- Правила залежності між опціями
CREATE TABLE configurator_rules (
    id              BIGSERIAL PRIMARY KEY,
    configurator_id BIGINT NOT NULL REFERENCES configurator_products(id),
    rule_type       VARCHAR(50) NOT NULL, -- requires | excludes | enables
    if_option_id    BIGINT NOT NULL REFERENCES configurator_options(id),
    then_option_id  BIGINT NOT NULL REFERENCES configurator_options(id)
);

Обчислення ціни

Ціна конфігурації обчислюється на сервері, а не на клієнті:

class ConfiguratorPriceCalculator
{
    public function calculate(
        ConfiguratorProduct $configurator,
        array $selectedOptions  // [group_id => option_id | value]
    ): PriceBreakdown
    {
        $base = $configurator->base_price;
        $breakdown = [['label' => 'Базова ціна', 'amount' => $base]];
        $total = $base;

        foreach ($selectedOptions as $groupId => $selection) {
            $group = $configurator->optionGroups->find($groupId);

            if ($group->type === 'text' || $group->type === 'number') {
                // Для вільного введення — фіксована надбавка за групу
                $modifier = $group->text_price_modifier ?? 0;
            } else {
                $option = ConfiguratorOption::findOrFail($selection);
                $modifier = $this->resolveModifier($option, $total);
            }

            if ($modifier != 0) {
                $breakdown[] = [
                    'label'  => $group->name . ($group->type !== 'text' ? ': ' . $option->label : ''),
                    'amount' => $modifier,
                ];
                $total += $modifier;
            }
        }

        return new PriceBreakdown($total, $breakdown);
    }

    private function resolveModifier(ConfiguratorOption $option, float $currentTotal): float
    {
        return match($option->modifier_type) {
            'add'      => $option->price_modifier,
            'multiply' => $currentTotal * ($option->price_modifier_pct / 100),
            'fixed'    => $option->price_modifier - $currentTotal,
        };
    }
}

Клієнт показує ціну попередньо (з JS-розрахунку), але при додаванні в кошик ціна завжди перераховується на сервері. Довіряти клієнтському розрахунку у фінансовому контексті неможливо.

Правила залежності

Деякі опції взаємно виключають одна одну або вимагають вибору іншої опції. Правила перевіряються і на клієнті (UX), і на сервері (валідація):

class ConfiguratorRuleEngine
{
    public function validate(ConfiguratorProduct $configurator, array $selected): ValidationResult
    {
        $errors = [];

        foreach ($configurator->rules as $rule) {
            $ifSelected = in_array($rule->if_option_id, $selected);
            $thenSelected = in_array($rule->then_option_id, $selected);

            match($rule->rule_type) {
                'requires' => $ifSelected && !$thenSelected
                    ? $errors[] = "Опція вимагає вибору: {$rule->thenOption->label}"
                    : null,
                'excludes' => $ifSelected && $thenSelected
                    ? $errors[] = "Несумісні опції: {$rule->thenOption->label}"
                    : null,
                'enables'  => !$ifSelected
                    ? $this->disableOption($rule->then_option_id)
                    : null,
            };
        }

        return new ValidationResult(empty($errors), $errors);
    }
}

Формування SKU конфігурації

Для виробництва важливо мати детермінований код конфігурації:

class ConfigurationSkuBuilder
{
    public function build(ConfiguratorProduct $configurator, array $selected): string
    {
        $parts = [$configurator->product->sku];

        $sortedOptions = collect($selected)
            ->sortKeys()
            ->map(fn($optionId, $groupId) =>
                ConfiguratorOption::find($optionId)?->sku_suffix ?? $optionId
            );

        return implode('-', array_merge($parts, $sortedOptions->all()));
        // Приклад: CHAIR-BLK-LEATH-ARMB-CUST
    }
}

API для фронтенда

Конфігуратор працює через AJAX. Мінімальний набір кінцевих точок:

GET  /api/configurators/{id}           — повна схема конфігуратора
POST /api/configurators/{id}/price     — перерахунок ціни за вибором
POST /api/configurators/{id}/validate  — валідація набору опцій
POST /api/cart/add-configuration       — додавання конфігурації в кошик

Запит перерахунку ціни:

POST /api/configurators/5/price
{
  "selected": {
    "1": 12,
    "2": 7,
    "3": "Іван Іванов"
  }
}

Відповідь:

{
  "total": 4850.00,
  "breakdown": [
    { "label": "Базова ціна", "amount": 3500.00 },
    { "label": "Матеріал: Натуральна шкіра", "amount": 1200.00 },
    { "label": "Колір: Чорний", "amount": 0 },
    { "label": "Гравіювання", "amount": 150.00 }
  ]
}

Збереження конфігурації в кошику

Конфігурація зберігається як JSON у позиції кошика:

ALTER TABLE cart_items ADD COLUMN configuration JSONB;
ALTER TABLE order_items ADD COLUMN configuration JSONB;
ALTER TABLE order_items ADD COLUMN configuration_sku VARCHAR(255);
{
  "configurator_id": 5,
  "groups": {
    "1": { "option_id": 12, "label": "Натуральна шкіра" },
    "2": { "option_id": 7, "label": "Чорний" },
    "3": { "type": "text", "value": "Іван Іванов" }
  },
  "sku": "CHAIR-LEATH-BLK-CUST",
  "price_at_add": 4850.00
}

При додаванні конфігурації в кошик ціна перераховується на сервері та фіксується. Зміна прайсу не впливає на вже додані конфігурації.

Адміністративний інтерфейс

Менеджер повинен мати можливість:

  • Створювати та редагувати конфігуратори без програміста
  • Керувати порядком груп та опцій
  • Встановлювати правила залежності через UI (не SQL)
  • Переглядати конфігуратор перед публікацією

Терміни реалізації

  • Базова схема + API перерахунку ціни + додавання в кошик: 5–7 днів
  • Правила залежності (requires/excludes): 2–3 дні
  • Адміністративний інтерфейс для управління конфігуратором: 3–4 дні
  • Візуальний попередній перегляд (зміна зображення при виборі опції): 2–3 дні
  • Інтеграція з системою виробничих завдань: +3–5 днів

Типовий проект: 2–4 тижні залежно від складності правил та вимог до візуалізації.