RYBAK.INFO — подключение магазинов, версия 2.6.0 Что работает сейчас ------------------ Один товар может иметь предложения нескольких продавцов. Покупатель сравнивает цену, наличие, доставку и переходит на страницу товара в магазине. Оформление, оплата и обслуживание заказа происходят у продавца. Автоматической синхронизации через API, кабинета продавца и приёма заказов на rybak.info в этой версии нет. Все 12 текущих товаров и 3 магазина вымышлены. Это примеры интерфейса. Демонстрационные предложения не имеют активных внешних ссылок и не принимают заказы. Их цены, остатки и сроки нельзя выдавать за реальные сведения. Подготовка настоящего каталога ---------------------------- 1. Согласуйте публикацию каталога с магазином и получите его файл. 2. Добавьте реальные карточки с новыми id в assets/products.js. Сохраняйте прежние карточки и их id: они могут использоваться в личных данных. Для одного productId должна совпадать точная модель и вариант товара, включая размер, вес, цвет или другую характеристику комплектации. Нельзя привязывать реальные предложения к похожим вымышленным моделям. 3. Сопоставьте каждое предложение с уже существующим productId вручную. Импорт не угадывает товары по названию и не создаёт новые карточки. 4. Укажите магазин, его точный домен и предложения по схеме ниже. У реального магазина и всех его предложений demo: false. Форматы и локальный импорт ------------------------ Примеры (они заменяют каталог небольшим демонстрационным набором): docs/merchant-feed.example.json docs/merchant-feed.example.csv На компьютере владельца нужен Node.js 22 или новее. Хостингу Node.js не нужен. Откройте папку сайта и выполните одну команду: node tools/import-offers.mjs путь/каталог.json или: node tools/import-offers.mjs путь/каталог.csv Импорт полностью ЗАМЕНЯЕТ список магазинов и предложений. Для сохранения всех продавцов передавайте общий файл. Сохраните прежний assets/marketplace-data.js перед успешным импортом. Ошибка проверки не изменяет исходный каталог. Личные данные посетителей, дневники и резервные JSON-копии импорт не меняет. Скрипт работает локально, не отправляет сведения по сети и не исполняет строки из файла как код. Выходной файл — assets/marketplace-data.js. После импорта измените только имя кэша в sw.js, например добавьте уникальную дату выгрузки к const CACHE: CACHE_PREFIX+VERSION+'-catalog-20260915-01'. VERSION приложения при обновлении только каталога оставьте прежним. Загрузите сначала marketplace-data.js, затем sw.js. Примените обновление на /install/ и закройте старые вкладки. Иначе офлайн-кэш продолжит показывать старый каталог. Для надёжного отката сохраните вместе прежние marketplace-data.js и sw.js. JSON: строгая схема, все перечисленные поля обязательны ---------------------------------------------------- Верхний объект: {"version":1,"merchants":[...],"offers":[...]}. Лишние поля отклоняются. merchant id уникален; offer id уникален во всём файле. Идентификаторы: 1–80 символов, a-z, 0-9, дефис и подчёркивание; первый символ буква или цифра. От 1 до 1000 магазинов, от 1 до 100000 предложений, до 30 МБ. Магазин: id уникальный идентификатор магазина name название, непустая строка до 160 символов domain точное DNS-имя без https://, пути, порта и www-догадок url HTTPS-ссылка магазина либо null demo true для вымышленных примеров; false для реального магазина description непустое описание до 500 символов Предложение: id уникальный идентификатор предложения productId существующий id из assets/products.js merchantId id магазина из merchants этого же файла price цена в копейках BYN: 12900 означает 129,00 BYN currency только "BYN" availability "in_stock", "out_of_stock" или "unknown" deliveryDays [минимум,максимум] календарных дней или null shipping доставка одной позиции в копейках; 0 бесплатно, null неизвестно updatedAt время получения данных от магазина в UTC ISO: "2026-09-14T08:00:00Z" или "2026-09-14T08:00:00.000Z" url HTTPS-ссылка именно на товар у продавца либо null demo то же значение, что у соответствующего магазина Цена: целое число 1–1000000000. Доставка: целое число 0–1000000000 или null. Сроки: два целых числа от 0 до 365; минимум не больше максимума. У demo-магазинов и demo-предложений url обязательно null. Ссылки допускаются только по HTTPS, без логина, пароля и нестандартного порта, строго на domain магазина. Поддомены не разрешаются автоматически. Если страница товара находится на shop.example.by, укажите именно shop.example.by как domain. CSV --- Кодировка UTF-8, разделитель — запятая, первая строка — названия колонок. Заголовки обязательны, их порядок можно менять. Значения true/false строчные. Пустые url, merchantUrl, shipping означают null. Два пустых deliveryMin и deliveryMax означают неизвестный срок. Одно пустое значение срока — ошибка. Цена и доставка только целыми копейками, без пробелов и десятичного разделителя. Кавычки в полях удваиваются по стандартным правилам CSV. Excel-формулы не нужны. Данные одного магазина повторяются в строках без изменений. Колонки: id,productId,merchantId,merchantName,merchantDomain,merchantUrl,merchantDemo, merchantDescription,price,currency,availability,deliveryMin,deliveryMax, shipping,updatedAt,url,demo Актуальность и планирование -------------------------- Предложение старше 48 часов или с временем из будущего требует обновления. Свежесть считается от updatedAt; нельзя обновлять это поле без получения новых данных продавца. Демонстрационные исторические примеры остаются видимыми. Наличие unknown не означает «есть в наличии». При shipping:null итоговая цена с доставкой неизвестна; она не подменяется нулём. Цена доставки одной позиции не является ценой доставки всего списка покупок или общей корзины. Прогноз относительно выезда сравнивает календарные дни и не гарантирует доставку. Адрес покупателя, время приёма заказа, выходные и условия продавца нужно уточнять. Офлайн доступны сохранённые предложения. Для перехода к продавцу нужен интернет. Следующий этап после подключения первых партнёров — адаптеры автоматического обновления каталога и кабинет продавца. «Любой магазин» подключается через согласованный формат или отдельную интеграцию; универсального API пока нет.