<!-- Canonical: https://docs.shopstory.live/docs/operations/troubleshooting -->

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

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

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

1. В Network найдите запрос bundle. Проверьте HTTP-код, Content-Type и блокировки CSP или расширений. При loader failure разрешён повтор загрузки script после устранения причины.
2. После загрузки проверьте наличие `window.ShopStorySDK`. Используйте точный production URL из [Web SDK guide](<https://docs.shopstory.live/docs/guide/web-sdk>), без подстановки своей версии вместо буквального `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](<https://docs.shopstory.live/docs/guide/web-sdk-reference#spa-%D0%B8-lifecycle>).

При CSP-блокировке сопоставьте конкретный заблокированный запрос с [политикой CSP](<https://docs.shopstory.live/docs/operations/csp-headers>). Исправление должно разрешать нужный ресурс; отключение 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](<https://docs.shopstory.live/docs/guide/quickstart>), а поля ответа — с [OpenAPI](<https://docs.shopstory.live/docs/reference/openapi>).

Для транспортного сбоя используйте ограниченные повторы GET с backoff: [правила повторов](<https://docs.shopstory.live/docs/operations/rate-limits>). Эти правила не разрешают автоматический повтор записи в 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](<https://docs.shopstory.live/docs/reference/mobile-sdk-ios>), [Flutter reference](<https://docs.shopstory.live/docs/reference/mobile-sdk-flutter>).

## 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.

Контракт: [добавление в корзину](<https://docs.shopstory.live/docs/guide/add-to-cart>). Рабочий пример отправки аналитики после подтверждения: [confirmed cart](<https://docs.shopstory.live/docs/guide/confirmed-cart-analytics>).

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

| Симптом | Последовательность проверки |
| --- | --- |
| Событие есть в `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 |

Определения и формулы: [события и метрики](<https://docs.shopstory.live/docs/reference/events-metrics>). Связь просмотра с заказом не доказывает причинный эффект видео на продажи.

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

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

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