How to Update My Post Purchase Tracking to the Latest Recommendation

Our Upsell tracking recommendations have changed in December 2023

đŸ“˜

This guide is for users on our Shopify Source. If you are not on our Shopify, following our guide to upgrade will bring your post-purchase tracking up to speed.

What's New?

In December 2023 our approach to tracking when using an upsell platform has changed. Previously we fired the dl_purchase from the upsell and then made adjustments to ensure it was not fired from the thank you page. We are changing the approach to have the dl_purchase fire from the thank you page as it does with a standard setup, but still allow you to capture the upsell purchase event from the post-purchase page!

Why did we change our approach?

  • Made the setup easier - The new recommended setup has less tag customization and no manual updates needed to your order status scripts.
  • Allows new and returning users to be captured for your purchase event when the user navigates to the thank you page. These values can impact the way you pay on affiliate platforms! Also, allows you to target new vs returning users on your advertising platform. With the previous setup, this data would never be captured.
  • The previous advanced setup is not necessary with so many destinations available for server-side setup.
  • No longer need to be concerned with the 500ms processing time on the post-purchase page.
  • Makes future updates to your Elevar Tracking much easier!

Changes you need to make

Step 1: Update your Order Status Additional Scripts

We are going to reset your Order Status Additional Scripts the unmodified version.

1. Remove your previous version of script before adding the new

In Shopify navigate to Settings, and then Select Checkout Settings. Scroll to the Order Status page section. You'll add the code as instructed below to this section.

Not sure where you code begins and ends? Looks for the comments <!-- Begin Elevar --> and <!-- End Elevar --> to mark the start and end of the scripts you'll be removing.

Not seeing the comments? You may have added our script before we begin included the comments. Here is an example of the script you are looking for. The identifiers will be different for your specific store, but use this as a guideline. If you are still not sure where your script begins and ends, send a file of your entire order status page additional scripts to our support team and we can help you out.

1. Find your script in your Elevar App

Access your Shopify Source in Elevar App.

Navigate to My Tracking and Select you Shopify Source

Select the Configure Order Status Page Step and follow the steps on this page

3. Add the new script in your Order Status Additional Scripts

Paste the code you've copied from above into the Order Status Additional Scripts.

Save your update!

Step 2: Update your Post-Purchase Additional Scripts

In Shopify navigate to Settings, and then Select Checkout Settings. Scroll to the Post-purchase page section. You'll add the code as instructed below to this section.

1. Remove any previous versions of this script before adding the new script##

The old script looks very similar to the new code below. It does not begin and end with the <!-- --> comments. If you are unclear where your script begins and ends, send a file of your entire post-purchase page additional scripts to our support team and we can help you out.

2. Add the new code with you updated GTM Container ID##

The code below pushes a dl_upsell_purchase event when a user takes an upsell or downsell offer.

Copy the script below into your Shopify post-purchase page checkout settings (shown in the previous image above). Be sure to update the GTM-xxxxx near the top of the script with your Web Container ID.

New Code:

<!-- Begin Elevar Upsell Tracking -->
<script>
// Fires an dl_upsell_purchase event when customer takes upsell offer

(function (w, d, s, l, i) {
    w[l] = w[l] || []; w[l].push({
        'gtm.start':
            new Date().getTime(), event: 'gtm.js'
    }); var f = d.getElementsByTagName(s)[0],
        j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src =
            'https://www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f);
})(window, document, 'script', 'dataLayer', 'GTM-XXX');

var upsellCount = 0;
(function() {
// EVENT HOOKS -----------------------------------------------------------
if (!Shopify.wasPostPurchasePageSeen) {
    onCheckout(window.Shopify.order, window.Shopify);
}

Shopify.on('CheckoutAmended', function (newOrder, initialOrder) {
    onCheckoutAmended(newOrder, initialOrder, window.Shopify);
});
// END EVENT HOOKS -------------------------------------------------------

// UTILS -----------------------------------------------------------------
// Function called after original order is placed, pre upsell.
function onCheckout(initialOrder, shopifyObject) {
    window.dataLayer = window.dataLayer || [];
    pushDLPurchase(initialOrder, initialOrder.lineItems, false, null, shopifyObject);
}

// Function called when upsell is taken. Separate the new/upsell
// items from the items in the initial order and then send a purchase event
// for just the new items.
function onCheckoutAmended(upsellOrder, initialOrder, shopifyObject) {
    // identify which items were added to the initial order, if any.
    upsellCount++;
    // The line item id is unique for order items, even if the items contained are the same.
    // We can use this to seperate out items from the initial order from the upsell.
    var initialItemIds = initialOrder.lineItems.map(function (line) { return line.id; });
    var addedItems = upsellOrder.lineItems.filter(
        function (line) { return initialItemIds.indexOf(line.id) < 0; }
    );
    // if no new items were added skip tracking
    if (addedItems.length === 0) return;
    pushDLPurchase(upsellOrder, addedItems, true, initialOrder, shopifyObject);
}

function pushDLPurchase(order, addedItems, isUpsell, initialOrder, shopifyObject) {
    window.dataLayer.push({
        'event': isUpsell ? 'dl_upsell_purchase' : '',
        'event_id': getOrderId(order.id, isUpsell),
        'user_properties': getUserProperties(order),
        'ecommerce': {
            'purchase': {
                'actionField': getActionField(order, isUpsell, initialOrder, addedItems, shopifyObject),
                'products': getLineItems(addedItems),
            },
            'currencyCode': order.currency,
        },
    });
}
// Returns a user properties object
function getUserProperties(data) {
    return {
        'customer_id': data.customer.id,
        'customer_email': data.customer.email,
        'customer_first_name': data.customer.firstName,
        'customer_last_name': data.customer.lastName,
        'customer_order_count': data.customer.ordersCount,
    }
}

// Gets line items in purchase
function getLineItems(lineItems) {
    return lineItems.map(function (item) {
        return {
            'category': item.product.type,
            'variant_id': item.variant.id.toString(),
            'product_id': Number(item.product.id).toString(),
            'id': item.variant.sku,
            // We don't get variant title details
            'variant': item.title,
            'name': item.title,
            'price': item.price.toString(),
            'quantity': item.quantity.toString(),
            // Not available
            // 'brand': orderItem.brand,
        }
    });
}

function getActionField(order, isUpsell, initialOrder, addedItems, shopifyObject) {
    var revenue = isUpsell ? getAdditionalRevenue(order, initialOrder) : order.totalPrice;
    var subtotal = isUpsell ? getAdditionalSubtotal(order, initialOrder) : order.subtotalPrice;
    try {
        affiliation = new URL(shopifyObject.pageUrl).hostname;
    } catch (e){
        affiliation = '';
    }
    return {
        'action': "purchase",
        'affiliation': affiliation,
        // This is the longer order id that shows in the url on an order page
        'id': getOrderId(order.id, isUpsell).toString(),
        // This should be the #1240 that shows in order page.
        'order_name': getOrderId(order.number, isUpsell).toString(),
        // This is total discount. Dollar value, not percentage
        // On the first order we can look at the discounts object. On upsells, we can't.
        // This needs to be a string.
        'discount_amount': getDiscountAmount(order, isUpsell, addedItems),
        // We can't determine shipping & tax. For the time being put the difference between subtotal and rev in shipping
        'shipping': (parseFloat(revenue) - parseFloat(subtotal)).toString(),
        'tax': '0',
        'revenue': revenue,
        'sub_total': subtotal,
    };
}

function getDiscountAmount(shopifyOrder, isUpsell, addedItems) {
    if (shopifyOrder.discounts === null || typeof shopifyOrder.discounts === 'undefined') return '0';
    if (shopifyOrder.discounts.length === 0) return '0';
    // If this isn't an upsell we can look at the discounts object.
    if (!isUpsell) {
        // Collect all the discounts on the first order.
        return shopifyOrder.discounts.reduce(function (acc, discount) {
            return acc += parseFloat(discount.amount);
        }, 0).toFixed(2).toString();
    // If this an upsell we have to look at the line item discounts
    // The discount block provided doesn't only applies to the first order.
    } else {
        return addedItems.reduce(function (acc, addedItem) {
            return acc += parseFloat(addedItem.lineLevelTotalDiscount);
        }, 0).toFixed(2).toString();
    }

}

function getOrderId(orderId, isUpsell) {
    return isUpsell ? orderId.toString() + '-US' + upsellCount.toString() : orderId;
}


function getAdditionalRevenue(newOrder, initialOrder) {
    return (parseFloat(newOrder.totalPrice) - parseFloat(initialOrder.totalPrice)).toFixed(2);
}

function getAdditionalSubtotal(newOrder, initialOrder) {
    return (parseFloat(newOrder.subtotalPrice) - parseFloat(initialOrder.subtotalPrice)).toFixed(2);
}

function test() {
    onCheckoutAmended(newOrder, initialOrder);
}

try {
    module.exports = exports = {
        onCheckoutAmended: onCheckoutAmended,
        onCheckout: onCheckout,
        resetUpsellCount: function(){upsellCount = 0;},
    };
} catch (e) { }

})();
</script>
<!-- End Elevar Upsell Tracking -->

Save your update!

Done!