Маркетплейс · оголошення

Admister — сім маркетплейсів з одним рушієм

Оголошення, авто, нерухомість, товарний ринок із магазинами, цифрові товари, купони та прайс-агрегатор. Сім сервісів живуть на своїх піддоменах, і кожен — це той самий застосунок: сервіс обирається за адресою запиту, а каталог, акаунти, гроші, модерація та пошук спільні. Ми придумали модель, написали рушій і випустили всі сім.

Категорія
Маркетплейс · оголошення
Оцінка вартості
від €32 000
Сервісів
сім, одна кодова база
Мови
EN, UK · чотири валюти показу
Стек
PHP 8.3, MariaDB, без фреймворка
admister.org
Admister
Головна сторінка проєкту — admister.org

01Про проєкт

Admister — мультивертикальний маркетплейс. Під одним дахом працюють дошка оголошень, авто із запчастинами, нерухомість із продажем і орендою, товарний ринок із магазинами продавців, цифрові товари, купонний сервіс і прайс-агрегатор. У кожного свій піддомен, своя головна і своє уявлення про те, що таке «оголошення».

Ззовні це сім різних продуктів. Усередині — один застосунок: сервіс визначається за адресою запиту, а все, що нижче — акаунти, гроші, модерація, пошук, медіа, сповіщення, — спільне. Проєкт наш цілком: модель, рушій, інтерфейс і запуск кожної вертикалі.

02Контекст і проблема

Звичайний спосіб запустити кілька маркетплейсів — запустити кілька сайтів. Він працює до другого: з’являються дві таблиці користувачів, дві черги модерації, дві інтеграції з оплатою і два місця, де ту саму помилку треба лагодити двічі — і по-різному, бо код на той час уже розійшовся.

Протилежна крайність не краща. Сайт із категорією «Авто» не вміє питати пробіг, двигун і номер так, як це робить авто-дошка, а пошук нерухомості без поверху й кількості кімнат — не пошук нерухомості. Завдання було в тому, щоб лишити один рушій і водночас не вдавати, ніби сім дуже різних каталогів — це один каталог.

03Завдання проєкту

  • одна кодова база й один акаунт на всі вертикалі, сервіс обирається за адресою;
  • власні атрибути та фільтри в кожної вертикалі: десятки полів в авто й нерухомості, і жодного з них — в інших сервісах;
  • гроші, яким власник довіряє: баланс, криптоінвойси, ідемпотентне зарахування та звіряння завислих платежів;
  • причини повертатися: збережені пошуки з пушами, бейджі продавців, аукціони та групові закупівлі;
  • дві мови й чотири валюти показу без дублювання контенту;
  • мобільний застосунок, що ходить у свій BFF, а не розбирає сторінки сайту.

04Що ми зробили

Реєстр сервісів вбудовано в завантаження застосунку. Надходить запит, адреса звіряється з реєстром — і далі застосунок знає, яка він вертикаль: які модулі піднімати, який набір атрибутів брати, яку головну та яке меню малювати. Голий домен — дошка оголошень, тож найкоротша адреса водночас і найзагальніша.

Усе, що не залежить від вертикалі, написано один раз: акаунти й сесії, баланс і платежі, приймання медіа, модерація, збережені пошуки, сповіщення, карта сайту та API. Додати сьомий сервіс означало написати його атрибути та його головну — а не ще один маркетплейс.

05Сім сервісів — сім каталогів

  • Оголошення — загальна дошка: від велосипеда до дивана, публікація безкоштовна.
  • Авто — транспорт, номери та запчастини, з власним набором із кількох десятків атрибутів і фільтрами поверх нього.
  • Нерухомість — продаж і оренда, власний набір атрибутів, карти та пошук по районах.
  • Маркет — товари з магазинами продавців: вітрина на продавця, залишки, замовлення.
  • Цифрові товари — ключі, гіфт-карти та eSIM: те, що доставляють, а не відправляють.
  • Купони — промокоди та акції магазинів-партнерів.
  • Прайс — агрегатор цін: один товар у різних магазинах, порівняння та враховані переходи.

У них спільні акаунт, баланс, черга модерації та пошуковий індекс — і нічого спільного в атрибутах, заради чого все й робилося.

06Гроші: баланс, криптоінвойси, звіряння

Платне — просування, тарифи магазинів, цифрові товари — оплачується з внутрішнього балансу, а баланс поповнюється криптою через Payora, наш же шлюз. Тіло інвойсу збирається рівно в одній функції, бо те саме тіло повторює крон звіряння під тим самим ключем ідемпотентності: одне розбіжне поле повернулося б конфліктом і підвісило платіж.

Дві деталі, які ми повторимо на будь-якому шлюзі. В інвойс іде мова самого покупця з його рядка в базі, а не з вебзапиту: у крона запиту немає, і інакше всім ішла б англійська. І адреса повернення веде в кабінет на голому домені — покупець, що почав з авто-вертикалі, повертається залогіненим, а не на сторінку «увійдіть знову».

07Довіра: модерація, бейджі, суперечки

Маркетплейс судять за найгіршим оголошенням, тому модерація тут не бічний екран. Кожне рішення — схвалити, відхилити, зняти — проходить через один обробник, і «відхилити» навмисно не те саме, що «зняти»: перше — відповідь авторові з причиною, друге прибирає те, що вже висіло. Два дієслова, два різні листи, два різні стани в записі.

У продавців і магазинів є бейджі, які заробляють, а не купують: скільки живе акаунт, скільки угод закрито, чи підтверджені телефон і пошта. Покупець бачить той самий бейдж усюди, де зустрічає продавця, бо рахується він в одному місці.

09Мобільний застосунок із власним бекендом

Застосунок не розбирає сторінки сайту. Він ходить у свій BFF: невеликий набір точок, що відповідають у тих формах, які потрібні екранам, із токенами, які видаються окремо від вебсесій. Без токена відкриті два шляхи — довідники, потрібні до входу, і адреса живості.

Адреса живості окрема навмисно. Реєстр, що стежить за флотом застосунків, раніше питав довідники, а вони збирають усі словники й курси, — перевірка живості не має коштувати дорожче за саму роботу. Він же віддає версію договору: клієнт, зібраний під стару версію, видно раніше, ніж це помітять його користувачі.

10SEO на сім фронтів

Сім сервісів на одному домені — це сім карт сайту, сім наборів структурованих даних і дуже простий спосіб наплодити дублі. Кожна вертикаль публікує свою карту з кешу, сторінки оголошень оголошують свій тип розмітки, а сторінки результатів пошуку ніколи не видають себе за канонічну адресу оголошення.

Контент теж автоматизований: потік матеріалів надходить з Astrina — платформи, яку ми зробили саме для цього, — і щойно стаття приходить, кеш карти сайту її вертикалі скидається. Інакше нова сторінка чекала б наступної перезбірки, і ніхто б не зрозумів, чому її немає.

11Один канал назовні

Усе, що застосунок надсилає назовні — виклики API, вебхуки, партнерські фіди, забирані картинки, пошта, — іде через один модуль, прив’язаний до SOCKS5-проксі, і DNS резолвиться через той самий проксі. Модуль працює fail-closed: недоступний проксі — запит блокується, а не йде тихо з адреси сервера.

Це не прикраса. Маркетплейс цілий день тягне партнерські фіди й чужі картинки, і кожен такий запит інакше відносив би адресу майданчика третій стороні. Пошта йде тим самим шляхом, через YourTrend: листи підписані, а ім’я сервера не з’являється в заголовках.

12Технології

  • PHP 8.3 без фреймворка, тонка обгортка над PDO і підготовлені запити всюди;
  • MariaDB, схема живе нумерованими файлами міграцій, а не в чиїйсь пам’яті;
  • медіа лежать поза вебрутом і віддаються контролером — завантажений файл ніколи не стає виконуваним шляхом;
  • збірка асетів із хешем в імені й без інлайну того, що має кешуватися, з вимикачем на випадок збою;
  • SOCKS5 назовні для кожного вихідного виклику, пошта через SMTP YourTrend;
  • Payora — криптоінвойси, Astrina — вхід і матеріали, Adgora — власна реклама.

13Результат

Сім живих сервісів на одній кодовій базі, один акаунт і один баланс на всіх, і при цьому атрибути та фільтри різняться рівно настільки, наскільки різняться каталоги. Нова вертикаль — це набір атрибутів і головна сторінка, а не новий проєкт, не друга таблиця користувачів і не друга інтеграція з оплатою.

Власникові це дає одне місце, куди дивитися. Модерація, гроші, продавці та контент ведуться із загальної панелі керування всієї групи проєктів, а маркетплейс віддає їх підписаним адмінським API, а не другим власним адмін-сайтом.

14Висновки

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

Другий висновок — про гроші. Місце, де описується платіж, зобов’язане бути єдиною функцією: його однаково повторить хтось інший — крон, повтор, звіряння, — а два описи одного платежу це найдешевший спосіб тихо втратити гроші.

Якщо ви будуєте маркетплейс, дошку оголошень або мультивертикальний майданчик на одному рушії — це робота, яку ми робимо цілком.

На які запити відповідає ця сторінка

розробка мультивертикального маркетплейсу, створення сайту оголошень під ключ, зробити маркетплейс як olx, розробка авто-дошки оголошень, платформа оголошень нерухомості розробка, маркетплейс цифрових товарів розробка, сайт купонів і промокодів розробка, агрегатор цін розробка, маркетплейс із магазинами продавців, збережені пошуки зі сповіщеннями, бейджі продавців і довіра, криптооплата на маркетплейсі, баланс і виплати на маркетплейсі, модерація оголошень процес, бекенд мобільного застосунку маркетплейсу, скільки коштує розробка маркетплейсу, одна кодова база кілька вертикалей, архітектура піддомен на вертикаль, seo маркетплейсу карта сайту, admister.