Sat, May 9, 2020
UPDATED: April 2025
The original article was written on May 9, 2020, and it focused on sending data to Google Analytics Universal. However, during the migration of the blog to a new CMS, I decided to update the content to reflect the current version — Google Analytics 4.
The previous article on this blog was published almost a year ago — on July 30. It’s not that I had nothing to write about, but somehow I just never “got around” to doing it. Meanwhile, the desire to share knowledge had been building up this whole time, and at the beginning of April I finally sat down to write a new article. It’s still sitting in drafts. It can wait.
But the topic of today’s article cannot wait. In my opinion, it’s time for everyone to understand it — because this is where the future of analytics lies.
Of course, I’m talking about the new version of Google Analytics 4 and Ecommerce setup. Enough lyrical intro — let’s get to the point.
Ecommerce reports are a special group of reports in Google Analytics 4 that help evaluate the performance of online stores. While in some cases, this group of reports can be used to evaluate other types of businesses, that's a topic for another article.
A full Ecommerce setup in Google Analytics 4 lets you track the following user interactions with products on your website (listed below are the official GA4 event names and the corresponding user actions they represent):
view_item_list
— Product view in a product listselect_item
— Product click in a product listview_item
— Product detail viewadd_to_cart
— Add to cartremove_from_cart
— Remove from cartbegin_checkout
— Begin checkoutadd_shipping_info
— Add shipping infoadd_payment_info
— Add payment infopurchase
— Purchase (transaction)refund
— Refundadd_to_wishlist
— Add to wishlistview_cart
— View cart pageIn addition to product actions, you can also track banner interaction on the website:
view_promotion
— Banner or promotion viewselect_promotion
— Banner or promotion clickThe distinctive (and painful) feature of Ecommerce reports is that data for them is not collected out of the box in GA4. To get the data, marketers need to invest a lot of effort, time, and energy. This is because proper setup requires a joint understanding (between marketer and developer) of what dataLayer is and how it works in GTM.
Although many describe Ecommerce setup as a “nightmare job,” most specialists still go through this process to get the reports they need. And if you haven’t — the next section is for you.
When I first wrote a version of this material, the Ecommerce functionality in GA4 had just been introduced, and there were no built-in reports in the interface yet. There was only a notification like this:
So, back then, this section included just one remark:
“Google Analytics 4 isn’t cool because of its interface, but because it lets you send all collected data to BigQuery almost for free — and then build any custom reports based on raw data. This feature already works. The BigQuery schema has tons of fields dedicated to Ecommerce. They didn’t even all fit in the screenshot below.”
And here’s that screenshot:
But that was over five years ago. GA4 has since evolved significantly. Now you’ll find a full block of reports that work based on Ecommerce events:
Since this article focuses on setting up Ecommerce (and not analyzing the data), I’ll only highlight a few:
This is the report I recommend checking right after you configure. Ecommerce (of course, give the system some time to collect data before drawing conclusions based on just 1,000 visitors). This is where you’ll see exactly where you’re losing potential buyers:
For example, in the screenshot above, I can already see several issues:
Do you know what your own funnel conversion rates look like?
Ecommerce reports also let you dig deeper into specific problems. For example, this report helps examine where users drop off during the checkout process:
As we can see in the screenshot above, there are no issues at the shipping selection stage. However, during the payment method selection — and especially after it — we lose a significant portion of users who were almost customers.
And just to show that Ecommerce reports aren't limited to visual funnel charts only — there’s one more report. Here you’ll find detailed funnel information, but now broken down by product attributes: categories, brands, and more.
But enough about reports — let’s get back to the main topic.
Now that you’ve seen the wide range of data you can collect, let’s break down the setup process in more detail.
Setting up Ecommerce for Google Analytics 4 includes the following steps:
Note: Although we’re setting up Ecommerce for GA4, there’s no need to configure anything inside GA4 itself.
Let’s go over these steps in more detail.
This is arguably the easiest part. All you need to do is go to the official documentation page and, based on the information there, write a technical specification. In this doc, you should clearly outline each implementation step.
This event refers to viewing products in lists on your site. For example, on a “Best Deals”
or “Top Products” page.
Very often, I come across articles that state this event should be sent at the page load moment. In reality, this implementation is incorrect because at the time the page loads, the user hasn't yet seen all the products on the page. Sometimes users don’t scroll to certain lists at all, but information about them is still sent during page load. To avoid data distortion, I recommend sending the event either when the user actually views the product in the list or when they leave the page (using the browser event beforeunload
), having first saved information about which products entered the visible area of the user's screen.
Event name in GA4: view_item_list
This is the name you'll later use to find the event both in the user interface and in BigQuery.
Example code to track the event:
IMPORTANT! Each product is passed as a separate object in the items
array. In the following code examples, I’ll show only one product to shorten the article length, but the rule above applies to all code fragments.
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'event': 'view_item_list',
'ecommerce': {
'items': [
{
'item_name': 'PRO GTM', // Name or ID is required.
'item_id': '12345',
'affiliation': 'PROANALYTICS.ACADEMY',
'price': '500',
'item_brand': 'Analytics Tips',
'item_category': 'Very Good Category',
'item_category2': 'Very Good Category 2',
'item_category3': 'Very Good Category 3',
'item_category4': 'Very Good Category 4',
'item_variant': 'full',
'item_list_name': 'Hits',
'item_list_id': 'A123',
'index': 1,
'quantity': '1',
'location_id': 'ChIJIQBpAG2ahYAR_6128GcTUEo'
},
{
'item_name': 'Triblend Android T-Shirt',
'item_id': '12345',
'affiliation': 'PROANALYTICS.ACADEMY',
'price': '15.25',
'item_brand': 'Google',
'item_category': 'Apparel',
'item_category2': 'Mens',
'item_category3': 'Shirts',
'item_category4': 'Tshirts',
'item_variant': 'Gray',
'item_list_name': 'Search Results',
'item_list_id': 'SR123',
'index': 1,
'quantity': '1',
'discount': '100',
'location_id': 'ChIJIQBpAG2ahYAR_6128GcTUEo'
}
]
}
});
Parameter descriptions for this event:
Параметр | Приклад даних | Опис |
---|---|---|
event* | view_item_list | Event name. This is what you'll set the trigger on in GTM. It's better not to change the value in the example. |
item_name* | PRO GTM | Name of the product the user saw in the list. One of the most important parameters, because without the product name or ID, the request will not be accepted by analytics. |
item_id* | 12345 | ID of the product seen by the user in the list. |
price | 500 | Price of a single unit of the product seen in the list. |
item_brand | Analytics Tips | Brand of the product from the list. |
item_category | Very Good Category | Top-level category of the product in the list. |
item_category2 | Very Good Category 2 | Second level in the product category hierarchy from the list. |
item_category3 | Very Good Category 3 | Third level in the product category hierarchy from the list. |
item_category4 | Very Good Category 4 | Fourth level in the product category hierarchy from the list. |
item_category5 | Very Good Category 5 | Fifth level in the product category hierarchy from the list. |
item_variant | full | Product variant from the list. This parameter can include any additional product info: color, size, memory capacity, material type, etc. |
item_list_name | Hits | Name of the list in which the user saw the product. See examples above. |
item_list_id | A123 | Identifier of the list where the user saw the product. |
index | 1 | Product position in the list. Numbering goes from left to right and top to bottom. See screenshot above for numbering logic. |
quantity | 1 | Quantity of the product seen by the user. Usually, a user sees a product thumbnail, implying 1 unit. In that case, this parameter can be omitted. |
discount | 100 | Discount amount for the product seen in the list. Learn more about how this works here. |
affiliation | PROANALYTICS.ACADEMY | Seller/provider name offering the product. More relevant for marketplaces. |
location_id | ChIJIQBpAG2ahYAR_6128GcTUEo | Physical location of the product involved in the action (e.g., the physical store location). |
An asterisk "*" in the table indicates required parameters that you must always pass, or those that require your special attention. More details are always provided in the "Description" column of the table.
You can read more about the parameters in the official documentation.
In addition to the main parameters, you can also send up to 27 custom parameters inside the items
array.
Information about this step should be sent at the moment a user clicks on one of the items in the list.
GA4 event name: select_item
Example tracking code:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'event': 'select_item',
'ecommerce': {
'items': [
{
'item_name': 'PRO GTM', // Name or ID is required.
'item_id': '12345',
'affiliation': 'PROANALYTICS.ACADEMY',
'price': '500',
'item_brand': 'Analytics Tips',
'item_category': 'Very Good Category',
'item_category2': 'Very Good Category 2',
'item_category3': 'Very Good Category 3',
'item_category4': 'Very Good Category 4',
'item_variant': 'full',
'item_list_name': 'Hits',
'item_list_id': 'A123',
'index': 1,
'quantity': '1',
'location_id': 'ChIJIQBpAG2ahYAR_6128GcTUEo',
'discount': '100'
}]
}
});
Description of parameters that can be sent with the event:
Параметр | Приклад даних | Опис |
---|---|---|
event* | select_item | The event name. This is what you will use to trigger tags in GTM. Better not to change this value. |
item_name* | PRO GTM | Name of the item the user clicked in the list. |
item_id* | 12345 | ID of the item the user clicked in the list. |
price | 500 | Price per unit of the clicked item. |
item_brand | Analytics Tips | Brand of the item clicked from the list. |
item_category | Very Good Category | Top-level category of the clicked product. |
item_category2 | Very Good Category 2 | Second level of category hierarchy. |
item_category3 | Very Good Category 3 | Third level of category hierarchy. |
item_category4 | Very Good Category 4 | Fourth level of category hierarchy. |
item_category5 | Very Good Category 5 | Fifth level of category hierarchy. |
item_variant | full | Variant of the item clicked (e.g., color, size, memory). |
item_list_name | Hits | Name of the list where the item was clicked. |
item_list_id | A123 | ID of the list where the item was clicked. |
index | 1 | Item position in the list (left to right, top to bottom). Should match the index used for the view_item_list event. |
quantity | 1 | Quantity of the clicked item. Optional for this event. |
discount | 100 | Discount applied to the clicked item. |
affiliation | PROANALYTICS.ACADEMY | Name of the seller. For marketplaces, not the brand. Optional for single-seller shops. |
location_id | ChIJIQBpAG2ahYAR_6128GcTUEo | Physical location related to the item action (e.g., store ID). |
This event is typically sent when a user views a product detail page, usually triggered when the page loads.
GA4 event name: view_item
Example tracking code:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'event': 'view_item',
'ecommerce': {
'items': [
{
'item_name': 'PRO GTM', // Name or ID is required.
'item_id': '12345',
'affiliation': 'PROANALYTICS.ACADEMY',
'price': '500',
'item_brand': 'Analytics Tips',
'item_category': 'Very Good Category',
'item_category2': 'Very Good Category 2',
'item_category3': 'Very Good Category 3',
'item_category4': 'Very Good Category 4',
'item_variant': 'full',
'item_list_name': 'Hits',
'item_list_id': 'A123',
'index': 1,
'quantity': '1',
'location_id': 'ChIJIQBpAG2ahYAR_6128GcTUEo',
'discount': '100'
}]
}
});
Description of parameters that can be sent with the event:
Параметр | Приклад даних | Опис |
---|---|---|
event* | view_item | Event name. This is used to trigger tags in GTM. Better not to change it. |
item_name* | PRO GTM | The name of the product being viewed. One of the most important parameters — without item_name or item_id, the request will be rejected by GA4. |
item_id* | 12345 | Product ID of the item being viewed. |
price | 500 | Price per unit of the viewed item. |
item_brand | Analytics Tips | Brand of the viewed product. |
item_category | Very Good Category | Top-level category of the viewed product. |
item_category2 | Very Good Category 2 | Second level of category hierarchy. |
item_category3 | Very Good Category 3 | Third level of category hierarchy. |
item_category4 | Very Good Category 4 | The fourth highest level in the product category hierarchy for the item whose detail page is being viewed by the user. |
item_category5 | Very Good Category 5 | Fifth level of category hierarchy. |
item_variant | full | Variant of the product (e.g. color, size, memory). |
item_list_name | Hits | Name of the list where the user found the product. If the session started directly on the product page — you can pass (direct) to distinguish such cases. |
item_list_id | A123 | ID of the list where the user found the product. Same logic as with item_list_name. |
index | 1 | Product position in the list. Counted left-to-right and top-to-bottom. Same logic as above. |
quantity | 1 | Quantity. Optional for this event. |
discount | 100 | Discount applied to the viewed product. |
affiliation | PROANALYTICS.ACADEMY | Seller name. More relevant for marketplaces. |
location_id | ChIJIQBpAG2ahYAR_6128GcTUEo | The physical location of the item being interacted with (e.g., store location). It’s recommended to use a Google Place ID. |
You should send information in all cases when the user adds a product to the cart. This includes sometimes non-obvious actions such as clicking "+" on the cart page, adding a bundle of products, automatically adding an item to the cart when selecting the option to buy on credit, and so on.
Event name in GA4: add_to_cart
Example of event tracking code:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'event': 'add_to_cart',
'ecommerce': {
'items': [
{
'item_name': 'PRO GTM', // Name or ID is required.
'item_id': '12345',
'affiliation': 'PROANALYTICS.ACADEMY',
'price': '500',
'item_brand': 'Analytics Tips',
'item_category': 'Very Good Category',
'item_category2': 'Very Good Category 2',
'item_category3': 'Very Good Category 3',
'item_category4': 'Very Good Category 4',
'item_variant': 'full',
'item_list_name': 'Hits',
'item_list_id': 'A123',
'index': 1,
'quantity': '1',
'discount': '100',
'location_id': 'ChIJIQBpAG2ahYAR_6128GcTUEo',
'coupon': 'SPRING'
}]
}
});
Parameter descriptions that can be sent with the event:
Параметр | Приклад даних | Опис |
---|---|---|
event* | add_to_cart | Event name. This is what we will use to configure the trigger in GTM. It is better not to change the value in the example. |
item_name* | PRO GTM | Name of the product added to the cart. One of the most important parameters, because without product name or ID, your request will not be accepted by GA. |
item_id* | 12345 | ID of the product added to the cart. |
price | 500 | Price per unit of the product added to the cart. |
item_brand | Analytics Tips | Brand of the product added to the cart. |
item_category | Very Good Category | Highest-level category of the product added to the cart. |
item_category2 | Very Good Category 2 | Second highest level of category hierarchy for the product. |
item_category3 | Very Good Category 3 | Third highest level of category hierarchy. |
item_category4 | Very Good Category 4 | Fourth highest level of category hierarchy. |
item_category5 | Very Good Category 5 | Fifth highest level of category hierarchy. |
item_variant | full | Product variant added to the cart. You can use this field for any additional product info such as color, size, memory, material type, etc. |
item_list_name | Hits | Name of the list from which the product was added to the cart. If added from the product page, specify the list the user came from. |
item_list_id | A123 | ID of the list from which the product was added to the cart. Same notes apply as for item_list_name. |
index | 1 | Product's position in the list. Indexing is from left to right, top to bottom. Same notes as above. |
quantity | 1 | Number of items the user added to the cart. If the product was already in the cart, pass only the quantity from the last iteration. |
discount | 100 | Discount amount for the product added to the cart. |
affiliation | PROANALYTICS.ACADEMY | Name of the seller/provider. More relevant for marketplaces. |
location_id | ChIJIQBpAG2ahYAR_6128GcTUEo | Physical location associated with the product (e.g. store address). |
coupon | SPRING | You can send a coupon code used for the product added to the cart. |
We send data when a user removes items from the cart.
Event name in GA4: remove_from_cart
Example of code to track the event:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'event': 'remove_from_cart',
'ecommerce': {
'items':
{
'item_name': 'PRO GTM', // Name or ID is required.
'item_id': '12345',
'affiliation': 'PROANALYTICS.ACADEMY',
'price': '500',
'item_brand': 'Analytics Tips',
'item_category': 'Very Good Category',
'item_category2': 'Very Good Category 2',
'item_category3': 'Very Good Category 3',
'item_category4': 'Very Good Category 4',
'item_variant': 'full',
'item_list_name': 'Hits',
'item_list_id': 'A123',
'index': 1,
'quantity': '1',
'discount': '100',
'location_id': 'ChIJIQBpAG2ahYAR_6128GcTUEo',
'coupon': 'SPRING'
}]
}
});
Description of parameters you can send with the event:
Параметр | Приклад даних | Опис |
---|---|---|
event* | remove_from_cart | The name of the event. This is what we'll use to configure the trigger in GTM. It’s better not to change this value. |
item_name* | PRO GTM | The name of the item the user removed from the cart. One of the most important parameters — if missing, your request will be rejected by GA. |
item_id* | 12345 | The ID of the item the user removed from the cart. |
price | 500 | The price per unit of the item that was removed from the cart. |
item_brand | Analytics Tips | The brand of the item that was removed from the cart. |
item_category | Very Good Category | Top-level category of the item removed. |
item_category2 | Very Good Category 2 | Second level of item category hierarchy. |
item_category3 | Very Good Category 3 | Third level of item category hierarchy. |
item_category4 | Very Good Category 4 | Fourth level of item category hierarchy. |
item_category5 | Very Good Category 5 | Fifth level of item category hierarchy. |
item_variant | full | The variant of the item removed from the cart. This can include any additional product detail like color, size, memory, material type, etc. |
item_list_name | Hits | The name of the list from which the user removed the item. |
item_list_id | A123 | The ID of the list from which the user removed the item. |
index | 1 | The position of the item in the list. Numbered from left to right, top to bottom. It's important that the index matches between the display and the click. |
quantity | 1 | The quantity of the item removed from the cart. Do not send the full cart quantity — only the amount removed in the current action. |
discount | 100 | Discount applied to the item removed from the cart. |
affiliation | PROANALYTICS.ACADEMY | The seller/provider offering the product. Especially relevant for marketplaces. |
location_id | ChIJIQBpAG2ahYAR_6128GcTUEo | The physical location of the product (e.g., the store location). |
coupon | SPRING | The coupon code applied to the item that the user removed from the cart. |
It’s best to send this event when the checkout page loads, as it marks the start of the checkout process.
Event name in GA4: begin_checkout
Example of code to track the event:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'event': 'begin_checkout',
'ecommerce': {
'currency': 'USD',
'value': 30.03,
'coupon': 'SUMMER_FUN',
'items': [
{
'item_name': 'PRO GTM', // Name or ID is required.
'item_id': '12345',
'affiliation': 'PROANALYTICS.ACADEMY',
'price': '500',
'item_brand': 'Analytics Tips',
'item_category': 'Very Good Category',
'item_category2': 'Very Good Category 2',
'item_category3': 'Very Good Category 3',
'item_category4': 'Very Good Category 4',
'item_variant': 'full',
'item_list_name': 'Hits',
'item_list_id': 'A123',
'index': 1,
'quantity': '1',
'discount': '100',
'location_id': 'ChIJIQBpAG2ahYAR_6128GcTUEo',
'coupon': 'SPRING'
}]
}
});
Description of parameters you can send with the event:
Параметр | Приклад даних | Опис |
---|---|---|
event* | begin_checkout | The name of the event. This is what we'll use to configure the trigger in GTM. It’s better not to change this value. |
item_name* | PRO GTM | The name of the item that was in the user's cart when they viewed the checkout page. One of the most important parameters — if missing, your request will be rejected by GA. |
item_id* | 12345 | The ID of the item that was in the user's cart at the time of viewing the checkout page. |
price | 500 | The unit price of the item in the cart at checkout page view. |
item_brand | Analytics Tips | The brand of the item in the cart at checkout. |
item_category | Very Good Category | The highest-level category for the item that was in the user's cart at the time of viewing the checkout page. |
item_category2 | Very Good Category 2 | The second-highest category level for the item that was in the user's cart at the time of viewing the checkout page. |
item_category3 | Very Good Category 3 | The third-highest category level for the item that was in the user's cart at the time of viewing the checkout page. |
item_category4 | Very Good Category 4 | Fourth category level. |
item_category5 | Very Good Category 5 | Fifth category level. |
item_variant | full | Variant of the item (e.g., color, size, memory, material, etc.). |
item_list_name | Hits | The list from which the user added the item to cart. If the session started directly on the product page, you can send something like (direct) to differentiate from missing data. |
item_list_id | A123 | ID of the list from which the item was added. |
index | 1 | Item position in the list. Numbered left to right, top to bottom. Must match what was sent earlier. |
quantity | 1 | Number of units of the item. |
discount | 100 | Discount applied to the item. |
affiliation | PROANALYTICS.ACADEMY | Seller or provider of the item. Especially relevant for marketplaces. |
location_id | ChIJIQBpAG2ahYAR_6128GcTUEo | Physical location of the item (e.g., store). |
coupon | SPRING | Coupon code applied to the item in the cart. |
value* | 23.07 | Total cart value at the time of sending the event. Calculated as (price × quantity) for all items. Does not include taxes or shipping. |
currency* | USD | Currency code in 3-letter ISO 4217 format. |
As the name suggests, send the data at the moment the user chooses the delivery option.
Event name in GA4: add_shipping_info
Example code to track the event:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'event': 'add_shipping_info',
'ecommerce': {
'shipping_tier': 'google',
'value': 23.07,
'currency': 'USD',
'items': [
{
'item_name': 'PRO GTM', // Name or ID is required.
'item_id': '12345',
'affiliation': 'PROANALYTICS.ACADEMY',
'price': '500',
'item_brand': 'Analytics Tips',
'item_category': 'Very Good Category',
'item_category2': 'Very Good Category 2',
'item_category3': 'Very Good Category 3',
'item_category4': 'Very Good Category 4',
'item_variant': 'full',
'item_list_name': 'Hits',
'item_list_id': 'A123',
'index': 1,
'quantity': '1',
'discount': '100',
'location_id': 'ChIJIQBpAG2ahYAR_6128GcTUEo',
'coupon': 'SPRING'
}]
}
});
Description of parameters that can be sent for the event:
Параметр | Приклад даних | Опис |
---|---|---|
event* | add_shipping_info | Event name. This is what we will use to configure the trigger in GTM. It's better not to change the value in the example. |
item_name* | PRO GTM | Name of the item that was in the user’s cart at the moment of selecting the shipping method. One of the most important parameters. Without this or the item ID, the request will not be accepted by analytics. |
item_id* | 12345 | ID of the item that was in the user’s cart at the moment of selecting the shipping method. |
price | 500 | Price of a single unit of the item at the time of shipping selection. |
item_brand | Analytics Tips | Brand of the item in the cart at the time of shipping selection. |
item_category | Very Good Category | Top-level category of the item in the cart. |
item_category2 | Very Good Category 2 | Second highest category level. |
item_category3 | Very Good Category 3 | Third highest category level. |
item_category4 | Very Good Category 4 | Fourth highest category level. |
item_category5 | Very Good Category 5 | Fifth highest category level. |
item_variant | full | Variant of the item (e.g., color, size, memory, material). |
item_list_name | Hits | Name of the list where the item was added to the cart. |
item_list_id | A123 | ID of the list where the item was added to the cart. |
index | 1 | Item's position in the list. Counted left to right, top to bottom. Must match the position when the product was first displayed. |
quantity | 1 | Quantity of the item in the cart at the time of shipping selection. |
discount | 100 | Discount applied to the item in the cart at the time of shipping selection. |
affiliation | PROANALYTICS.ACADEMY | Seller or provider name (relevant for marketplaces). |
location_id | ChIJIQBpAG2ahYAR_6128GcTUEo | Physical location of the item (e.g., store). Use Google Place ID or your own location ID. |
coupon | SPRING | Coupon code applied to the item in the cart at the time of shipping selection. |
shipping_tier* | Shipping method selected by the user. | |
value* | 23.07 | Total cart value at the time of the event. Calculated as (price * quantity) for all cart items. Does not include tax or shipping costs. |
currency* | USD | Currency in 3-letter ISO 4217 format. |
As the name suggests, this event is sent when the user selects a payment method.
GA4 event name: add_payment_info
Sample code to track the event:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'event': 'add_payment_info',
'ecommerce': {
'payment_type': 'google_pay',
'value': 23.07,
'currency': 'USD',
'items': [
{
'item_name': 'PRO GTM', // Name or ID is required.
'item_id': '12345',
'affiliation': 'PROANALYTICS.ACADEMY',
'price': '500',
'item_brand': 'Analytics Tips',
'item_category': 'Very Good Category',
'item_category2': 'Very Good Category 2',
'item_category3': 'Very Good Category 3',
'item_category4': 'Very Good Category 4',
'item_variant': 'full',
'item_list_name': 'Hits',
'item_list_id': 'A123',
'index': 1,
'quantity': '1',
'discount': '100',
'location_id': 'ChIJIQBpAG2ahYAR_6128GcTUEo',
'coupon': 'SPRING'
}]
}
});
Опис параметрів, які можна надсилати для події:
Параметр | Приклад даних | Опис |
---|---|---|
event* | add_payment_info | The name of the event. This is the trigger name in GTM. It's recommended not to change this value. |
item_name* | PRO GTM | Name of the product in the cart at the moment the user selected the payment method. One of the most important parameters, as GA4 requires either the product name or ID. |
item_id* | 12345 | ID of the product in the cart when the user selected the payment method. |
price | 500 | Price per unit of the product in the cart at the moment of payment method selection. |
item_brand | Analytics Tips | Brand of the product in the cart. |
item_category | Very Good Category | Top-level category of the product in the cart. |
item_category2 | Very Good Category 2 | Second-level category of the product in the cart. |
item_category3 | Very Good Category 3 | Third-level category of the product in the cart. |
item_category4 | Very Good Category 4 | Fourth-level category of the product in the cart. |
item_category5 | Very Good Category 5 | Fifth-level category of the product in the cart. |
item_variant | full | Product variant (e.g., color, size, material). |
item_list_name | Hits | Name of the product list where the user initially added the product to the cart. |
item_list_id | A123 | ID of the product list. |
index | 1 | Position of the product in the list. Counting goes from left to right, top to bottom. |
quantity | 1 | Quantity of the product at the time of payment method selection. |
discount | 100 | Discount amount for the product at the time of payment method selection. |
affiliation | PROANALYTICS.ACADEMY | Seller/merchant name. More relevant for marketplaces. |
location_id | ChIJIQBpAG2ahYAR_6128GcTUEo | Physical location of the product (e.g., store address). |
coupon | SPRING | Coupon code used for the product at the time of payment method selection. |
payment_type* | google_pay | Selected payment method. |
value* | 23.07 | Total cart value at the time of the event. Calculated as (price * quantity) for all products. Tax and shipping are excluded. |
currency* | USD | Currency code in 3-letter ISO 4217 format. |
Send this event at the moment a transaction is completed on the website. Most often, it is triggered on the thank-you page. Keep in mind: if online payment redirects users to an acquirer page, the traffic source may be overwritten.
GA4 event name: purchase
Sample code to track the event:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'event': 'purchase',
'ecommerce': {
'transaction_id': '24T',
'value': 510,
'currency': 'USD',
'tax': 10,
'shipping': 0,
'coupon': 'free_shipping',
'items': [
{
'item_name': 'PRO GTM', // Name or ID is required.
'item_id': '12345',
'affiliation': 'PROANALYTICS.ACADEMY',
'price': '500',
'item_brand': 'Analytics Tips',
'item_category': 'Very Good Category',
'item_category2': 'Very Good Category 2',
'item_category3': 'Very Good Category 3',
'item_category4': 'Very Good Category 4',
'item_variant': 'full',
'quantity': '1',
'discount': '100',
'location_id': 'ChIJIQBpAG2ahYAR_6128GcTUEo',
'coupon': 'SPRING'
}]
}
});
Description of parameters that can be sent with the event:
Параметр | Приклад даних | Опис |
---|---|---|
event* | purchase | Name of the event. This is the trigger we’ll configure in GTM. It’s best not to change the value in the example. |
item_name* | PRO GTM | Name of the product purchased by the user. One of the most important parameters: if the product name or ID is missing, the request will be rejected by GA4. |
item_id* | 12345 | ID of the product purchased by the user. |
price | 500 | Price per unit of the purchased product. |
item_brand | Analytics Tips | Brand of the purchased product. |
item_category | Very Good Category | Top-level product category. |
item_category2 | Very Good Category 2 | Second-level product category. |
item_category3 | Very Good Category 3 | Third-level product category. |
item_category4 | Very Good Category 4 | Fourth-level product category. |
item_category5 | Very Good Category 5 | Fifth-level product category. |
item_variant | full | Product variant. This parameter can include additional info: color, size, memory, material, etc. |
item_list_name | Hits | Name of the product list where the user clicked the item. |
quantity | 1 | Number of product units. |
coupon | free_shipping | Coupon code applied to the product. |
discount | 100 | Discount value on the purchased product. |
affiliation | PROANALYTICS.ACADEMY | Seller/merchant name. More relevant for marketplaces. |
location_id | ChIJIQBpAG2ahYAR_6128GcTUEo | Physical location where the purchase action occurred (e.g., store address). |
transaction_id* | 24T | Transaction identifier. |
value* | 510 | Total cart value at the time of the event. Calculated as (price * quantity) across all products. Tax and shipping not included. |
currency* | USD | 3-letter ISO 4217 currency code. |
tax | 10 | Tax amount. |
shipping | 0 | Shipping cost. |
In addition to the core funnel events above (which were also present in Universal Analytics), GA4 introduces three more standard ecommerce events:
As the name suggests, this event is sent when a user performs a product return. Since in most cases returns are not done on the website, this information is provided more for informational purposes than for direct implementation. In practice, this event is usually sent using the Measurement Protocol.
Important: If the user cancels the entire transaction, you only need to send the transaction_id. If it's a partial refund, you must include full data about the returned item(s).
GA4 event name: refund
Sample code to track the event:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'event': 'refund',
'ecommerce': {
'items': [
{
'item_name': 'PRO GTM', // Name or ID is required.
'item_id': '12345',
'affiliation': 'PROANALYTICS.ACADEMY',
'price': '500',
'item_brand': 'Analytics Tips',
'item_category': 'Very Good Category',
'item_category2': 'Very Good Category 2',
'item_category3': 'Very Good Category 3',
'item_category4': 'Very Good Category 4',
'item_variant': 'full',
'quantity': '1',
'discount': '100',
'location_id': 'ChIJIQBpAG2ahYAR_6128GcTUEo',
'coupon': 'SPRING'
}]
}
});
Description of parameters that can be sent with the event:
Параметр | Приклад даних | Опис |
---|---|---|
event* | refund | Name of the event. This is the trigger we’ll configure in GTM. It’s best not to change the value in the example. |
item_name* | PRO GTM | Name of the product being refunded by the user. One of the most important parameters: if the product name or ID is missing, the request will be rejected by GA4. |
item_id* | 12345 | ID of the product being refunded. |
price | 500 | Price per unit of the product being refunded. |
item_brand | Analytics Tips | Brand of the refunded product. |
item_category | Very Good Category | Top-level product category of the refunded item. |
item_category2 | Very Good Category 2 | Second-level product category of the refunded item. |
item_category3 | Very Good Category 3 | Third-level product category of the refunded item. |
item_category4 | Very Good Category 4 | Fourth-level product category of the refunded item. |
item_category5 | Very Good Category 5 | Fifth-level product category of the refunded item. |
item_variant | full | Product variant being refunded. You can pass additional product info here: color, size, memory, material, etc. |
quantity | 1 | Number of units of the product being refunded. |
discount | 100 | Discount amount applied to the refunded product. |
affiliation | PROANALYTICS.ACADEMY | Seller/merchant name. More relevant for marketplaces. |
location_id | ChIJIQBpAG2ahYAR_6128GcTUEo | Physical location of the product (e.g., the store). |
coupon | SPRING | Coupon code applied to the refunded product. |
transaction_id | 24T | Transaction ID. |
value | 510 | Total value of the cart at the time the event is sent. |
currency | USD | 3-letter ISO 4217 currency code. |
tax | 10 | Tax amount. |
shipping | 0 | Shipping cost. |
This is a new standard event. It is typically sent at the moment the user adds an item to their wishlist.
GA4 event name: add_to_wishlist
Sample code to track the event:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'event': 'add_to_wishlist',
'ecommerce': {
'items': [
{
'item_name': 'PRO GTM', // Name or ID is required.
'item_id': '12345',
'affiliation': 'PROANALYTICS.ACADEMY',
'price': '500',
'item_brand': 'Analytics Tips',
'item_category': 'Very Good Category',
'item_category2': 'Very Good Category 2',
'item_category3': 'Very Good Category 3',
'item_category4': 'Very Good Category 4',
'item_variant': 'full',
'item_list_name': 'Hits',
'item_list_id': 'A123',
'index': 1,
'quantity': '1',
'discount': '100',
'location_id': 'ChIJIQBpAG2ahYAR_6128GcTUEo',
'coupon': 'SPRING'
}]
}
});
Description of parameters that can be sent with the event:
Параметр | Приклад даних | Опис |
---|---|---|
event* | add_to_wishlist | Event name. This is the trigger we'll configure in GTM. It’s best not to change the value in the example. |
item_name* | PRO GTM | Name of the product that was added to the wishlist. One of the most important parameters: if the product name or ID is missing, the request will be rejected by GA4. |
item_id* | 12345 | ID of the product that was added to the wishlist. |
price | 500 | Price per unit of the product added to the wishlist. |
item_brand | Analytics Tips | Brand of the product added to the wishlist. |
item_category | Very Good Category | Top-level product category of the item added to the wishlist. |
item_category2 | Very Good Category 2 | Second-level product category of the item added to the wishlist. |
item_category3 | Very Good Category 3 | Third-level product category of the item added to the wishlist. |
item_category4 | Very Good Category 4 | Fourth-level product category of the item added to the wishlist. |
item_category5 | Very Good Category 5 | Fifth-level product category of the item added to the wishlist. |
item_variant | full | Variant of the product added to the wishlist. You can pass any additional product information here: color, size, memory, material type, etc. |
item_list_name | Hits | Name of the list from which the user added the product to the wishlist. |
item_list_id | A123 | ID of the list from which the user added the product to the wishlist. |
index | 1 | Product’s position in the list. Counting starts from left to right and top to bottom. The index at the time of the product view and at the time of click should match. |
quantity | 1 | Quantity of the item. For the wishlist event, this parameter is optional. |
affiliation | PROANALYTICS.ACADEMY | Seller/merchant name. More relevant for marketplaces. |
location_id | ChIJIQBpAG2ahYAR_6128GcTUEo | Physical location of the product (e.g., the store). |
This is also a new standard event introduced with GA4. It should be sent at the moment the user views the cart page.
GA4 event name: view_cart
Sample code to track the event:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'event': 'view_cart',
'ecommerce': {
'items': [
{
'item_name': 'PRO GTM', // Name or ID is required.
'item_id': '12345',
'affiliation': 'PROANALYTICS.ACADEMY',
'price': '500',
'item_brand': 'Analytics Tips',
'item_category': 'Very Good Category',
'item_category2': 'Very Good Category 2',
'item_category3': 'Very Good Category 3',
'item_category4': 'Very Good Category 4',
'item_variant': 'full',
'item_list_name': 'Hits',
'item_list_id': 'A123',
'index': 1,
'quantity': '1',
'discount': '100',
'location_id': 'ChIJIQBpAG2ahYAR_6128GcTUEo',
'coupon': 'SPRING'
}]
}
});
Description of parameters that can be sent with the event:
Параметр | Приклад даних | Опис |
---|---|---|
event* | view_cart | Event name. This is the trigger we'll configure in GTM. It’s best not to change the value in the example. |
item_name* | PRO GTM | Name of the product that was in the user’s cart at the moment they viewed the cart page. One of the most important parameters: if the product name or ID is missing, the request will be rejected by GA4. |
item_id* | 12345 | ID of the product that was in the cart when the user viewed the cart page. |
price | 500 | Price per unit of the product in the cart at the time of the cart page view. |
item_brand | Analytics Tips | Brand of the product in the cart at the time of the cart page view. |
item_category | Very Good Category | Top-level product category of the item in the cart. |
item_category2 | Very Good Category 2 | Second-level category of the item in the cart. |
item_category3 | Very Good Category 3 | Third-level category of the item in the cart. |
item_category4 | Very Good Category 4 | Fourth-level category of the item in the cart. |
item_category5 | Very Good Category 5 | Fifth-level category of the item in the cart. |
item_variant | full | Product variant in the cart. You can pass any additional product information here: color, size, memory, material type, etc. |
item_list_name | Hits | Name of the list from which the product was added to the cart. |
item_list_id | A123 | ID of the list from which the product was added to the cart. |
index | 1 | Product’s position in the list. Counting starts from left to right and top to bottom. The index at the time of product view and at the time of click should match. |
quantity | 1 | Number of items in the cart at the time of the cart page view. |
discount | 100 | Discount amount applied to the item in the cart. |
affiliation | PROANALYTICS.ACADEMY | Seller/merchant name. More relevant for marketplaces. |
location_id | ChIJIQBpAG2ahYAR_6128GcTUEo | Physical location of the product (e.g., store address). |
coupon | SPRING | Coupon code applied to the product in the cart at the time of cart page view. |
In the previous section, we covered each event in detail, which should help minimize the number of implementation errors. However, based on my experience, it's nearly impossible to eliminate them entirely. Therefore, it’s important to carefully check each event after the developer has implemented the technical specification (TS).
Since this article is already quite long, if you're interested in learning how to effectively conduct such testing, let me know in the comments and I’ll prepare a separate guide.
Once the TS is written and implemented by the developer — and you’ve (VERY IMPORTANT) verified the implementation — it’s time for the final step: configuring everything in GTM.
Back when GA4 Ecommerce was just starting, it required a lot of setup to begin collecting data. Fortunately, the process has become much simpler. Now, you only need to create one trigger and one tag.
Trigger settings should look like this:
In the event_name
field, list all necessary Ecommerce events using a regular expression. Here’s the full list, though you can include only the events you actually need:
^(view_item_list|select_item|view_item|add_to_cart|remove_from_cart|begin_checkout|add_shipping_info|add_payment_info|purchase|refund|add_to_wishlist|view_cart|view_promotion|select_promotion)$
And don’t forget to enable the Use regex matching toggle.
Tag settings are also quite straightforward.
Select the Google Analytics: GA4 Event tag type and specify your Measurement ID.
In the Event Name field, choose the variable {{Event}}
, and enable the toggle Send Ecommerce data in the More Settings -> Ecommerce section.
That’s it! Just don’t forget to publish your Google Tag Manager version.
This section (and everything beyond) is now outdated and is included mainly for historical reference. If you found this article helpful, let me know in the comments.
Of course, writing a TS, waiting for implementation, and only then setting up and collecting data is a solid strategy. But what if you want to start collecting data right now?
First, check whether Enhanced Ecommerce is already set up on your site, and whether it's done via GTM.
If so — lucky you! Setting up GA4 Ecommerce based on those data will take just a few minutes.
Let’s get started.
To configure this setup, you'll need:
Here’s a screenshot with the full list of what needs to be created:
This part is simple — nothing new. You’ll need a Data Layer Variable with the following settings:
Note: in the Data Layer Version field, be sure to select Version 1
.
This variable adds a bit of magic: based on the dataLayer values, the script determines which event should be passed to GA4 Ecommerce.
Use a Custom JavaScript Variable with the following code:
function() {
var event;
var ecom = {{DL - ecommerce}};
var keys = Object.keys(ecom);
action = keys[0];
switch(true) {
case "detail" in ecom:
event = "view_item";
break;
case "add" in ecom:
event = "add_to_cart";
break;
case "remove" in ecom:
event = "remove_from_cart";
break;
case "checkout" in ecom && ecom.checkout.actionField.step == 1:
event = "begin_checkout";
break;
case "purchase" in ecom:
event = "purchase";
break;
default:
event = false;
}
return event;
}
IMPORTANT! If you renamed the variable from section 1, make sure to replace {{DL - ecommerce}}
with your variable’s name in the code above.
Here’s where the main transformation happens — this variable converts the legacy Enhanced Ecommerce data format to GA4. Use another Custom JavaScript Variable with the following code:
function() {
var items = [];
var ecom = {{DL - ecommerce}};
var keys = Object.keys(ecom);
var action = keys[0];
prod_tr = function(products, list) {
awProduct = []
products.forEach(function(item, i, products) {
o = {};
o.item_name = item.name;
o.item_id = item.id;
o.price = item.price;
o.item_brand = item.brand;
o.item_category = item.category.split("/")[0];
o.item_category2 = item.category.split("/")[1];
o.item_category3 = item.category.split("/")[2];
o.item_category4 = item.category.split("/")[3];
o.item_category5 = item.category.split("/")[4];
o.item_variant = item.variant;
o.item_list_name = list;
o.quantity = item.quantity;
awProduct[i] = o;
return awProduct;
});
return awProduct
}
switch(true) {
case "detail" in ecom:
list = ecom.detail.actionField ? ecom.detail.actionField.list : "";
prod = ecom.detail.products;
items = prod_tr(prod, list);
break;
case "add" in ecom:
list = ecom.add.actionField ? ecom.add.actionField.list : "";
prod = ecom.add.products;
items = prod_tr(prod, list);
break;
case "remove" in ecom:
list = ecom.remove.actionField ? ecom.remove.actionField.list : "";
prod = ecom.remove.products;
items = prod_tr(prod, list);
break;
case "checkout" in ecom && ecom.checkout.actionField.step == 1:
prod = ecom.checkout.products;
items = prod_tr(prod);
break;
case "purchase" in ecom:
prod = ecom.purchase.products;
items = prod_tr(prod);
break;
}
return items;
}
Again, if you renamed the variable in step 1, update its name in this code.
This tag sends data for events such as product detail views, add/remove from cart, and beginning checkout.
IMPORTANT! You’ll likely need to tweak the triggers for your website setup. Specify all triggers that push the following events into dataLayer: view product, add/remove from cart, begin checkout.
In my case, adding and removing items from the cart occurs at the moment when the addToCart
and removeFromCart
events are pushed to the dataLayer
. Therefore, the triggers for them look like this:
As for the product detail page and the checkout page, in my case, the data is pushed to the dataLayer upon page load. Therefore, I use the following trigger:
Don't forget to specify an additional condition, as shown in the screenshot, for the pageview tag. Otherwise, undefined events might be sent during the views of pages other than product details and checkout.
Equally important! In my setup, there is an additional parameter called debug_mode
. You are not required to use it. It is intended to help you verify whether the data is being sent correctly. When debug mode is enabled, you will be able to see your events in the DebugView tab.
Since you'll need to pass additional data with the transaction, it's better to create a separate tag.
Again, you may need to slightly adjust the triggers depending on your site's implementation. I use the following:
affiliation
information:IMPORTANT! At the time of writing this article, I haven’t found official documentation specifying which parameters should be used to pass id
, revenue
, and affiliation
. In the current implementation, I send them as event parameters, which seem to be the most logical choice. Once official information becomes available, this part may need to be updated.
That’s it — setup is complete. The only thing left is to publish the changes.
As I mentioned earlier, to verify that everything is working correctly, you can use the DebugView mode. However, it will only show the event itself without any additional data, such as product details.
Another method is to open the Network tab in your browser’s developer tools and look for the relevant request. You can search using the keyword collect
. Then, select the requests that use version 2 of the measurement protocol (v=2
).
You can decode and convert the data into a readable format using any online decoder — for example, this one.
Google Analytics 4 is a great tool, and with the official support for Ecommerce (instead of the workarounds we had before), it's going to become even more popular. Feel free to leave your questions about GA4 or share ideas on how this guide could be improved in the comments.
If you enjoyed this content, subscribe to my LinkedIn page.
I also run a LinkedIn newsletter with fresh analytics updates every two weeks — here’s the link to join.
Web Analyst, Marketer