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

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, 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 недели в зависимости от сложности правил и требований к визуализации.