While my team and I love working with Shopify and are proud to list ourselves as Shopify Partners, we do have our gripes with their platform. This article deals with one such complaint we have about the platform: multiple “Locations” on a single Store.
When clients have a need to serve multiple markets (for us it’s usually Canada and the US), we always recommend splitting the concerns and having a specific Store per market.
The reasoning behind this is that the “Locations” options within Shopify seem to have been developed as an afterthought and, despite their most recent upgrades, the feature creates a lot of unintended problems.
In this article, we’re dealing with one very specific problem with having two “Locations” on a single Store: conversion tracking.
Disclaimer: this seems to be an unintended consequence that is absolutely affecting one of our clients but does not seem to affect all clients. There seems to be something that is affecting some Stores but not others (as indicated by the discussions on the Shopify Community Forums: https://community.shopify.com/c/extensions/issue-with-detecting-checkout-completed-event-using-web-pixel/m-p/2615185/highlight/true#M3291).
Context
Our client has one store that is serving two markets: Canada and the US. While the Canadian data is tracking just fine using the official “Google & YouTube” sales channel app, we're having issues when trying to get the US data to track.
Because Google Ads is "flying blind" on the US side, we're not able to run campaigns efficiently. Google Ads' "pmax" depends on us being able to track conversions on the website, which is the problem we've been trying to resolve.
What's Supposed to Happen:
Shopify has a "Google & YouTube" sales channel that's supposed to handle tracking using a combination of their own Shopify code and sending event data to GA4.
GA4 is then linked to Google Ads, which is then able to take in all of the data and run it through their AI to improve targeting and get better results.
What's Actually Happening:
While the Canadian side is working as intended, the US campaigns are not receiving any data when it comes to conversion numbers. As a result, we can't optimize and can't report back on progress.
At first we thought this was a problem because the data was getting mixed up in a single Google Ads account so we worked with you to create a separate USD Google Ads account (still linked to the same GA4). We hoped that this separation would help unconfuse the system.
Unfortunately, this didn't seem to help. While some conversions started showing up, it seems that less than 10% are being accurately tracked (when we compare with the data on Shopify reports and GA4 for the US market).
What We've Tried:
Without messing with the existing tracking (since Canada is working), we wanted to add tracking code to try and send conversions from the Shopify site directly into the USD Google Ads account.
The problem with this approach is that the Shopify platform keeps the checkout page "black boxed". You cannot edit the code on this page directly.
There's good reason for this setup, from a security standpoint, to prevent hackers from stealing sensitive user data, such as credit card information. Unfortunately, this limits our options for tracking checkout data.
Since we're bypassing the built-in Shopify options for Google tracking and we need to fire a conversion event from the checkout page, we need to use an advanced feature called "Customer Events" and create a "Custom Pixel".
Essentially, a "Custom Pixel" is a JavaScript snippet that runs in a sandbox that allows Shopify to control what data gets passed into your custom code.
With all of the above information, we did the following:
- Created a Conversion Event on Google Ads (USD account)
- Created a Shopify Custom Pixel
- Set the Pixel to fire the Google Ads Conversion Event when someone triggers "checkout_completed" (https://shopify.dev/docs/api/web-pixels-api/standard-events/checkout_completed)
Because there is a delay on the Google Ads side (for data privacy reasons), we waited a few days for the code above to collect some data and checked back in (to be honest, I became a little obsessed at one point and was checking every few hours).
After a few days of no data, it was apparent that something was still wrong.
We had to try something more drastic to get to the root of the issue.
I needed to speed up testing and could not rely on the Google Ads Conversion Event due to the built-in delay. I also wanted to eliminate all possible factors in my test so that I could have clear results.
Creating a Custom Test:
I decided that I would need to create our own custom snippet to be able to fully test and track down the problem.
A few key things I needed to consider ... the snippet:
- Will run on our server
- Needs to track events, in real-time, on our database so we diagnose the logs
- Cannot collect sensitive user data but needs to be able to collect a payload
- Needs to confirm if it fired successfully or not from a third-party URL (this is important)
- Should, as much as possible, emulate the way in which the Google "gtag()" function works
With the above in mind, we created a custom Drive Marketing Snippet (!) that meets all of the above requirements.
On Shopify's Custom Pixel solution, we have a few "trigger" events that we can target: https://shopify.dev/docs/api/web-pixels-api/standard-events
The one we're most interested in is the "checkout_completed", however, "product_viewed" should also be handy for testing as it should fire pretty much all the time. "payment_info_submitted" could also be interesting as clients need to enter their payment details to checkout (in case we need a fallback).
To make sure the new snippet worked, we did several tests (all of which were successful):
- We installed the snippet on a non-Shopify test server to ensure the basic code fires
- We installed the snippet on another client's Shopify Store (one without problems) to make sure it fired successfully on "checkout_completed"
- We installed the snippet on the Bench.ca Shopify Store and targeted "product_viewed"
All of the above were successful in proving that the snippet was working, recording events, and even getting payload information about products.
We then modified the code to target "checkout_completed" instead of "product_viewed" (since it would take longer to wait for someone to checkout).
A few hours went by, many confirmed orders were recorded on the Shopify "Order Reports" page, and only one order was recorded by our snippet.
We ran this test multiple times switching back and forth between "product_viewed", "payment_info_submitted", and "checkout_completed".
In all of our tests on the client’s website, it seems that the only two that don't fire properly are the "payment_info_submitted" and the "checkout_completed" events.
Code below for reference:
// Step 1. Initialize the JavaScript pixel SDK (make sure to exclude HTML) const script=document.createElement("script"); function dtag(){dtagQueue.push(arguments)}script.setAttribute("src", "https://snippet.drivelabs.ca/record.js?ver=1.3"),script.setAttribute("async", ""),document.head.appendChild(script),window.dtagQueue=window.dtagQueue||[], function t(){if("function"==typeof window.realDtag)for( ;dtagQueue.length;)window.realDtag.apply(this,dtagQueue.shift()); else setTimeout(t,50)}(); // Step 2. Subscribe to customer events with analytics.subscribe(), and add tracking // analytics.subscribe("event_name", event => { // pixel("track", "event_name", event.data); // }); analytics.subscribe("checkout_completed", event => { dtag('checkout_completed', {}); });
D'autres Shopify Partners signalent des problèmes similaires: https://community.shopify.com/c/extensions/issue-with-detecting-checkout-completed-event-using-web-pixel/m-p/2615185/highlight/true#M3291
Next Steps:
We're now fully stuck. I need help from someone over on the Shopify Plus side to help us diagnose what the underlying problem is and why their events are not firing when they're supposed to.
We’ve reached out to our client to contact their Shopify rep and we’re currently waiting to hear back. Once we have news, I’ll post an update.