Tracking in Shopify

If you want to use the revenue tracking goal (and others) within a Shopify project, you can use the following code.
Just use it in Shopify as a Customer event.

More info from Shopify's side here: https://help.shopify.com/en/manual/promoting-marketing/pixels

On this page

How to set it up

Please follow the following steps:

  1. Go to Settings > Customer Pixels
  2. Click Add Custom Pixel > Name it "ABlyft Tracking" (for example)
  3. Edit to Project ID within the code (important!)
  4. Edit the eventName on each goal if they differ from the API names in the platform
  5. Add pixel > Save > Connect it

Code to copy

/*
IMPORTANT: Edit the Project ID
*/

const projectId = 123456789; // ← Your project id

//Further options (do not change if not necessary)
const trackingCurrency  = "EUR"; // ← currency you want to track in
const useMultiCurrency  = false; // ← convert amounts if shop uses multiple currencies

const FX_RATES = {
    USD: 1.00, EUR: 1.08, GBP: 1.27, CHF: 1.10,
    SEK: 0.095, NOK: 0.089, DKK: 0.145, PLN: 0.23,
    CZK: 0.044, HUF: 0.0027, RON: 0.21, CAD: 0.75,
    AUD: 0.67, NZD: 0.60, JPY: 0.0068, CNY: 0.14,
    HKD: 0.13, SGD: 0.74, INR: 0.012, BRL: 0.20,
    ZAR: 0.052, MXN: 0.055
};

const convertCurrency = (amt, from, to) => {
    const f=from.toUpperCase(), t=to.toUpperCase();
    if(!FX_RATES[f]||!FX_RATES[t]) return amt;
    return +((amt*FX_RATES[f])/FX_RATES[t]).toFixed(2);
};

analytics.subscribe("all_events", async ({ name, data, context }) => {
    if(!name.startsWith("checkout_")) return;

    const d = document;
    const w = window;

    w.insideShopifyPixel = true;
    w.ablyftAllowIframe = true;
    let j = d.createElement("script");
    j.async = true;
    j.src = `https://cdn.ablyft.com/s/${projectId}.js`;

    j.onload = async () => {
        const url = context.window.location.href;
        const { checkout } = data;
        let events = [{ eventType:"custom", eventName:`shopify_event_${name}`}];

        if(name === "checkout_completed"){
            const { amount: rawAmount, currencyCode } = checkout.totalPrice;
            const count = checkout.lineItems.reduce((sum, {quantity}) => sum + quantity, 0);
            let revenue = rawAmount;
            if(useMultiCurrency && sourceCurrency !== trackingCurrency) {
                revenue = convertCurrency(rawAmount, sourceCurrency, trackingCurrency);
            }
            //use your own eventNames here
            events = events.concat([
                { eventType:"revenue", eventName:"revenue", eventValue: revenue },
                { eventType:"custom",  eventName:"products-count", eventValue: count },
                { eventType:"custom",  eventName:"purchase" }
            ]);
        }

        let userData = await browser.cookie.get("ablyft_uvs");
        if(!userData){
            userData = await browser.localStorage.getItem("ablyft_uvs");
        }

        const user = JSON.parse(userData);
        let visitor_type = "new";
        if (user && user.sessions && user.sessions > 1) {
            visitor_type = "returning";
        }

        const attributes = {
            device_type: w.ablyft.get("deviceType"),
            visitor_type,
            url,
            user_agent: w.navigator.userAgent
        };


        let experimentsBucketData = await browser.cookie.get("ablyft_exps")
        if(!experimentsBucketData){
            experimentsBucketData = await browser.localStorage.getItem("ablyft_exps");
        }
        if(!experimentsBucketData){
            console.log("ABlyft - Empty user bucketing - aborting");
            return;
        }
        const experimentsBucket = JSON.parse(experimentsBucketData);

        const experimentIds = Object.keys(experimentsBucket);
        let variationIds = [];
        for (let i = 0; i < experimentIds.length; i++) { variationIds.push(experimentsBucket[experimentIds[i]]); }

        function createLockId() {
            const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
            let text = "";
            for (let i = 0; i < 10; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)); }
            return text;
        }

        const goals = w.ablyft.get("goals");

        const postObj = {
            projectId: projectId,
            source: "shopify-webpixel",
            snippetVersion: 1.20,
            user: {
                attributes,
                experimentsBucket
            },
            events: events.filter(event => goals.find(goal => goal.api_name === event.eventName)).map(event => {
                const goalObject = goals.find(goal => goal.api_name === event.eventName);
                return {
                    type: event.eventType,
                    value: event.eventValue,
                    timestamp: Math.floor(Date.now() / 1000),
                    locked: Math.floor(Date.now() / 1000),
                    lockId: createLockId(),
                    goal: {
                        id: goalObject.id,
                        variations: variationIds
                    }
                };
            })
        }

        await fetch("https://log.ablyft.com", {
            method: "POST",
            mode: "no-cors",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify(postObj),
        });
    };

    d.head.appendChild(j);
});

List of events

You can use this goals by creating a custom goal and taking care that one of the following events is used as the goal's api name:

  • shopify_event_checkout_started
  • shopify_event_checkout_shipping_info_submitted
  • shopify_event_checkout_contact_info_submitted
  • shopify_event_checkout_address_info_submitted
  • shopify_event_checkout_completed (or purchase or revenue)