Understanding Products Variable & Commerce Events in Adobe Analytics

September 3, 2020 | Kevin Haag
Understanding Products Variable & eCommerce Events in Adobe Analytics image

It's no secret that Adobe Analytics comes with very powerful commerce features. In fact, for "8 of the top 10 global internet retailers," Adobe Analytics is their digital analytics tool of choice, according to Adobe.

We’re covering some of the core principles of modern, commerce setup in Adobe Analytics. Understanding the basics will greatly benefit your overall understanding of the underlying implementation principles needed for proper commerce data in Adobe Analytics.  

The Products Variable (s.products) 

The Products Variable, also called s.products, is the fundamental dimension for commerce tracking and reporting in Adobe Analytics. It is a hit-based variable that stores contextual information about products and can be set together with both standard commerce events and custom success events. Due to its hit-level expiration, you have to set it with every success event you’d like to analyze it by.

"It is because of the correct implementation and the power of the Products Variable, that you can generate sophisticated commerce reports in Adobe Analytics"

That’s why I encourage you to try to understand the implementation fundamentals, even if you’re mostly focused on analyzing the commerce data in Adobe Analytics.

s.products follows a rigid syntax. Any deviation from this syntax might result in a broken data collection.

The variable can contain multiple products, separated by a comma. Each product within the Products Variable has a 100-byte character limit and can contain up to six predefined, product-specific fields which are separated by semicolons. 

The six products-specific fields are:

  • Category
  • Product Name (required)
  • Quantity
  • Price 
  • Events
  • eVars

"Within s.product, product-specific fields are separated by a semi-colon."

s.products = "<Category>;<Product Name>;<Quantity>;<Price>;<Events>;<eVars>"; 


<Category> is an optional field that allows you to group together your products. While this sounds like a useful feature, Adobe actually recommends against using this field due to the fact that a product can irreversibly only be associated with the first assigned category. A better way to categorize products is by using Merchandising eVars or leveraging classifications.

Product Name

The <Product Name> is the only mandatory field of the s.products string. We recommend using unique product identifiers (e.g. a product ID or a SKU) to populate this field. More user-friendly product names (e.g. "iPhone 11") usually come with whitespaces, distinct capitalization, and are not necessarily unique. Plus, the Product Name has a 100-byte character limit. Any additional characters will get truncated. So keep your Product Name short and crisp.

In our example, "iPhone11" is not a good, unique Product Name since the iPhone 11 comes in a variety of colors and different storage sizes.

You can always use Product Merchandising eVars to store a more user-friendly name. Continue reading to learn more. Alternatively, you can use classifications to upload product metadata to Adobe Analytics post data collection.

We recommend you don’t try to populate a Product Name that includes commas or semicolons. Both are reserved characters of the s.products syntax. Using them elsewhere, e.g. in the Product Name, will break your commerce tracking.

Let’s take a look at a minimum viable implementation of the Products Variable that includes only the product name:  

s.products = ";apip11bl256gb";

Our Products Variable above only contains the Product Name apip11bl256gb since we followed Adobe’s best-practices and left the Category field blank.


Traditionally the <Quantity> field stores the number of units sold.


<Price> represents the total price of all units of a single product purchased together.

It’s up to you to decide what <price> you want to report on. We most commonly see our clients use the net price of a product. Nothing prevents you from using the gross price or including per-product shipping costs, though. Just make sure you are consistent and that you document and share the method you’re using.

When implementing Price, make sure the string you send does not contain any currency symbols and uses a period as its decimal separator. As established earlier, using colons (e.g. as thousands separator) will break the Product Variable.

If we purchase two identical iPhones 11s, each one costs $1000, the correct product string looks as follows:

s.products = ";apip11bl256gb;2;2000.00"

"Adobe Analytics does not multiple Quantity x (Unit) Price to calculate the total product revenue"

This false assumption can cost you your commerce data integrity. That’s why we encourage you to carefully review the following table to avoid under-reporting your revenue numbers:

  Right Wrong
s.product s.products = ";apip11bl256gb;2;2000" s.products = ";apip11bl256gb;2;1000"
Revenue $2000.00 $1000
Units 2 2
Revenue/Unit $1000 $500


The <Events> section enables you to set product-specific, custom events. For instance, If you use the net product revenue for the <price> field, you could use a custom currency event to also store the product gross price. Events within the product string are pipe-delimited.

Going back to our example, we could store the gross product revenue in event1 (e.g. $2500) & the product-level shipping costs (e.g. $5) in event2.

The product string will then look as follows: 

s.products = ";apip11bl256gb;2;2000.00;event1=2500.00|event2=5.00"

Keep in mind that this is not the recommended place to fire your basic commerce events for viewing or purchasing a product. We’ll cover those in a bit.

Merchandising eVars

Merchandising eVars are custom conversion variables that have the merchandising feature enabled. They allow you to tie their value to a single product for a specific event.

"Merchandising eVars allow you to tie their value to a single product for a specific event."

Going back to our example, we could use Merchandising eVars to store additional product context like the brand name in eVar1 and the product color in eVar2. Similar to Events, Merchandising eVars are also pipe-delimited.

See below our final product string that includes all context data discussed in this section.

s.products = ";apip11bl256gb;2;2000.00;event1=2500.00|event2=5.00;eVar1=apple|eVar2=black"

Merchandising eVars are a great way of storing product-level context data. If you want to associate a product with metadata like a category, color, size, etc. on the implementation side-of-things (and not through classifications), Merchandising eVars are the way to go.

Commerce Events

The Products Variable stores product context. But product context by itself is not useful unless you combine it with a metric, e.g. orders. 

Adobe Analytics comes with the seven predetermined commerce events:

Interface Name Implementation Name
Product View prodView
Carts scOpen
Cart Addition scAdd
Cart Views scView
Cart Removals scRemove
Checkouts scCheckout
Orders purchase

Product Views (prodView)

Product Views are incremented, whenever a visitor views a product.

If a visitor views the iPhone 11 product detail page like the below, we set s.products together with our prodView event:

s.products together with our prodView event

s.products = ";apip11bl256gb;;;;eVar1=apple|eVar2=black"; 
s.events = "prodView";

If s.product is set without any event, Adobe Analytics will increment prodViews by one. So technically, you don’t even need to fire the prodView event.

This is only true until somebody accidentally sets the Products Variable and forgets to fire the right event with it. Therefore, it’s considered best practice to also fire a custom success event (e.g. event3) in the rule that fires the "actual" Product View. If you have full control of the implementation and you are aware of this caveat, you might not need the additional custom success event:

s.products = ";apip11bl256gb;;;;eVar1=apple|eVar2=black"; 
s.events = "prodView,event3";

Carts (scOpen)

The Carts metric is incremented by one, whenever you fire the scOpen event. The majority of commerce clients populate the Carts event upon the initial creation of a shopping cart. Commerce solutions like Adobe Commerce, previously known as Magento Commerce or Shopify typically create a cart once the visitors add their first product to it: 

s.products = ";apip11bl256gb;;;;eVar1=apple|eVar2=black"; 
s.events = "scOpen";

Cart Additions (scAdd)

Once a visitor adds the iPhone to the cart, we fire the below code, which then increments the Cart Additions metric by one:

s.products = ";apip11bl256gb;;;;eVar1=apple|eVar2=black"; 
s.events = "scAdd";

Cart Views (scView)

The Cart Views metric is incremented by one whenever a visitor views the shopping cart. 

To track Cart Views, we would fire this code:

s.products =";apip11bl256gb;;;;eVar1=apple|eVar2=black"; 
s.events = "scView";

Cart Removals (scRemove)

Once we view our cart, we also have the ability to remove products.

Removing a product results in the Cart Removals metric increasing by one.

In our implementation, we fire the below to track those cart removals.

s.products = ";apip11bl256gb;;;;eVar1=apple|eVar2=black"; 
s.events = "scRemove";

Checkouts (scCheckout)

Once a visitor initiates the checkout flow, we fire the scCheckout event together with the Products Variable

s.products = ";apip11bl256gb;;;event5=849.00;eVar1=apple|eVar2=black"; 
s.events = "scCheckout";

Pro-Tip: Starting the checkout process can be interpreted as a strong signal of purchase intent. When looking at your sales funnel visualization in the Adobe Analytics interface, you will realize that not all visitors who initiate the checkout process also end up purchasing. Understanding the dropoff rate between Checkouts & Orders is undeniably a useful insight to have.

In our example fallout visualization below, 82 percent of visitors who went through the funnel and made it all the way to checkout, did not end up placing an order.

Using and Interpreting the Adobe Analytics Fallout Visualization
· October 17, 2019

We want to take this a step further. Imagine being able to tell your boss that you could’ve made $59K more yesterday if the checkout process was less complicated?

We love generating a report like this because it helps us quantify missed revenue. It’d be false to assume that we could’ve actually realized a total revenue of $71K instead of just $12K. But over time, we will understand our baseline and are able to start initiatives that bring potential revenue and actual revenue closer together. Those initiatives could be a combination of A/B testing, ad retargeting, and email marketing (for known visitors).

All we have to do on the implementation side of things is fire the scCheckout event together with our Products Variable, which now contains a custom currency event (event5) that stores the potential revenue at checkout:

s.products = ";apip11bl256gb;;;event5=849.00;eVar1=apple|eVar2=black"; 
s.events = "event5,scCheckout";

Orders (purchase)

Let’s say I went ahead and purchased the iPhone for a price of $849.00, with product-specific shipping costs of $5.00.

In the strategy session of this fictional example, our stakeholders decided to not include the shipping costs in the standard revenue metric. Instead, the stakeholders want to be able to report on product-specific shipping costs using a custom currency event (event2) instead to keep the shipping costs separate from the net product revenue:

s.products = ";apip11bl256gb;1;849.00;event2=5.00;eVar1=apple|eVar2=black"; 
s.events = "event2,purchase";
s.purchaseID = "123456789";

The three metrics Orders, Units & Revenue all depend on the correct population of the Products Variable together with the purchase event (s.purchase) and the purchase ID (s.purchaseID).

The purchase ID is a safeguard mechanism that helps you deduplicate orders, if you accidentally send the order confirmation data multiple times. To populate the purchase ID, we recommend using a unique identifier that comes from your commerce system. For instance, you can use Order ID or Order Confirmation Number, depending on how your commerce system calls that unique identifier. If you are not sure what identifiers are available, have a friendly chat with your commerce developer.

If you miss sending a unique purchase ID, "Adobe Analytics uses information from the hit to create a temporary purchase ID."

Custom Events (event1 - event1000)

In addition to the seven pre-determined commerce events, you can really use any of the 1000 custom success events together with the Products Variable.

For instance, if you have a three-step checkout flow and you’d only stick to the basic commerce events, you’d see the dropoff between Checkout & Orders as shown earlier, but you wouldn’t understand where exactly in the checkout process most visitors drop off. 

This could be solved by firing individual events together with the Products Variable at each step of the checkout funnel.

Fire event10 once the visitor reaches the Shipping Details screen:

s.products = ";apip11bl256gb;;;;eVar1=apple|eVar2=black"; 
s.events = "event10"; // Shipping Details

Fire event11 once the visitor reaches the Payment Information screen

s.products = ";apip11bl256gb;;;;eVar1=apple|eVar2=black"; 
s.events = "event11"; // Payment Information

Fire event12 once the visitor reaches the Review Order screen:

s.products = ";apip11bl256gb;;;;eVar1=apple|eVar2=black"; 
s.events = "event12"; // Review Order

Understanding the Basics

And that’s the basics of commerce tracking in Adobe Analytics.

Let me tell you a secret—you actually don’t need as much custom code as shown in this article. But knowing the underlying logic is key to fully understanding the essentials for commerce tracking in Adobe Analytics. Thankfully, Adobe Launch, in combination with an event-driven-data-layer (EDDL), makes our implementations much easier by handling a lot of the logic through extensions.