Налаштування ecommerce у GA4: події, параметри і перевірка
Покрокове налаштування електронної торгівлі в GA4 — рекомендовані події від view_item до purchase і refund, обов'язкові параметри, dataLayer, перевірка в DebugView і BigQuery.

Добрий дашборд магазину неможливий без правильних подій ecommerce у GA4. Більшість проблем, які я бачу на аудитах, однакові: purchase спрацьовує двічі, немає transaction_id, ціна передається рядком з «грн», а items порожній. Нижче — як налаштувати все так, щоб дані можна було використовувати.
Які події потрібні
Google описує рекомендовані події в документації ecommerce і в переліку рекомендованих подій. Мінімальний робочий набір:
| Подія | Коли | Пріоритет |
|---|---|---|
view_item_list | показ списку товарів (каталог, пошук) | середній |
select_item | клік по товару в списку | середній |
view_item | сторінка товару | високий |
add_to_cart | додавання в кошик | високий |
remove_from_cart | видалення з кошика | низький |
view_cart | перегляд кошика | середній |
begin_checkout | початок оформлення | високий |
add_shipping_info | обрано доставку | середній |
add_payment_info | обрано оплату | середній |
purchase | замовлення оформлено/оплачено | критичний |
refund | повернення | бажано |
Обов'язкові параметри
Для purchase:
| Параметр | Приклад | Нюанс |
|---|---|---|
transaction_id | "100245" | той самий ID, що в CRM; без нього — дублікати |
value | 1580.00 | число, без валюти й пробілів |
currency | "UAH" | ISO-код; без нього value ігнорується |
shipping | 70 | за потреби |
tax | 0 | за потреби |
coupon | "AUTUMN10" | для аналізу промокодів |
items | масив товарів | хоча б item_id або item_name |
Для кожного товару в items: item_id, item_name, price, quantity, бажано item_brand, item_category, item_variant.
Приклад dataLayer для purchase
dataLayer.push({ ecommerce: null }); // очистити попередній об'єкт
dataLayer.push({
event: 'purchase',
ecommerce: {
transaction_id: '100245',
value: 1580.00,
currency: 'UAH',
shipping: 70,
coupon: 'AUTUMN10',
items: [
{ item_id: 'SKU-881', item_name: 'Термочашка 450 мл', item_category: 'Посуд', price: 755.00, quantity: 2 }
]
}
});
Де відправляти purchase
Найчастіша проблема — подія на сторінці «Дякуємо за замовлення». Вона:
- спрацьовує повторно при оновленні сторінки або поверненні з пошти;
- не спрацьовує, якщо оплата пройшла на сторінці LiqPay/monobank, а користувач закрив вкладку до редиректу;
- блокується adblock-ом.
Що роблю я:
- Відправляю
purchaseу момент створення замовлення на фронтенді зtransaction_id— і захищаю від повтору (прапорець у localStorage або cookie за ID). - Для оплачених онлайн замовлень — дублюю подію з бекенду через Measurement Protocol після callback від платіжки (серверний трекінг). GA4 дедуплікує за
transaction_idу межах ресурсу. - Повернення — через
refundз бекенду.
Платформи
- Shopify має вбудовану інтеграцію з Google; перевіряйте, які події вона шле і чи не дублюються вони з GTM.
- Horoshop, Prom — є модулі або налаштування GA4; часто передають не всі параметри
items, перевіряйте. - OpenCart, WooCommerce, власна розробка — dataLayer + GTM за схемою вище.
Перевірка
- GTM Preview + GA4 DebugView: пройдіть шлях від каталогу до оплати, перевірте кожну подію й параметри.
- Звіт «Монетизація → Покупки в електронній торгівлі»: чи заповнені назви товарів.
- BigQuery: запити на дублікати
transaction_idі порожніitems(експорт GA4). - Звірка з CRM за тиждень: кількість і сума замовлень. Розбіжність до кількох відсотків нормальна; більше — шукаємо причину (розбіжності GA4 і CRM).
SELECT event_date,
COUNTIF(ecommerce.transaction_id IS NULL) AS no_tid,
COUNTIF(ARRAY_LENGTH(items) = 0) AS no_items,
COUNT(*) AS purchases
FROM `project.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX >= '20261001' AND event_name = 'purchase'
GROUP BY 1 ORDER BY 1;
Типові помилки
valueз ПДВ в одних замовленнях і без — в інших.- Різні
item_idдля одного товару (SKU в одному місці, внутрішній ID — в іншому). - Не очищується
ecommerceперед новим push — параметри «перетікають» між подіями. - Валюта не передається — GA4 ігнорує суми.
- Тестові замовлення потрапляють у прод-ресурс.
Чекліст
- Всі події воронки від
view_itemдоpurchase transaction_id= ID замовлення в CRMvalue— число,currency— ISO-кодitemsз однаковимиitem_idу всіх подіях- Захист від повторної відправки
purchase - Серверне підтвердження оплачених замовлень
refundдля повернень- Тижнева звірка з CRM
Покроково: purchase через dataLayer
Найчистіше рішення для більшості магазинів — push у dataLayer зі сторінки підтвердження (а краще — з коду, що підтверджує оплату) і тег події GA4 у Google Tag Manager, який його зчитує. Структура відповідає документації Google з e-commerce:
window.dataLayer = window.dataLayer || [];
dataLayer.push({ ecommerce: null }); // очищаємо попередній об'єкт ecommerce
dataLayer.push({
event: "purchase",
ecommerce: {
transaction_id: "100245", // той самий ID, що зберігає бекенд
value: 1840.00, // вирішіть: з доставкою/ПДВ чи без — і задокументуйте
currency: "UAH",
shipping: 90.00,
tax: 0,
coupon: "AUTUMN10",
items: [
{ item_id: "SKU-118", item_name: "Лляна сорочка", item_category: "Сорочки",
price: 875.00, quantity: 2, discount: 0 },
{ item_id: "SKU-402", item_name: "Ремінь", item_category: "Аксесуари",
price: 90.00, quantity: 1 }
]
}
});
Правила, що згодом економлять години:
- Спочатку
ecommerce: null. Без цього на односторінкових сайтах товари з попередньої події можуть «злитися» з наступною. - purchase — один раз. Захистіться від перезавантаження сторінки подяки, наприклад, збережіть ID транзакції в
sessionStorageі пропускайте push, якщо він уже є. GA4 теж відсіює дублікати заtransaction_id, але не покладайтеся лише на це. value— відповідно до вашого визначення. Якщо на сайтіvalueвключає доставку, а виручка в CRM — ні, розбіжність буде постійною. Запишіть, що обрали.item_id— той самий, що в каталозі товарів, щоб товарні звіти чисто з'єднувалися із собівартістю і залишками.
Повна воронка на практиці
| Крок | Подія | Де спрацьовує | Типова пастка |
|---|---|---|---|
| Перегляд списку | view_item_list | категорії, пошук | спрацьовує на кожен скрол і роздуває кількість |
| Перегляд товару | view_item | сторінка товару | у варіантів немає item_variant |
| Додавання в кошик | add_to_cart | клік або успішна відповідь API кошика | спрацьовує на клік навіть коли додавання не вдалося |
| Початок оформлення | begin_checkout | перший крок оформлення | відсутній на односторінковому оформленні |
| Доставка/оплата | add_shipping_info, add_payment_info | кроки оформлення | пропущені зовсім — і не видно, де люди відпадають |
| Покупка | purchase | підтверджена оплата | спрацьовує до оплати й рахує невдалі оплати |
| Повернення | refund | бекенд, після обробки | ніколи не надсилається — виручка в GA4 лишається завищеною |
add_to_cart — на успішну відповідь API кошика, а не на клік; purchase — на підтвердження оплати, а не на «замовлення створено». Обидві помилки роздувають воронку так, що це виглядає як справжня поведінка.
Перевірка: 20 хвилин перед кожним релізом
- Відкрийте DebugView у GA4 і ввімкніть режим налагодження (Tag Assistant або параметр
debug_mode) - Пройдіть усю воронку з реальним тестовим замовленням
- Кожна подія спрацьовує один раз, з
currency,valueі непорожнімitems transaction_idзбігається з номером замовлення в адмінці- Перезавантажте сторінку подяки — другого
purchaseнемає - Оплатіть способом із переходом на зовнішню сторінку — purchase все одно спрацьовує (або йде із сервера, див. серверний трекінг)
- Поверніть тестове замовлення — подія
refundнадходить
Перевірка SQL після запуску
Якщо ввімкнено експорт у BigQuery, порівнюйте покупки GA4 із замовленнями бекенду щодня:
WITH ga AS (
SELECT ecommerce.transaction_id AS order_id, MIN(event_date) AS day
FROM `project.analytics_123456.events_*`
WHERE _TABLE_SUFFIX BETWEEN @from AND @to AND event_name = 'purchase'
GROUP BY 1
)
SELECT o.order_date,
COUNT(*) AS backend_orders,
COUNTIF(ga.order_id IS NOT NULL) AS seen_in_ga4,
SAFE_DIVIDE(COUNTIF(ga.order_id IS NOT NULL), COUNT(*)) AS coverage
FROM clean.orders o
LEFT JOIN ga ON ga.order_id = o.order_id
WHERE o.status = 'paid' AND o.order_date BETWEEN @from_date AND @to_date
GROUP BY 1 ORDER BY 1;
Покриття нижче 100% — норма через згоду і блокувальники. Різке падіння в конкретний день зазвичай означає, що реліз зламав тег, — тому цей запит має бути в щоденному моніторингу.
Як утримати трекінг робочим після запуску
Трекінг рідко ламається в день запуску. Він ламається через три місяці, коли хтось переробляє оформлення, додає спосіб оплати чи переносить тему. Більшості таких випадків запобігають три звички:
- Додайте чекліст перевірки вище в чекліст релізу для будь-якої зміни, що зачіпає картки товарів, кошик чи оформлення.
- Щодня моніторте покриття запитом SQL вище і сповіщайте, коли воно падає більш ніж на ~10 пунктів нижче звичного рівня.
- Ведіть специфікацію трекінгу: одна таблиця з кожною подією, місцем спрацювання, параметрами і прикладом даних. Тоді розробники можуть змінювати сайт, не вгадуючи, від чого залежить аналітика.
Специфікація також прискорює роботу з новим підрядником: замість тижня розбирання контейнера GTM він за годину бачить, що і навіщо збирається.
Якщо магазин на готовій платформі
Багато платформ (Shopify, WooCommerce, Хорошоп, Prom та інші) мають вбудовані інтеграції з GA4 або плагіни. Вони заощаджують час, але перевіряйте їх так само ретельно, як власний код: чи передається transaction_id, що саме входить у value, чи не дублюється purchase, якщо паралельно стоїть ще й тег у GTM. Найчастіша проблема — дві інтеграції одночасно: вбудована і ручна.
Часті запитання
Чи можна налаштувати ecommerce GA4 без програміста?
Частково — через модулі платформи. Для надійних даних (dataLayer, дедуплікація, серверні події) зазвичай потрібно кілька годин розробника за специфікацією аналітика.
GTM чи gtag.js?
GTM зручніший для керування і тестування без релізів сайту. gtag.js простіший, якщо подій мало і розробка своя.
Чому в GA4 менше покупок, ніж у CRM?
Блокувальники реклами, відмова від cookies, оплата на сторонніх сторінках без повернення на сайт, замовлення по телефону. Детально — в окремій статті.
Чи потрібно відправляти події скасування?
Повернення — так, через refund. Скасовані до оплати замовлення простіше враховувати в CRM, а не в GA4.

