Conversion tracking (Pixels)

🚧

Disclaimer

You only need to change how your store tracking scripts if you use a custom tracking pixel. If you use native Shopify conversion tracking such as Google Analytics from Online Store > Preferences then it'll automatically capture events correctly on AfterSell.

The typical store setup has conversion tracking pixels setup to fire on the order status page. However, with post-purchase offers there may be scenarios where the customer doesn't reach the order status page.

For example, a customer may exit the tab on the post-purchase page (after the order has been confirmed) and they would never reach the order status page. In this example, the conversion tracking pixel on the order status page wouldn’t fire.

This section describes how to ensure that you can still track all conversions, even when using a post-purchase offer. The information in this section is important to ensure that your store’s conversion tracking infrastructure continues to work with the highest accuracy possible while using AfterSell.

Cases

There are two cases that we need to consider when thinking about conversion tracking with post-purchase offers:

  1. Customer does not see a post purchase offer. We want to track the conversion as normal on the order status page.
  2. Customer sees a post-purchase offer. As mentioned in the example above, the customer might exit the post-purchase page at any time and may never reach the order status page. Because of this, we need to capture the initial order on the post-purchase page, instead of on the order status page. We can also track the extra revenue if a customer accepts a post-purchase offer. We do not want to track anything on the order status page in this case (i.e the scripts on the order status page should not execute).

We will go through how to set up your conversion tracking scripts to cover both of these cases below.

Accessing scripts in your Shopify store

All of the code that we will go through will be added in your store’s checkout settings. The following video shows how you can access these script sections in your Shopify checkout settings:

Required updates to pixel tracking code

For simplicity, we will assume that you already have scripts that fire on the order status or understand how to do that.

Step 1: Update script for order status page

The script for the order status page will require some minor modifications. These changes are necessary to ensure that your pixels don’t accidentally track a conversion twice. We only want the conversion to be tracked on either the post-purchase page or the order status page. To prevent double-tracking, we will NOT fire the order status page scripts if the customer has seen the post-purchase page. Below is the change that you will have to make to your order status page script:

{% if first_time_accessed == true and post_purchase_page_accessed == false %}
<script>
   // ... your existing tracking code
</script>
{% endif %}

Here we added the post_purchase_page_accessed liquid variable to ensure that the event is not tracked twice.

Step 2: Add script for post-purchase page

Next we will need to add a new script that will handle all of the conversion tracking on the post-purchase page. This script has two jobs:

  1. Track the initial purchase. We must do this in case the customer exits the post-purchase page and doesn’t ever see the order status page.
  2. Track additional revenue from post-purchase upsells (optional). If you want to ensure that all revenue is tracked by your pixels, we will also need to track any additional revenue from upsell items that the customer adds to their order while on the post-purchase page.

Please note that it is not possible to track the entire order (including upsell items) all at once. Although we know that this would be simpler, it is not possible because the customer may leave the post-purchase page at any time.

Below is an example script that handles both steps. Please note that liquid code is NOT allowed in the post-purchase script. All data about the order that would normally come from liquid is instead available on the Shopify object. For a full reference on the data available from the Shopify object, visit the Shopify documentation here.

Post purchase page script:

<script async src="https://www.googletagmanager.com/gtag/js?id=G-FYNQ742HTX"></script>
<script>
(function() {
  // set up google analytics
  window.dataLayer = window.dataLayer || [];

  function gtag() {
    dataLayer.push(arguments);
  }

  gtag('js', new Date());
  gtag('config', 'G-FYNQ742HTX');

    // Step 1: Track the initial purchase
  // make sure the initial conversion isn't tracked twice
  if (!Shopify.wasPostPurchasePageSeen) {
    var order = window.Shopify.order;

    // track initial conversion
    gtag('event', 'purchase', {
      affiliation: 'My Shopify Store',
      transaction_id: Number(order.id).toString(),
      value: order.totalPrice,
      currency: order.currency,
      items: order.lineItems.map(function(item) {
        return {
          id: Number(item.id).toString(),
          name: item.title,
          category: item.product.type,
          price: item.price,
          quantity: item.quantity,
          variant: Number(item.variant.sku).toString(),
        };
      }),
    });
  }

    // Step 2: Track additional revenue from post-purchase upsells (optional)
  // set up additional conversion tracking
  Shopify.on('CheckoutAmended', function(newOrder, previousOrder) {
    // identify which items were recently added, if any
    var oldItems = previousOrder.lineItems.map(function (line) { return line.id; });

    var addedItems = newOrder.lineItems.filter(
      function (line) { return oldItems.indexOf(line.id) < 0; }
    );

    // no new items were added, so we skip conversion tracking
    if (addedItems.length === 0) {
      return;
    }

    // track additional purchase
    gtag('event', 'purchase', {
      affiliation: 'My Shopify Store',
      transaction_id: Number(order.id).toString(),
      value: order.totalPrice,
      currency: order.currency,
      items: addedItems.map(function (item) {
        return {
          id: Number(item.id).toString(),
          name: item.title,
          category: item.product.type,
          price: item.price,
          quantity: item.quantity,
          variant: Number(item.variant.sku).toString(),
        };
      }),
    });
  });
})();
</script>