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

Диагностика интеграции

Начните с наблюдаемого симптома. Для проверки нужен один тестовый проект и известный товар: с опубликованным VOD, без видео или с активным live. Время проверки записывайте с часовым поясом.

Web SDK: каталог или player не появился​

  1. В Network найдите запрос bundle. Проверьте HTTP-код, Content-Type и блокировки CSP или расширений. При loader failure разрешён повтор загрузки script после устранения причины.
  2. После загрузки проверьте наличие window.ShopStorySDK. Используйте точный production URL из Web SDK guide, без подстановки своей версии вместо буквального v1.x.
  3. Сверьте выданный applicationId с параметром SDK config.clientId. Проверьте, что DOM-контейнер существует до show.
  4. Отдельно проверьте загрузку конфигурации, каталога и media. Событие script load и возврат из show() не подтверждают готовность каталога или video frame.
  5. Сверьте origin страницы, включая scheme, hostname и port, с регистрацией проекта. Работа запроса из терминала не доказывает корректность браузерного CORS.

У основного Web SDK нет публичных onReady / onError и универсального destroy(). Не добавляйте их в интеграцию по аналогии с другим SDK. Для SPA используйте документированный lifecycle.

При CSP-блокировке сопоставьте конкретный заблокированный запрос с политикой CSP. Исправление должно разрешать нужный ресурс; отключение CSP целиком не является проверкой успешной интеграции.

Public API: ошибка, пустой список или no_active_stream​

  1. Проверьте HTTP-код, затем верхнеуровневое поле status в JSON. HTTP 200 может содержать ошибку приложения.
  2. Проверьте имя параметра проекта: /v3/streams использует applicationId, /v2/mini-player/* — application.
  3. Для stream-state передавайте feedProductId строкой. Сверьте его с фидом, включая ведущие нули и вариант товара.
  4. Установите ожидаемое состояние: у товара действительно есть опубликованный VOD или доступный live. no_active_stream и пустой список могут быть штатным результатом.
  5. Сравните тест с Quickstart, а поля ответа — с OpenAPI.

Для транспортного сбоя используйте ограниченные повторы GET с backoff: правила повторов. Эти правила не разрешают автоматический повтор записи в Cart API магазина.

Mobile: preview отсутствует или показывает прежний товар​

НаблюдениеПроверка и действие
Ошибка configureСверьте проект и exact package versions. Оставьте SDK UI скрытым, host app продолжает работу
.unavailable / ShopStoryProductStreamUnavailableПроверьте ожидаемое состояние товара. Уберите SDK-блок без пустого места
sdkNotConfiguredВыполните успешный configure до lookup или создания preview scope
invalidProductIdentifierПередайте feedProductId из каталога клиента, а не внутренний ShopStory productId
runtimePolicyDisabledПроверьте согласованное включение проекта и ограничения policy; новый WebView не обходит отключение
networkFailureПовторяйте lookup только для всё ещё видимого товара, с ограничением числа попыток
invalidResponse, decodingFailedСверьте версию и контракт; сохраните typed error и очищенные шаги воспроизведения
requestSupersededИспользуйте запрос текущей конфигурации; результат прежней не должен изменять PDP
Прежний preview после смены товараNative: отмените прежний request и уберите entrypoint. Flutter: обновите feedProductId у scope и проверьте его owner
presentationUnavailableПроверьте, что host UI доступен, нужный экран видим и приложение находится в подходящем lifecycle state

Native cancel() подавляет completion отменённого lookup. Отсутствие callback после cancel ожидаемо. Flutter scope управляет своей preview session; не снимайте новый preview из dispose прежнего экрана.

Полные типы и методы: iOS reference, Flutter reference.

Player открыт, но видео не воспроизводится​

  1. Разделите четыре проверки: страница player загружена, media-запрос прошёл, появился первый frame, позиция воспроизведения движется.
  2. Проверьте тот же тестовый VOD или активный live на поддерживаемом физическом устройстве. Статичный fixture не подтверждает media playback.
  3. В native iOS используйте entrypoint из lookup целиком. Для stream-list допускается только trusted URL, полученный из ShopStory API.
  4. При navigationBlocked или bridgeMessageBlocked проверьте источник URL и совместимость пакета. Не создавайте параллельный bridge и не отключайте origin checks.
  5. При background/foreground сверяйте текущую surface и policy перед возобновлением player.

pageLoaded означает загрузку страницы player, а не video readiness. Работающий VOD не подтверждает исправность текущего live: у него отдельно проверяются состояние эфира и поступление media.

Follow Me пропадает, дублируется или перекрывает checkout​

  1. После push, pop, replace, смены tab и nested route передавайте действительно видимую surface. Для неизвестного маршрута используйте unknown.
  2. В native iOS integration root удерживает один coordinator. При handoff переносите его view; повторный load или teardown начинает другой lifecycle.
  3. Для Flutter root Navigator используйте observer. При tabs и declarative router источник видимого состояния должен вызывать setCurrentSurface отдельно.
  4. Сверьте policy для cart, checkout, payment, auth и profile. Скрытие по policy не равно пользовательскому закрытию session.
  5. При close или remote disable освободите host container. При окончательном завершении native session вызовите teardown.

Геометрию применяйте с учётом safe area и media orientation. Проверяйте касания player и соседних элементов приложения на физическом устройстве.

Клик «Купить» есть, товара в корзине нет​

  1. Определите режим: переход на PDP или прямая корзина. Переход не подтверждает изменение корзины.
  2. Проверьте товар, SKU, выбранный магазин, availability и актуальную сессию покупателя в commerce-коде клиента.
  3. Найдите результат конкретной cart operation. Успех подтверждает ответ Cart API, а не счётчик Buy intent или кнопка player.
  4. При отказе не отправляйте add_to_cart. При timeout исход неизвестен: проверьте статус операции до повторной записи.
  5. В Web short flow вызывайте boolean callback один раз по результату операции. Native delegate не имеет completion; Flutter typed result управляет lifecycle adapter и не подтверждает корзину embedded player.

Контракт: добавление в корзину. Рабочий пример отправки аналитики после подтверждения: confirmed cart.

Аналитика отсутствует, дублируется или не сходится​

СимптомПоследовательность проверки
Событие есть в dataLayer, но его нет в отчётеИмя container → настройка E-commerce → consent → исходящий запрос → фильтры и период отчёта
Два cart events на одно добавлениеНайдите всех отправителей: SDK, callback клиента, GTM и analytics adapter. Оставьте одного владельца события для целевой системы
Buy intent больше подтверждённых добавленийСверьте отказы и переходы на PDP. Intent учитывается до результата Cart API
Числа VOD меняются при сверке источниковСравните источник метрик, покрытие и период. Provider и first-party имеют разные правила подсчёта
В старой выгрузке «уникальные» равны просмотрамПроверьте legacy first-party базис; он не подтверждает distinct viewers
Нет заказов с просмотром ShopStoryПроверьте покрытие страницы заказа и сохранение контекста. Отсутствие покрытия не означает нулевые продажи
Consent запрещён или действует blockerЗафиксируйте ограничение покрытия; не считайте его ошибкой Cart API

Определения и формулы: события и метрики. Связь просмотра с заказом не доказывает причинный эффект видео на продажи.

Что приложить в поддержку​

  • версия SDK; ОС, browser или toolchain; host app version;
  • проект, затронутые feedProductId и streamId;
  • время с часовым поясом, видимая surface и короткие шаги;
  • ожидаемый результат, фактический typed result или очищенный HTTP/envelope status;
  • для аналитики — система, имя события, период, источник показателя и наличие повторной отправки.

Удалите tokens, cookies, URL query с секретами, профиль покупателя, содержимое корзины и полные production logs. Для воспроизведения используйте тестовые товары. Канал: support@shopstory.live.