This guide covers implementing comprehensive GA4 ecommerce tracking in CS-Cart to monitor product performance, sales funnels, revenue, and customer purchasing behavior.
Overview
GA4 ecommerce tracking captures the complete customer journey from product discovery through purchase completion. This data helps you optimize product listings, improve conversion rates, and understand revenue drivers.
Key Ecommerce Events
GA4 defines these recommended ecommerce events:
- view_item_list - Product listing pages
- select_item - Product selection from list
- view_item - Product detail pages
- add_to_cart - Adding items to cart
- remove_from_cart - Removing items from cart
- view_cart - Cart page views
- begin_checkout - Starting checkout
- add_shipping_info - Shipping method selection
- add_payment_info - Payment method selection
- purchase - Completed transactions
Implementation Methods
Method 1: Using CS-Cart Built-in Add-on (Recommended for Basic Setup)
The CS-Cart Google Analytics add-on provides automatic ecommerce tracking.
Enable Ecommerce Tracking
- Go to Add-ons → Manage add-ons
- Find Google Analytics and click the gear icon
- Enable these options:
- Enable Ecommerce tracking: Yes
- Track enhanced ecommerce: Yes
- Track product impressions: Yes
- Click Save
The add-on automatically tracks:
- Product impressions
- Product clicks
- Add to cart
- Checkout steps
- Purchases
Method 2: Custom Implementation (For Full Control)
Implement ecommerce events manually for complete customization.
Event Implementation
1. View Item List (Product Listing Pages)
Track when customers view product category or search results pages.
In category template (design/themes/[theme]/templates/views/categories/view.tpl):
{if $products}
{literal}
<script>
gtag('event', 'view_item_list', {
'item_list_id': '{/literal}{$category_data.category_id}{literal}',
'item_list_name': '{/literal}{$category_data.category|escape:javascript}{literal}',
'items': [
{/literal}
{foreach from=$products item=product name=products}
{
'item_id': '{$product.product_id}',
'item_name': '{$product.product|escape:javascript}',
'item_category': '{$category_data.category|escape:javascript}',
'price': {$product.price|default:0},
'currency': '{$currencies.$primary_currency.currency_code|default:"USD"}',
'index': {$smarty.foreach.products.iteration}
}{if !$smarty.foreach.products.last},{/if}
{/foreach}
{literal}
]
});
</script>
{/literal}
{/if}
2. Select Item (Product Click)
Track when customers click on products in listings.
// Add to product grid template
document.querySelectorAll('.ty-grid-list__item').forEach(function(item, index) {
item.addEventListener('click', function(e) {
const productId = this.dataset.productId;
const productName = this.dataset.productName;
const productPrice = this.dataset.productPrice;
const categoryName = this.dataset.categoryName;
gtag('event', 'select_item', {
'item_list_id': 'category_listing',
'item_list_name': categoryName,
'items': [{
'item_id': productId,
'item_name': productName,
'price': parseFloat(productPrice),
'index': index
}]
});
});
});
3. View Item (Product Detail Page)
Track product detail page views.
In product template (design/themes/[theme]/templates/views/products/view.tpl):
{literal}
<script>
gtag('event', 'view_item', {
'currency': '{/literal}{$currencies.$primary_currency.currency_code|default:"USD"}{literal}',
'value': {/literal}{$product.price|default:0}{literal},
'items': [{
'item_id': '{/literal}{$product.product_id}{literal}',
'item_name': '{/literal}{$product.product|escape:javascript}{literal}',
{/literal}
{if $product.main_category}
'item_category': '{$product.main_category|escape:javascript}',
{/if}
{if $product.brand}
'item_brand': '{$product.brand|escape:javascript}',
{/if}
{literal}
'price': {/literal}{$product.price|default:0}{literal},
'quantity': 1
}]
});
</script>
{/literal}
4. Add to Cart
Track when items are added to cart.
JavaScript implementation:
// Hook into CS-Cart add to cart AJAX
$(document).on('click', '.cm-submit[name="dispatch[checkout.add]"]', function(e) {
const form = $(this).closest('form');
const productId = form.find('input[name="product_id"]').val();
const productName = form.find('.product-title').text().trim();
const productPrice = parseFloat(form.find('.ty-price-num').text().replace(/[^0-9.]/g, ''));
const quantity = parseInt(form.find('input[name="product_data[' + productId + '][amount]"]').val()) || 1;
gtag('event', 'add_to_cart', {
'currency': 'USD', // Use your store currency
'value': productPrice * quantity,
'items': [{
'item_id': productId,
'item_name': productName,
'price': productPrice,
'quantity': quantity
}]
});
});
Alternative: Using CS-Cart AJAX response:
$(document).ajaxComplete(function(event, xhr, settings) {
// Check if this is an add to cart request
if (settings.url.indexOf('checkout.add') !== -1) {
try {
const response = JSON.parse(xhr.responseText);
if (response.cart_products) {
// Extract product data from response
Object.values(response.cart_products).forEach(function(product) {
gtag('event', 'add_to_cart', {
'currency': product.currency || 'USD',
'value': product.display_price * product.amount,
'items': [{
'item_id': product.product_id,
'item_name': product.product,
'price': product.display_price,
'quantity': product.amount
}]
});
});
}
} catch (e) {
console.error('Error tracking add to cart:', e);
}
}
});
5. Remove from Cart
Track cart removals.
$(document).on('click', '.ty-cart-content__delete', function() {
const cartItem = $(this).closest('.ty-cart-items__item');
const productId = cartItem.find('input[name*="cart_id"]').data('cart-id');
const productName = cartItem.find('.product-title').text().trim();
const productPrice = parseFloat(cartItem.find('.ty-price-num').text().replace(/[^0-9.]/g, ''));
const quantity = parseInt(cartItem.find('input[type="text"]').val()) || 1;
gtag('event', 'remove_from_cart', {
'currency': 'USD',
'value': productPrice * quantity,
'items': [{
'item_id': productId,
'item_name': productName,
'price': productPrice,
'quantity': quantity
}]
});
});
6. View Cart
Track cart page views.
In cart template (design/themes/[theme]/templates/views/checkout/cart.tpl):
{if $cart_products}
{literal}
<script>
gtag('event', 'view_cart', {
'currency': '{/literal}{$currencies.$primary_currency.currency_code|default:"USD"}{literal}',
'value': {/literal}{$cart.total|default:0}{literal},
'items': [
{/literal}
{foreach from=$cart_products item=product name=cart_products}
{
'item_id': '{$product.product_id}',
'item_name': '{$product.product|escape:javascript}',
'price': {$product.price|default:0},
'quantity': {$product.amount|default:1}
}{if !$smarty.foreach.cart_products.last},{/if}
{/foreach}
{literal}
]
});
</script>
{/literal}
{/if}
7. Begin Checkout
Track checkout initiation.
In checkout template (design/themes/[theme]/templates/views/checkout/checkout.tpl):
{if $cart_products && $runtime.mode == 'checkout'}
{literal}
<script>
gtag('event', 'begin_checkout', {
'currency': '{/literal}{$currencies.$primary_currency.currency_code|default:"USD"}{literal}',
'value': {/literal}{$cart.total|default:0}{literal},
'coupon': '{/literal}{$cart.applied_promotions|@key}{literal}',
'items': [
{/literal}
{foreach from=$cart_products item=product name=cart_products}
{
'item_id': '{$product.product_id}',
'item_name': '{$product.product|escape:javascript}',
'price': {$product.price|default:0},
'quantity': {$product.amount|default:1}
}{if !$smarty.foreach.cart_products.last},{/if}
{/foreach}
{literal}
]
});
</script>
{/literal}
{/if}
8. Add Shipping Info
Track shipping method selection.
// Monitor shipping method selection
$(document).on('change', 'input[name^="shipping_ids"]', function() {
const shippingMethod = $(this).closest('label').find('.ty-shipping-option__title').text().trim();
const shippingCost = parseFloat($(this).data('shipping-cost')) || 0;
gtag('event', 'add_shipping_info', {
'currency': 'USD',
'value': shippingCost,
'shipping_tier': shippingMethod
});
});
9. Add Payment Info
Track payment method selection.
// Monitor payment method selection
$(document).on('change', 'input[name="payment_id"]', function() {
const paymentMethod = $(this).closest('label').find('.ty-payment-option__title').text().trim();
gtag('event', 'add_payment_info', {
'currency': 'USD',
'payment_type': paymentMethod
});
});
10. Purchase (Transaction Completion)
The most critical ecommerce event - track completed orders.
In order confirmation template (design/themes/[theme]/templates/views/checkout/components/order_notification.tpl):
{if $order_info}
{literal}
<script>
gtag('event', 'purchase', {
'transaction_id': '{/literal}{$order_info.order_id}{literal}',
'value': {/literal}{$order_info.total|default:0}{literal},
'tax': {/literal}{$order_info.tax_subtotal|default:0}{literal},
'shipping': {/literal}{$order_info.shipping_cost|default:0}{literal},
'currency': '{/literal}{$order_info.secondary_currency|default:$order_info.currency|default:"USD"}{literal}',
'coupon': '{/literal}{$order_info.promotions|@key}{literal}',
'items': [
{/literal}
{foreach from=$order_info.products item=product name=order_products}
{
'item_id': '{$product.product_id}',
'item_name': '{$product.product|escape:javascript}',
'price': {$product.price|default:0},
'quantity': {$product.amount|default:1}
{if $product.product_options}
,'item_variant': '{foreach from=$product.product_options item=option}{$option.variant_name} {/foreach}'
{/if}
}{if !$smarty.foreach.order_products.last},{/if}
{/foreach}
{literal}
]
});
</script>
{/literal}
{/if}
Advanced Ecommerce Tracking
Product Variants
Track product options (size, color, etc.):
gtag('event', 'view_item', {
'items': [{
'item_id': '12345',
'item_name': 'T-Shirt',
'item_variant': 'Blue/Large', // Product option combination
'price': 19.99
}]
});
Product Categories Hierarchy
Include full category path:
{literal}
'item_category': '{/literal}{$product.main_category}{literal}',
'item_category2': '{/literal}{$product.subcategory}{literal}',
'item_category3': '{/literal}{$product.subsubcategory}{literal}',
{/literal}
Custom Parameters
Add CS-Cart-specific data:
gtag('event', 'purchase', {
'transaction_id': '12345',
'value': 199.99,
'items': [...],
// Custom parameters
'customer_group': 'Wholesale',
'vendor_id': '456', // For Multi-Vendor
'points_earned': 100, // If using loyalty points
'affiliate_id': '789' // If using affiliate program
});
Multi-Vendor Tracking
Track vendor attribution in Multi-Vendor marketplace:
{literal}
'items': [
{
'item_id': '{/literal}{$product.product_id}{literal}',
'item_name': '{/literal}{$product.product|escape:javascript}{literal}',
'price': {/literal}{$product.price}{literal},
'quantity': {/literal}{$product.amount}{literal},
'affiliation': '{/literal}{$product.company_name|escape:javascript}{literal}', // Vendor name
'item_brand': '{/literal}{$product.company_name|escape:javascript}{literal}'
}
]
{/literal}
Refunds and Returns
Track order refunds:
gtag('event', 'refund', {
'transaction_id': '12345',
'value': 199.99,
'currency': 'USD',
'items': [{
'item_id': 'SKU123',
'item_name': 'Product Name',
'price': 199.99,
'quantity': 1
}]
});
Partial refund:
gtag('event', 'refund', {
'transaction_id': '12345',
'items': [{
'item_id': 'SKU123', // Only refunded items
'quantity': 1
}]
});
Promotions and Coupons
Track promotion views:
gtag('event', 'view_promotion', {
'creative_name': 'Summer Sale Banner',
'creative_slot': 'homepage_hero',
'promotion_id': 'SUMMER2024',
'promotion_name': 'Summer Sale',
'items': [{
'item_id': 'SKU123',
'item_name': 'Product Name',
'discount': 20
}]
});
Track promotion clicks:
gtag('event', 'select_promotion', {
'creative_name': 'Summer Sale Banner',
'promotion_id': 'SUMMER2024',
'promotion_name': 'Summer Sale'
});
Testing Ecommerce Tracking
Using GA4 DebugView
- Enable debug mode:
gtag('config', 'G-XXXXXXXXXX', {
'debug_mode': true
});
- In GA4, navigate to Admin → DebugView
- Complete a test purchase on your store
- Verify all ecommerce events appear with correct parameters
Using Browser Console
// Monitor all ecommerce events
window.dataLayer = window.dataLayer || [];
window.dataLayer.push = function() {
console.log('DataLayer Push:', arguments);
return Array.prototype.push.apply(this, arguments);
};
Test Transaction Checklist
Complete this flow to verify tracking:
- View product category → Check
view_item_list - Click on product → Check
select_item - View product details → Check
view_item - Add to cart → Check
add_to_cart - View cart → Check
view_cart - Proceed to checkout → Check
begin_checkout - Select shipping → Check
add_shipping_info - Select payment → Check
add_payment_info - Complete order → Check
purchase
Validation
In GA4 reports (after 24-48 hours):
- Reports → Monetization → Ecommerce purchases - Verify revenue data
- Reports → Monetization → Overview - Check total revenue
- Reports → Monetization → Product performance - Verify product data
Common Issues and Solutions
Duplicate Purchase Events
Problem: Purchase event fires multiple times
Solutions:
- Only add purchase tracking to order confirmation page
- Use session storage to prevent duplicate firing:
const orderId = '12345';
if (!sessionStorage.getItem('tracked_order_' + orderId)) {
gtag('event', 'purchase', { /* ... */ });
sessionStorage.setItem('tracked_order_' + orderId, 'true');
}
Missing Transaction Data
Problem: Purchases not showing in GA4
Solutions:
- Verify transaction_id is included
- Check value and currency parameters
- Ensure items array is populated
- Verify tracking fires after order completion
Incorrect Revenue
Problem: Revenue doesn't match CS-Cart reports
Checklist:
- Include shipping costs
- Include tax
- Subtract discounts correctly
- Use correct currency
- Check for duplicate tracking
Product Data Missing
Problem: Product details not appearing in reports
Solutions:
- Verify item_id is sent consistently across all events
- Use same product ID format (product_id, not cart_id)
- Include product name in all events
- Check for encoding issues in product names
Performance Optimization
Lazy Load Ecommerce Tracking
For large product catalogs:
// Only track visible products
const observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
const product = entry.target;
// Track product impression
observer.unobserve(product);
}
});
});
document.querySelectorAll('.product-item').forEach(function(item) {
observer.observe(item);
});
Batch Product Impressions
Send impressions in batches instead of individually:
let impressionBatch = [];
function trackProductImpression(product) {
impressionBatch.push(product);
if (impressionBatch.length >= 10) {
gtag('event', 'view_item_list', {
'items': impressionBatch
});
impressionBatch = [];
}
}
Next Steps
- Event Tracking Guide - Track custom events
- GTM Implementation - Manage ecommerce tracking via GTM
- Troubleshooting - Fix tracking issues