Требования к товарному фиду
ShopStory использует товарный фид для каталога, связки товаров с эфирами и состояния кнопки покупки. Одно строковое значение feedProductId связывает товар в фиде, на web-PDP, в Mobile SDK и в product action. Основной формат — YML. Другие XML-схемы подключаются после согласования маппинга полей.
Значение наличия обновляется при очередной успешной синхронизации фида и не учитывает магазин покупателя. Для остатка выбранного магазина SDK использует обработчик наличия на стороне сайта ритейлера, а окончательный результат подтверждает его cart-команда: Наличие товара и остатки.
Доступ к источнику
Фид должен быть доступен ShopStory по HTTPS одним из способов:
- публичный URL;
- URL с HTTP Basic Auth.
Для защищённого фида передайте реквизиты через согласованный защищённый канал. Не добавляйте логин и пароль в URL вида https://user:password@example.ru/feed.xml.
Источник должен возвращать валидный XML с кодировкой UTF-8. URL карточек и изображений также должны использовать HTTPS и открываться без пользовательской сессии.
Несколько версий фида
Каталог часто выгружается в нескольких версиях — по ценовым зонам, регионам или каналам продаж. Такие выгрузки различаются не только ценой: состав товаров в них тоже разный, вплоть до категорий, которые в отдельных версиях отсутствуют целиком.
Проект подключается к одной согласованной версии. Её цена и её состав отображаются в плеере и mini-player всем зрителям, независимо от того, где находится зритель.
Поэтому передайте при подключении:
| Что сообщить | Зачем |
|---|---|
| Полный список версий выгрузки и правило «регион или зона → версия» | Чтобы выбрать подключаемую версию осознанно, а не по первой ссылке |
| Какие версии рабочие | Пустая или неполная выгрузка проходит загрузку, но оставляет товары эфира без карточек |
| Зависит ли цена от региона покупателя и насколько | Определяет, допустимо ли показывать всем цену одной зоны |
Если цена или ассортимент зависят от региона покупателя, поведение для зрителей из других зон согласуется отдельно. Обработчик наличия эту разницу не покрывает: он отвечает за доступность покупки и не меняет цену, название и состав каталога.
Несколько стран и валют
Для рынков с разным ассортиментом или валютой согласуйте с ShopStory отдельные каталоги и конфигурации проектов. По каждой стране зафиксируйте источник товаров, валюту, правила цены, строковые товарные ID и назначенный applicationId. Приложение выбирает конфигурацию своего рынка; местоположение зрителя само по себе не переключает подключённый фид.
Одинаковый внешний SKU может встречаться в разных каталогах. Сопоставляйте его внутри выбранного проекта, не переносите между рынками цену, условия покупки или данные из кэша. Роль applicationId описана в идентификаторах проекта.
В приёмку каждой валюты включите карточку товара, кабинет и денежные отчёты: сумма сохраняет точность и код валюты. Например, 9.90 BYN должно отображаться как 9,90 BYN, а не 10 ₽. Итоги разных валют показываются раздельно; конвертация требует отдельного согласованного правила. Наличие поля currencyId не заменяет проверку поддержки валюты в выбранной поставке.
Мастер-фид для расширенной интеграции
В расширенном commerce-контракте товарные данные могут поступать из фида, API магазина или их сочетания. Если структура вариантов передаётся фидом, он содержит товары подключаемого ассортимента, все их SKU и опции, включая временно отсутствующие варианты. При API как источнике структуры эти данные возвращает обработчик магазина; мастер-фид для этого режима не обязателен.
Таблица YML ниже описывает базовый товарный фид. Структура вариантов передаётся по согласованному маппингу, а актуальные условия — через обработчик магазина. Полный набор SKU и опций описан в разделе Товары и варианты.
Идентификаторы товара
Для каждой позиции требуется стабильный строковый идентификатор:
idу элементаoffer— рекомендуемый источникfeedProductId;vendorCode— артикул или SKU продавца.
Рекомендуется передавать оба поля, но во время подключения ShopStory и клиент выбирают одно значение как feedProductId. Оно без изменения формата используется в ShopStory, на сайте, в приложении и в действиях с товаром. vendorCode может оставаться внутренним SKU продавца; если commerce API принимает другой ключ, маппинг выполняется на стороне системы продавца.
Для ранее подключённых проектов может быть согласован поиск по vendorCode. Не смешивайте этот legacy-мэппинг с новым feedProductId в одной интеграции.
Правила для идентификаторов:
- не переиспользуйте значение для другого товара;
- не меняйте формат между выгрузками;
- сохраняйте ведущие нули и регистр, если они значимы;
- передавайте их как строки, даже если значение состоит только из цифр.
Изменение id или vendorCode может создать новую товарную запись. Уже существующая связка товара с эфиром автоматически на неё не переносится.
Поля YML
| Поле | Требование | Назначение |
|---|---|---|
offer/@id или vendorCode | Хотя бы одно | Стабильная идентификация товара. |
name | Для публикации | Название товара. |
url | Для публикации | HTTPS-ссылка на карточку товара. |
picture | Для публикации | Прямая HTTPS-ссылка на изображение. Можно передать несколько элементов. |
price | Для публикации | Текущая цена. Правило для скидочной цены согласуется при подключении. |
currencyId | Для публикации | Код валюты цены, например RUB; поддержку отображения и отчётов проверяют для каждого рынка. |
available | Если фид управляет доступностью | Булево значение true или false в атрибуте offer. |
oldprice | Нет | Цена до скидки. |
vendor | Нет | Бренд или производитель. |
categoryId | Нет | Идентификатор категории в фиде. |
barcode | Нет | Штрихкод. |
description | Нет | Описание товара. |
«Для публикации» означает, что технически строка может быть прочитана без поля, но корректную карточку товара из неё сформировать нельзя. ShopStory проверяет состав полей и маппинг до первой синхронизации.
Минимальный YML-пример
<?xml version="1.0" encoding="UTF-8"?>
<yml_catalog date="2026-09-04 10:00:00">
<shop>
<offers>
<offer id="0001001" available="true">
<name>Крем для рук</name>
<url>https://example.ru/products/0001001</url>
<price>299.00</price>
<oldprice>349.00</oldprice>
<currencyId>RUB</currencyId>
<picture>https://cdn.example.ru/products/0001001.webp</picture>
<vendor>Example Brand</vendor>
<vendorCode>ART-0001001</vendorCode>
</offer>
</offers>
</shop>
</yml_catalog>
Не копируйте пример как готовый маппинг цен. Если ERP передаёт текущую и старую цену иначе, это фиксируется в клиентском приложении к интеграции.
Как обновляется доступность
feedProductId: '0002002'. Значения в примере условные.offer/@id0002002price1624currencyIdRUBavailabletrue
Название, изображение, цена и available.
Товарная карточка получает данные при полной загрузке player.
Запрашивает наличие товаров.
Код ритейлера знает выбранный магазин.
Источник актуального наличия.
Ответ обработчика → наличие в карточках Web SDK по правилам выбранного фида. Цена не меняется. Для неизвестного результата сохраняется состояние из фида.
Действие передаётся commerce-коду магазина.
Проверяет остаток и условия покупки. Подтверждает добавление или возвращает отказ.
Выбор версии фида и live-проверка независимы. Проверка наличия не резервирует товар и не заменяет решение корзины.
При стандартной синхронизации:
- ShopStory успешно загружает и проверяет новую версию фида.
- Для товара с теми же согласованными идентификаторами обновляются цена, карточка и
available. - Оффер с
available="false"становится недоступным для покупки. - Товар, исчезнувший из успешно обработанного полного фида, также может быть отмечен недоступным согласно согласованному правилу импорта.
- Live и VOD используют одно состояние доступности: товар остаётся в эфире, но кнопка покупки блокируется.
Уже открытый плеер использует полученный ранее снимок товарных данных. Новое значение появляется после следующей полной загрузки данных или перезагрузки страницы; фид не опрашивается в реальном времени.
В Public API этот снимок возвращается в body.products[].feedProductAvailable ответа GET /v3/streams. Поле не содержит количество единиц и не подтверждает наличие в выбранном магазине.
Если требуется остаток конкретного магазина, снимок фида дополняется live-проверкой: Web SDK запрашивает наличие у обработчика на сайте ритейлера и обновляет карточки его ответом. В стандартном boolean-контракте available="false" из фида запрещает покупку даже при true от обработчика. Значение этого поля и правила его заполнения согласуйте до запуска: Приоритет источников.
Проверка перед подключением
- URL открывается из внешней сети по HTTPS и возвращает XML, а не HTML-страницу входа.
- XML проходит синтаксическую проверку.
- В каждом
offerесть значение в поле, выбранном источникомfeedProductId; оно совпадает с тестовой web- или mobile-PDP. - Ведущие нули в идентификаторах не потеряны.
urlиpictureдоступны без cookie пользовательской сессии.availableпринимает только согласованные значения и проверен на нескольких доступных и недоступных товарах.- Тестовый импорт подтверждён до включения регулярной синхронизации.
Приёмка выбранной версии
Зафиксируйте вместе с ShopStory источник и версию выгрузки, правила полного обновления и время успешной обработки. serverTime в ответе Public API — время ответа API, не timestamp импорта.
Проверьте несколько согласованных тестовых товаров. В body.products ответа GET /v3/streams сопоставьте строковый feedProductId, название, изображения и feedProductAvailable; цену проверьте в заново открытом player. Public API не заменяет проверку цены в интерфейсе. Уже открытый player может сохранять предыдущий снимок.
Отдельно проверьте доступный товар, available="false" и исчезновение позиции из полного файла. Правило исчезновения согласуется до запуска; отсутствие товара в файле не следует самостоятельно трактовать как его удаление из эфира.
Как выбрать частоту обновления фида
Частота публикации файла у ритейлера и расписание его импорта в ShopStory — разные параметры. ShopStory использует последнюю успешно обработанную выгрузку. Успешный импорт не подтверждает свежесть её содержимого: возраст исходных данных проверяйте отдельно.
| Источник карточки | Что определяет интервал импорта |
|---|---|
| Фид передаёт описание, цены и доступность | Допустимый возраст всех этих данных; изменение цены или наличия требует успешного импорта |
| Мастер-фид передаёт каталог/SKU, расширенный commerce API — актуальные условия покупателя | Изменения ассортимента, описаний, изображений и вариантов. Персональная цена и остаток приходят через API без повторного импорта каталога |
| Описание и структура SKU поступают из товарного API | Мастер-фид не обязателен; свежесть чтения и обновление условий задаёт commerce-контракт |
Не назначайте импорт каждые четыре часа только потому, что меняются персональные цены или остатки. Ежедневное либо более редкое обновление подходит, если допустимый возраст каталога это позволяет; более частое — если меняются его данные. Конкретный интервал и дополнительное обновление перед эфиром согласуйте для проекта.
Это разделение источников относится к расширенному commerce-контракту. Штатный boolean-обработчик цену не обновляет и не отменяет запрет покупки из фида. Если его available отражает быстро меняющийся остаток, частота фида по-прежнему влияет на доступность покупки.
Свежесть и ошибка обновления
До production зафиксируйте:
- расписание загрузки и допустимый для клиента возраст снимка;
- как узнать время последней успешной обработки и подтвердить, какая версия принята;
- кто разбирает недоступный URL, ошибку авторизации, невалидный XML и несовпадение ID;
- какое состояние данных ожидается при неуспешном обновлении и как подтвердить восстановление.
Изменённый файл ещё не означает, что новая версия принята ShopStory. До подтверждения успешной обработки не используйте её как доказательство актуальности. Согласованное расписание не превращает фид в API текущих остатков: окончательную проверку покупки выполняет магазин.
