Перейти к основному содержимому

Требования к товарному фиду

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'. Значения в примере условные.
Bronzing powder
offer/@id
0002002
price
1624
currencyId
RUB
available
true
Выбранная версия фида

Название, изображение, цена и available.

Успешный импорт
Снимок в ShopStory

Товарная карточка получает данные при полной загрузке player.

Дополнительная ветвь: нужен текущий остаток магазина
Основной Web SDK

Запрашивает наличие товаров.

Товарные ID
Обработчик сайта

Код ритейлера знает выбранный магазин.

Запрос остатка
Stock API магазина

Источник актуального наличия.

Ответ обработчика → наличие в карточках Web SDK по правилам выбранного фида. Цена не меняется. Для неизвестного результата сохраняется состояние из фида.

При добавлении товара — отдельная проверка
Покупатель нажимает «Купить»

Действие передаётся commerce-коду магазина.

Cart-команда
Cart API магазина

Проверяет остаток и условия покупки. Подтверждает добавление или возвращает отказ.

Выбор версии фида и live-проверка независимы. Проверка наличия не резервирует товар и не заменяет решение корзины.

При стандартной синхронизации:

  1. ShopStory успешно загружает и проверяет новую версию фида.
  2. Для товара с теми же согласованными идентификаторами обновляются цена, карточка и available.
  3. Оффер с available="false" становится недоступным для покупки.
  4. Товар, исчезнувший из успешно обработанного полного фида, также может быть отмечен недоступным согласно согласованному правилу импорта.
  5. Live и VOD используют одно состояние доступности: товар остаётся в эфире, но кнопка покупки блокируется.

Уже открытый плеер использует полученный ранее снимок товарных данных. Новое значение появляется после следующей полной загрузки данных или перезагрузки страницы; фид не опрашивается в реальном времени.

В Public API этот снимок возвращается в body.products[].feedProductAvailable ответа GET /v3/streams. Поле не содержит количество единиц и не подтверждает наличие в выбранном магазине.

Если требуется остаток конкретного магазина, снимок фида дополняется live-проверкой: Web SDK запрашивает наличие у обработчика на сайте ритейлера и обновляет карточки его ответом. В стандартном boolean-контракте available="false" из фида запрещает покупку даже при true от обработчика. Значение этого поля и правила его заполнения согласуйте до запуска: Приоритет источников.

Проверка перед подключением​

  1. URL открывается из внешней сети по HTTPS и возвращает XML, а не HTML-страницу входа.
  2. XML проходит синтаксическую проверку.
  3. В каждом offer есть значение в поле, выбранном источником feedProductId; оно совпадает с тестовой web- или mobile-PDP.
  4. Ведущие нули в идентификаторах не потеряны.
  5. url и picture доступны без cookie пользовательской сессии.
  6. available принимает только согласованные значения и проверен на нескольких доступных и недоступных товарах.
  7. Тестовый импорт подтверждён до включения регулярной синхронизации.

Приёмка выбранной версии​

Зафиксируйте вместе с 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 текущих остатков: окончательную проверку покупки выполняет магазин.

Связанные разделы​