Кейс: площадка для производителей вина – как мы сделали интернет-магазин с поставщиками и корзиной

В Грузии сотни маленьких виноделен. У каждого своё уникальное саперави, киндзмараули, хванчкара. Но как ресторану в Москве или магазину в Санкт-Петербурге собрать корзину из вин разных производителей и оформить один заказ? Раньше никак. Приходилось договариваться с каждым поставщиком отдельно, ждать отдельные счета, оплачивать переводы, а потом разбираться с доставкой. Кошмар.

К нам пришёл предприниматель, который решил создать единую торговую площадку для вин Грузии. Модель: поставщики (винодельни) сами загружают свою продукцию, а покупатели (рестораны, магазины, частные клиенты) собирают корзину из вин разных поставщиков и оформляют единый заказ. Задача: сделать кабинет поставщика, кабинет покупателя, единую корзину и интеграцию с доставкой. Сделали за 2 месяца. Расскажу как.

Как работала торговля вином до площадки

Представьте: вы управляете рестораном. Вам нужно закупить вино. Вы звоните первому поставщику: «Дайте прайс». Вам присылают Excel. Второму — то же самое. Третьему. Сравниваете цены вручную, заказываете каждому отдельно, получаете 5 счетов, 5 оплат, 5 доставок. Умножайте на 5 разных грузинских виноделен. Это десятки часов в месяц на закупки.

Или вы — винодельня. Как продать своё вино в России? Ехать на выставку, договариваться с дистрибьюторами, ждать оплаты по полгода, отдавать 40% маржи посредникам.

Площадка решает обе проблемы: поставщик загружает вино один раз, покупатель видит всех в одном каталоге, делает заказ в корзине, платит одной суммой. А площадка перечисляет деньги поставщикам (за вычетом комиссии). Идея отличная, но технически — сложная.

Архитектура решения на Falcon Space

Мы взяли за основу наше типовое решение Falcon Marketplace (маркетплейс товаров), но серьёзно его доработали. Почему не взяли готовый OpenCart или Woocommerce? Потому что там нет нормального разделения «кабинет поставщика», нет аукциона, нет сложной логики комиссий. А дорабатывать их — это костыли.

Вот ключевые объекты системы:

Проект вела наша команда (аналитик, SQL-разработчик). Бюджет — около 800 тыс. рублей (лицензия + доработки + локализация). Первая версия запущена через 2 месяца, полная (с локализацией на английский и грузинский) — через 3,5 месяца.

Личный кабинет поставщика: управление винами

Поставщик (винодельня) после регистрации и модерации получает доступ к кабинету. Что там есть:

Всё это работает через SQL-процедуры. Например, процедура получения списка товаров поставщика выглядит так:

CREATE PROCEDURE [app].[supplier_products]
    @supplier_id int
AS
BEGIN
    SELECT product_id, name, price, stock, is_active
    FROM products
    WHERE supplier_id = @supplier_id
    ORDER BY name;
END

Личный кабинет покупателя: каталог и корзина

Покупатель (ресторан или магазин) регистрируется, после регистрации получает доступ к каталогу.

Ключевой момент — корзина с несколькими поставщиками. Технически мы реализовали это через временную таблицу cart_items с полями: buyer_id, product_id, quantity, supplier_id. При оформлении заказа срабатывает процедура, которая группирует товары по supplier_id и создаёт субзаказы.

Единый заказ и субзаказы: техническая логика

Таблица заказов (orders) хранит общую информацию: buyer_id, total_amount, status, created_at. Таблица субзаказов (suborders) — supplier_id, order_id, sub_total, status (pending, confirmed, shipped, delivered, cancelled). Также есть таблица order_items, которая связывает субзаказы с товарами.

Процедура оформления заказа (упрощённо):

CREATE PROCEDURE [app].[create_order_from_cart]
    @buyer_id int
AS
BEGIN
    -- Создаём главный заказ
    INSERT INTO orders (buyer_id, total_amount, status, created_at)
    SELECT @buyer_id, SUM(p.price * ci.quantity), 'pending', GETDATE()
    FROM cart_items ci
    JOIN products p ON ci.product_id = p.product_id
    WHERE ci.buyer_id = @buyer_id;
    
    DECLARE @order_id int = SCOPE_IDENTITY();
    
    -- Создаём субзаказы по каждому поставщику
    INSERT INTO suborders (order_id, supplier_id, sub_total, status)
    SELECT @order_id, ci.supplier_id, SUM(p.price * ci.quantity), 'pending'
    FROM cart_items ci
    JOIN products p ON ci.product_id = p.product_id
    WHERE ci.buyer_id = @buyer_id
    GROUP BY ci.supplier_id;
    
    -- Создаём позиции субзаказов
    INSERT INTO order_items (suborder_id, product_id, quantity, price)
    SELECT s.suborder_id, ci.product_id, ci.quantity, p.price
    FROM cart_items ci
    JOIN products p ON ci.product_id = p.product_id
    JOIN suborders s ON s.supplier_id = ci.supplier_id AND s.order_id = @order_id
    WHERE ci.buyer_id = @buyer_id;
    
    -- Очищаем корзину
    DELETE FROM cart_items WHERE buyer_id = @buyer_id;
    
    SELECT @order_id AS order_id;
END

После этого каждый поставщик видит свой субзаказ в своём кабинете. Если один поставщик отклонил заказ, главный заказ не отменяется полностью — покупатель может либо удалить товары этого поставщика, либо найти замену. Мы добавили механизм «частичная отмена».

Интеграция с доставкой и учёт остатков

Когда поставщик подтверждает субзаказ, он обязан указать срок отгрузки и трек-номер (если отправляет ТК). Мы интегрировали API СДЭК, чтобы покупатель мог отслеживать отправление. Также при подтверждении субзаказа резервируются товары (уменьшается поле reserved, а не stock), чтобы не случилось двойной продажи.

Остатки обновляются либо вручную (поставщик вносит изменения), либо через Excel-импорт (для массового обновления прайсов). Периодически запускается процедура, которая уведомляет поставщика, если по какому-то товару остатки упали ниже порогового значения.

Результаты через 3 месяца после запуска

Из отзыва заказчика на Startpack: «Положительным моментом Falcon Space является гибкая настройка системы, надежность, цена и невысокая стоимость владения по сравнению с конкурентами, удобная административная панель, возможность создания личных кабинетов и витрин, интеграция с внешними системами. Отдельно хотел бы отметить команду разработчиков, всегда на связи, помогают во многих вопросах и очень ответственно подходят к своей работе».

Что мы сделали ещё: локализация и SEO

Площадка работает на трёх языках: русский, английский, грузинский. Интерфейс переведён, данные каталога (названия вин, описания) могут быть на нескольких языках. Переключение языков — через кнопку. Это потребовало доработок, но дало возможность привлечь иностранных покупателей.

SEO: ЧПУ-адреса для каждого вина (например, /wine/saperavi-2018), мета-теги, карта сайта. Сейчас около 40% трафика — органический поиск.

Планы на развитие

Этот проект — яркий пример того, как Falcon Space позволяет быстро собрать сложный B2B-маркетплейс с разделением заказов по поставщикам. Если у вас похожая задача — напишите, адаптируем решение под ваш ассортимент и рынок.

P.S. Отдельно хочу отметить, что большинство поставщиков (виноделен) — люди пожилые, не слишком технически подкованные. Но наш кабинет оказался настолько простым, что они освоили его за пару дней. Это заслуга продуманного интерфейса и подсказок.

Страница-источник на сайте falconspace.ru