Мультивендорний маркетплейс, де кілька продавців конкурують на одній картці товару: вітрина, кабінет продавця й адмінка на спільному API, із пошуком, доставкою, оплатами та фіскальними чеками. Ось рішення, які його сформували.
Товар — це не пропозиція
Товар каталогу й пропозиція продавця — різні сутності. Одна картка описує саму річ, а кожен продавець чіпляє до неї свою пропозицію з власною ціною, залишком, медіа й оптовими ціновими рівнями.
Усе складне в маркетплейсі випливає з цього поділу: зіставити вхідну позицію з наявним товаром, злити дублі, які прослизнули, і вирішити, чию пропозицію покупець побачить першою. Зроблене навпаки — по рядку товару на кожного продавця — дає каталог, де та сама річ трапляється сорок разів і жоден фільтр цього не виправить.
Пошук, який не віддає сторінку одному продавцю
Пошук працює на OpenSearch: атрибути товарів індексуються вкладеними документами, тож фільтри будуються під категорію, а не під одне поле, а повний шлях категорії в індексі означає, що фільтр по батьківській категорії знаходить усе, що під нею.
Результати — не плоский список релевантності. Пропозиції групуються за продавцем, групи впорядковуються за найкращою пропозицією й далі чергуються, тож маркетплейс з одним великим продавцем і півсотнею малих усе одно показує малих. Маркетплейс, де найбільший продавець забирає кожну сторінку видачі, перестає приваблювати нових.
Продавці вантажать фіди, а не заповнюють таблиці руками
Каталог росте через пайплайн імпорту: спершу сирі позиції, зіставлення полів зберігається як пресет для кожного продавця, проблеми з медіа фіксуються по позиції, а не валять увесь батч, а матчинг пропонує товар каталогу, до якого позиція належить.
Нові бренди й категорії чекають на підтвердження, перш ніж потрапити у фасети пошуку. Без цього фільтра один недбалий фід перейменовує цілу гілку каталогу.
Одинадцять станів — і хто їх рухав
Замовлення проходить шлях від створеного через оплачене, в обробці, готове до відправки, відправлене, доставлене й завершене, а скасування, повернення коштів і повернення товару — повноцінні стани, а не прапорці.
Кожен перехід записує, що його спричинило й хто його зробив: створення замовлення, вебхук оплати, задача повернення, tracking-push Нової пошти, адміністратор, менеджер продавця чи планувальник. Коли покупець питає, чому в замовленні саме такий статус, відповідь лежить у рядку, а не в логах.
Гроші, доставка й податкова
Оплати йдуть через LiqPay, monobank і Hutko за спільним інтерфейсом провайдера, тож новий еквайр — це новий файл, а не нова гілка в оформленні замовлення. Накладений платіж лишається таким самим способом оплати, як інші.
Доставка охоплює Нову пошту, Укрпошту, Meest і Delivery Auto — довідники відділень і поштоматів, друк накладних і трекінг, який повертає статус у замовлення. Фіскальні чеки йдуть через Checkbox, Cashalot або «Вчасно», бо в Україні чек — це не побажання, а закон.
Зроблено, щоб цим керували
Чат покупця з продавцем працює через вебсокети з Redis під ними. Сповіщення, відгуки, скарги, аудит, CMS-блоки для футера й статичних сторінок, аналітика продавця та рекламний модуль — окремі модулі на тому самому API.
Сто три міграції — це чесна міра маркетплейсу: схема рухається, бо бізнес постійно доузнає, що саме він продає.
Результат
Робочий мультивендорний маркетплейс на enez.com.ua — вітрина покупця, кабінет продавця й адмінка на одному API, з фасетним пошуком, чотирма службами доставки, трьома еквайрами й фіскальними чеками в продакшені.