eCommerce Tracking not Working? dataLayer Showing the correct information

I’ve set up a dataLayer push event within Piwik Pro Tag manage with the below code. When I use debug mode I can see that it is firing an event with the dataLayer populating with the right information but it’s not coming through within eCommerce tracking in Piwik Pro.

What is going wrong?

Code within Tag Manager that fires on Order Confirmation page:

<script>
  
    purchaseOrder = dataLayer.find(function(obj){return obj.Reference});
  
    if(purchaseOrder){
      orderItemCount =  purchaseOrder.OrderItems.length;
      itemsArray = [];
      totalDiscount = 0;
      
      for (i = 0; i < orderItemCount; i++) {
        orderItem = purchaseOrder.OrderItems[i];
        itemsArray[i] = {
            'sku':orderItem.OrderItemID,
            'name': orderItem.Title,
            'price': orderItem.PricePaid.Value,
            'quantity':1,
            'category':orderItem.Product.ProductType.Name,
        };    
      
      }

    orderValue = purchaseOrder.TotalPrice.Value;

    if(orderValue && totalDiscount<=orderValue){
        orderValue -= totalDiscount;
    }

    dataLayer.push({
     'event': 'ecommerceOrder',
     'ecommerceOrder': {
          'orderId':purchaseOrder.Reference,
          'grandTotal': orderValue,
          'tax': purchaseOrder.TotalVat.Value,
          'shipping': purchaseOrder.DeliveryCost,
          'discount': purchaseOrder.TotalAmountDiscounted,
          'products': itemsArray
     }
     });
    }
    </script>

Event in Event Log:
image

dataLayer for Event:
image

Hi,
Have you followed this article while creating your ecommerce setup? Set up ecommerce tracking | Piwik PRO help center

What I am missing here are ecommerce paq.push methods which handle the data layer data which you set up and forward it to your analytics reports.

You can find more information about paq.push methods here: API — Piwik PRO Analytics Suite 17.4 documentation

You can set the methods up in our Tag Manager.

Thanks for getting back to me asenior.

I thought that a dataLayer.push event would pass that information through - I didn’t realise it needed to be _pag.push - I have come across that before.

So from that article I can see that it needs to be a simplified version of what I stated above - how do I reference an array with _paq.push? To fill in the products section, how do I create the array?

Below is what I have got so far but that isn’t an array it will just fill it out once.

_paq.push([
    "ecommerceOrder",
    [
        {
            sku: orderItem.OrderItemID,
            name: orderItem.Title,
            category: orderItem.Product.ProductType.Name,
            price: orderItem.PricePaid.Value,
            quantity: 1,
        },
        
    ],
    {
        orderId: purchaseOrder.Reference,
        grandTotal: orderValue,
        tax: purchaseOrder.TotalVat.Value,
        shipping: purchaseOrder.DeliveryCost,
        discount: purchaseOrder.TotalAmountDiscounted
    }
]);

Let me know if I understood you correctly. You want to change your datalayer.push method to paq.push and you are not sure how you would be able to access the products array? If so, it would actually be recommended to store the array in the data layer and handle it through the ecommerce paq.push methods. So, you do not have to replace your data layer method with paq.push here and you should set up the both methods.

Thanks asinior.

I’m not sure on next steps. I have the dataLayer firing the correct information by the looks of it but it isn’t passing through to Piwik. You mentioned that I need to utilise _paq.push but I don’t know how to do this.

What do I need to write to get the paq.push to pass information to Piwik Analytics?

What about this:

I have a dataLayer event for GA3 which pushes data to the “ecommerce” dataLayer

I have written the paq.push below for Piwik that references that dataLayer:

_paq.push([
  "ecommerceOrder",
  [
      {'products': ecommerce.items
}]
[{ 
          'orderId':ecommerce.transaction_id,
          'grandTotal': ecommerce.value,
          'tax': ecommerce.tax,
          'shipping': ecommerce.shipping,
  }]
])

Will that work?

Nope, that hasn’t worked.

Could you please provide me with a URL of the website? You can send it here or via private message if you prefer to. I am going to take a look at the ecommerce setup and maybe come up with some solution.

Hi,

most GA3 dataLayers have id and name for a product but no sku. It might be necessary to re-map products for that reason in order to have all required attributes. Did you check that?

best,
Markus

Thanks asinior, really appreciate that.

Website is www.instantprint.co.uk

I can confirm what Markus said that it might seem like there is a sku parameter missing, at least in the paq.push method, could you please investigate that?

The full list of required arguments for an ecommerceOrder method can be found here:
(API — Piwik PRO Analytics Suite 17.4 documentation) and you will find an example on how the methods should be structured and what arguments to use in the ecommerce setup there.

Thanks for the reply chaps.

Within the ecommerce entry on the dataLayer ecommerce.items is the GA3 array and as you rightly point out it’s not mapped to the field names that Piwik requires.

If my ecommerce.items array looks like this:

{
  "event": "purchase",
  "ecommerce": {
    "transaction_id": "web2666671-1",
    "value": 16.25,
    "tax": 2.71,
    "shipping": 4.99,
    "currency": "GBP",
    "coupon": null,
    "items": [
      {
        "item_id": "93b7bf39-f428-40cf-8245-d862939344a9",
        "item_name": "85 x 55 mm Business Cards",
        "currency": "GBP",
        "price": 11.26,
        "coupon": null,
        "quantity": 1,
        "discount": 0,
        "index": 0,
        "item_category": "Business Cards",
        "item_list_name": "Business Cards"
      }
    ]
  },
  "gtm.uniqueEventId": 31
}

Then how do I update my _paq.push to remap the GA3 values to the Piwik ones?

Here is my current paq.push:

_paq.push([
  "ecommerceOrder",
  [
      {'products': ecommerce.items
}]
[{ 
          'orderId':ecommerce.transaction_id,
          'grandTotal': ecommerce.value,
          'tax': ecommerce.tax,
          'shipping': ecommerce.shipping,
  }]
])

Hi,

add a function like this to your code. It (hopefully) converts any GA4 “items” or UA “products” payload to the format needed for Piwik PRO.

//map GA4 items or UA products tp PP format 
  function makePPitems(products) {
    if (!Array.isArray(products)) {
      return [];
    }
    var rsItems = products.map(function(prod) {
      var prodObj = new Object();
      prodObj.name = prod.name||prod.item_name;
      prodObj.sku  = prod.sku||prod.id||prod.item_id||prodObj.name;
      prodObj.brand = prod.brand||prod.item_brand||"";
      prodObj.variant = prod.variant||prod.item_variant||"";
      prodObj.price = prod.price||prod.item_price;
      if (prod.quantity) prodObj.quantity = prod.quantity;

      //build category list
      var additionalCategoriesPresent = (prod.item_category2+prod.item_category3+ 
                                        prod.item_category4+prod.item_category5).length > 0; 
     
      var cat = prod.category||prod.item_category;
      
      if (additionalCategoriesPresent && typeof(cat) === "string") {
        cat = [cat];
        //yes, this is not elegant. Feel free to improve it anytime ;) 
        if (cat.length < 5 && prod.item_category2) 
          cat.push(prod.item_category2);
        if (cat.length < 5 && prod.item_category3) 
          cat.push(prod.item_category3);
        if (cat.length < 5 && prod.item_category4) 
          cat.push(prod.item_category4);
        if (cat.length < 5 && prod.item_category5) 
          cat.push(prod.item_category5);
      }
      prodObj.category = cat;
      if (prodObj.sku)
        return prodObj;
      else return;
    })
    return rsItems;
  }

it looks for specific attributes and remaps them into a new object product by product. If no sku can be found, it uses the name as fallback value.

As “ecommerce” seems to point to a dataLayer variable that gives you access to the items array, replacing

'products': ecommerce.items

with

'products': makePPitems(ecommerce.items)

shoud do the trick. Let me know if this solved your problem,

best,
Markus

Thanks so much for getting back to me.

I’ve just posted the new code like this:

<script> 

//map GA4 items or UA products tp PP format 
  function makePPitems(products) {
    if (!Array.isArray(products)) {
      return [];
    }
    var rsItems = products.map(function(prod) {
      var prodObj = new Object();
      prodObj.name = prod.name||prod.item_name;
      prodObj.sku  = prod.sku||prod.id||prod.item_id||prodObj.name;
      prodObj.brand = prod.brand||prod.item_brand||"";
      prodObj.variant = prod.variant||prod.item_variant||"";
      prodObj.price = prod.price||prod.item_price;
      if (prod.quantity) prodObj.quantity = prod.quantity;

      //build category list
      var additionalCategoriesPresent = (prod.item_category2+prod.item_category3+ 
                                        prod.item_category4+prod.item_category5).length > 0; 
     
      var cat = prod.category||prod.item_category;
      
      if (additionalCategoriesPresent && typeof(cat) === "string") {
        cat = [cat];
        //yes, this is not elegant. Feel free to improve it anytime ;) 
        if (cat.length < 5 && prod.item_category2) 
          cat.push(prod.item_category2);
        if (cat.length < 5 && prod.item_category3) 
          cat.push(prod.item_category3);
        if (cat.length < 5 && prod.item_category4) 
          cat.push(prod.item_category4);
        if (cat.length < 5 && prod.item_category5) 
          cat.push(prod.item_category5);
      }
      prodObj.category = cat;
      if (prodObj.sku)
        return prodObj;
      else return;
    })
    return rsItems;
  }

  
  _paq.push([
  "ecommerceOrder",
  [
      {'products': makePPitems(ecommerce.items)
}]
[{ 
          'orderId':ecommerce.transaction_id,
          'grandTotal': ecommerce.value,
          'tax': ecommerce.tax,
          'shipping': ecommerce.shipping,
  }]
])</script>

Is this what you mean?

Yes, even if I still do not get how and where variables like ecommerce.items are defined and get their values.

If there is a dataLayer variable that is called “ecommerce” in GTM and it points to the “ecommerce” key in the dataLayer, you should reference it in tag code with {{ecommerce}}.

Do you have a dataLayer variable like this?

Hi all, I have redone the tag that we are trying to use for this to the below.

<script> 
  var piwikOrderItems = [];
    for (var i = 0, l = purchaseOrder.OrderItems.length; i < l; i++) {
      var orderItemIn = purchaseOrder.OrderItems[i];
    var prodObj = new Object();
        prodObj.name = orderItemIn.Title;
        prodObj.sku  = orderItemIn.ProductID;
        prodObj.brand = "";
        prodObj.variant = "";

    piwikOrderItems.push(prodObj)
  }

  var _paq = window._paq || [];
  
    _paq.push([
      "ecommerceOrder",
      [piwikOrderItems],
      {
          orderId: purchaseOrder.OrderID,
          grandTotal: purchaseOrder.TotalPrice.Value,
          subTotal: purchaseOrder.TotalPriceOfItems.Value,
          tax: purchaseOrder.TotalVat.Value,
          shipping: purchaseOrder.Delivery.DeliveryCharge.Value
      }
  ])
</script>

This does not throw any errors and i can see a call going out from our site to piwik, with the data being built from our orders on it. It is getting a 202 response from piwik. However, this data still does not appear anywhere within our dashboard.

an example page that this code is firing on can be found at

any insights you can provide would be greatly appreciated.
Ross.

FYI Ross works with myself as a developer - I’ve get him involved as the JS is beyond me.

I see that “purchaseOrder” seems to be defined when I look at the console on that page, so it basically should work, even if you now are only passing name and sku for products and skip other attributes like quantity and price.

I can see a hit being dispatched:

… and it looks strange because there is no action name - both here and in your page view hit before that as well. I assume you get no pageview for that URL when testing as well? Are you initializing Piwik PRO with a custom tage title that is broken somehow? Maybe this is holding your requests back from being processed correctly.

1 Like

We do seem to be getting pageviews for that page through but not this tag.

I can’t see any errors in the tag which is loading in there was another error being thrown by a different tag but i have resolved that now so it should no longer interfere if that was the issue.

Hi all,

I’ve just finished reviewing and fixing the tag with ecommerce functionality. The main reason of its failure was wrong type of some paremeters. I change the code to follow our Solution Templates and made sure that parameters types are proper. Wrong parameters type is the most common issue, so please always make sure that they match requirements from our documentation.

Have a nice day!

1 Like