<!-- Canonical: https://docs.shopstory.live/docs/guide/analytics-web -->

# Web tracking: E-commerce и UTM

Сначала определите [смысл метрик](<https://docs.shopstory.live/docs/guide/analytics>). Этот раздел описывает события магазина и переходы с Web SDK. Он не добавляет методы в Public API.

## Яндекс Метрика

Для согласованной интеграции SDK отправляет `ecommerce.add` после успешного callback корзины. ShopStory должен подтвердить поддержку вашего именованного data container; создание массива или включение E-commerce в счётчике само по себе не подключает отправку.

До включения передайте команде ShopStory имя container, страницу player, test origin и способ подтверждения корзины. ID и настройка счётчика остаются у клиента.

1. Разместите основной Web SDK как script на странице магазина с установленным счётчиком.
2. В настройках Яндекс Метрики включите **Электронную коммерцию** и укажите согласованное имя data container.
3. Подключите [callback корзины](<https://docs.shopstory.live/docs/guide/add-to-cart>). Возвращайте `true` после подтверждённого изменения.
4. Получите подтверждение включения tracking для проекта и проверьте тестовый товар.

SDK, встроенный отдельным iframe на другом origin, не пишет в data container родительской страницы. Самостоятельный `postMessage` bridge в этот контракт не входит.

Ниже показан формат события, а не код для повторной отправки. `shopstoryEcommerce` — пример имени container; используйте имя из конфигурации вашего счётчика.

metrica-add-example.js

```javascript
window.shopstoryEcommerce.push({
  ecommerce: {
    currencyCode: 'RUB',
    add: {
      products: [{
        id: '0001001',
        name: 'Тестовый товар',
        price: 1299,
        quantity: 1,
        list: 'ShopStory VOD',
      }],
    },
  },
});
```

| Поле | Значение |
| --- | --- |
| `id` | `feedProductId`; в ранее подключённых данных возможен внутренний ID — маппинг проверяется до запуска |
| `price` | Цена из карточки ShopStory, которая может быть снимком каталога; не сумма оплаченного заказа |
| `quantity` | Для стандартного callback — `1` |
| `currencyCode` | Валюта каталога; `RUR` нормализуется в `RUB`, отсутствующее значение — в `RUB` |
| `list` | `ShopStory Live`, `ShopStory VOD` или `ShopStory Mini Player` |

`ShopStory Mini Player` означает, что player открыт через mini-player. В остальных случаях текущий эфир относится к Live, запись — к VOD.

Если цена зависит от сессии или SKU, согласуйте источник аналитической суммы отдельно. Стандартный boolean callback не возвращает SDK фактическую цену Cart API.

Назначьте одного отправителя события в счётчик. Если SDK уже отправляет `ecommerce.add`, не дублируйте его в клиентском callback.

## GA4

Формат `ecommerce.add.products` не равен событию GA4 `add_to_cart`. Автоматическая конвертация между ними не входит в общий контракт Web SDK.

Для GA4 магазин может отправить событие своим analytics adapter после подтверждения Cart API. Используйте существующий `gtag`/GTM и принятый consent flow. Сумма, валюта, SKU и quantity берутся из подтверждённого результата магазина.

В примере `confirmed.items` содержит добавленные позиции, а `confirmed.total` — сумму этих единиц. Полный состав и стоимость корзины сюда не передаются.

merchant-ga4-add.js

```javascript
function reportConfirmedCartAdd(gtag, confirmed, source) {
  gtag('event', 'add_to_cart', {
    currency: confirmed.currency,
    value: confirmed.total,
    items: confirmed.items.map(item => ({
      item_id: item.feedProductId,
      item_name: item.name,
      price: item.unitPrice,
      quantity: item.quantity,
      item_list_name: source,
    })),
  });
}
```

Это код аналитики магазина, не метод SDK. Вызывайте его один раз из успешной ветки cart operation. При ошибке, timeout с неизвестным результатом или открытии PDP событие не отправляется. После выяснения исхода повторно проверьте, не было ли событие уже отправлено.

`purchase` отправляет система магазина по подтверждённому заказу с уникальным `transaction_id`. Не создавайте `purchase` из клика «Купить» или `callback(true)`.

## UTM-переходы

При включённой для проекта разметке SDK добавляет UTM к URL товара при клике по фото или названию:

| Параметр | Значение |
| --- | --- |
| `utm_source` | `shopstory` |
| `utm_medium` | Источник открытия player; по умолчанию `organic`, для mini-player — `mini-player` |
| `utm_campaign` | `live`, `record` или `planned` |
| `utm_content` | `applicationId_translationId` |
| `utm_term` | Название эфира после преобразования в URL-совместимую строку |

`record` — значение UTM, а `ShopStory VOD` — значение E-commerce `list`. Они относятся к разным схемам и не должны механически заменять друг друга.

Прямая корзина не открывает PDP, поэтому UTM-перехода для неё нет. Standalone PiP и основной Web SDK имеют разные способы подключения callback; проверяйте фактический маршрут: [mini-player на PDP](<https://docs.shopstory.live/docs/guide/web-mini-player>).

## Проверить tracking

- В тестовой среде выполните успешное добавление: одна cart operation, одно ожидаемое событие.
- Повторите отказ, timeout и повторный callback: ложного подтверждения и дубля нет.
- Сравните `feedProductId`, SKU, валюту и quantity с корзиной.
- Проверьте Live, VOD и вход через mini-player по отдельности.
- Проверьте container в DevTools без его очистки или перезаписи; затем запрос аналитики в Network.
- Проверьте событие в отчёте нужного счётчика. Фильтруйте тестовый период и источник.
- Повторите сценарий с запрещённым consent и блокировщиком. Зафиксируйте ограничение покрытия, не считайте отсутствие события отказом Cart API.

Если событие есть в container, но отсутствует в отчёте, проверьте имя container, включение E-commerce, consent, фильтры и отправку запроса. Если есть дубли — найдите всех отправителей, прежде чем менять отчёт.

Схемы поставщиков: [Яндекс Метрика](<https://yandex.ru/support/metrica/ru/ecommerce/data>), [проверка настройки](<https://yandex.ru/support/metrica/ru/ecommerce/check>), [GA4 E-commerce](<https://developers.google.com/analytics/devguides/collection/ga4/ecommerce>).
