В Грузии сотни маленьких виноделен. У каждого своё уникальное саперави, киндзмараули, хванчкара. Но как ресторану в Москве или магазину в Санкт-Петербурге собрать корзину из вин разных производителей и оформить один заказ? Раньше никак. Приходилось договариваться с каждым поставщиком отдельно, ждать отдельные счета, оплачивать переводы, а потом разбираться с доставкой. Кошмар.
К нам пришёл предприниматель, который решил создать единую торговую площадку для вин Грузии. Модель: поставщики (винодельни) сами загружают свою продукцию, а покупатели (рестораны, магазины, частные клиенты) собирают корзину из вин разных поставщиков и оформляют единый заказ. Задача: сделать кабинет поставщика, кабинет покупателя, единую корзину и интеграцию с доставкой. Сделали за 2 месяца. Расскажу как.
Представьте: вы управляете рестораном. Вам нужно закупить вино. Вы звоните первому поставщику: «Дайте прайс». Вам присылают Excel. Второму — то же самое. Третьему. Сравниваете цены вручную, заказываете каждому отдельно, получаете 5 счетов, 5 оплат, 5 доставок. Умножайте на 5 разных грузинских виноделен. Это десятки часов в месяц на закупки.
Или вы — винодельня. Как продать своё вино в России? Ехать на выставку, договариваться с дистрибьюторами, ждать оплаты по полгода, отдавать 40% маржи посредникам.
Площадка решает обе проблемы: поставщик загружает вино один раз, покупатель видит всех в одном каталоге, делает заказ в корзине, платит одной суммой. А площадка перечисляет деньги поставщикам (за вычетом комиссии). Идея отличная, но технически — сложная.
Мы взяли за основу наше типовое решение 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-импорт (для массового обновления прайсов). Периодически запускается процедура, которая уведомляет поставщика, если по какому-то товару остатки упали ниже порогового значения.
Из отзыва заказчика на Startpack: «Положительным моментом Falcon Space является гибкая настройка системы, надежность, цена и невысокая стоимость владения по сравнению с конкурентами, удобная административная панель, возможность создания личных кабинетов и витрин, интеграция с внешними системами. Отдельно хотел бы отметить команду разработчиков, всегда на связи, помогают во многих вопросах и очень ответственно подходят к своей работе».
Площадка работает на трёх языках: русский, английский, грузинский. Интерфейс переведён, данные каталога (названия вин, описания) могут быть на нескольких языках. Переключение языков — через кнопку. Это потребовало доработок, но дало возможность привлечь иностранных покупателей.
SEO: ЧПУ-адреса для каждого вина (например, /wine/saperavi-2018), мета-теги, карта сайта. Сейчас около 40% трафика — органический поиск.
Этот проект — яркий пример того, как Falcon Space позволяет быстро собрать сложный B2B-маркетплейс с разделением заказов по поставщикам. Если у вас похожая задача — напишите, адаптируем решение под ваш ассортимент и рынок.
P.S. Отдельно хочу отметить, что большинство поставщиков (виноделен) — люди пожилые, не слишком технически подкованные. Но наш кабинет оказался настолько простым, что они освоили его за пару дней. Это заслуга продуманного интерфейса и подсказок.