Shopify GA4 Setup: Events to Check Before You Trust It
How to check view_item, add_to_cart, begin_checkout and purchase in GA4 against your Shopify orders, and find duplicate purchases, gaps and gateway referrals.
Quick answer: A Shopify GA4 setup is only trustworthy once you have tested four events on a real order: view_item, add_to_cart, begin_checkout and purchase. Each should fire once, at the right moment, with the same currency and item IDs all the way down the funnel, and the purchase should carry a unique transaction ID that you can find in Shopify. Then compare a week of GA4 purchases with Shopify orders, order by order. A purchase that is missing, counted twice under two different IDs, or credited to a payment gateway instead of the channel that earned it each leaves a different pattern in your data, and this guide shows you what to look for.
Most Shopify stores have GA4 “set up” in the sense that someone connected a property and numbers appeared. Whether those numbers are right decides whether you can use GA4 to judge a landing page, an SEO project, a Meta campaign or a Klaviyo flow.
This is a setup and reconciliation guide for whoever looks after the store and has GA4 connected. It does not explain why GA4 and Shopify Analytics differ in general, because GA4 vs Shopify Analytics already does. Here you get a test to run on a real order and a method to find which orders GA4 got wrong.
Everything below about screens, events and settings is as at 31 October 2026, read from Google’s and Shopify’s own documentation. Both change their interfaces often, so if a menu name looks different in your account, search for the setting by name.
Connected is not the same as correct
Shopify’s help centre says to install the Google & YouTube sales channel and then follow Google’s article on setting up the Google tag for Shopify. Shopify’s page says certain ecommerce events are tracked automatically, but it does not list them.
Google’s article is more specific. It names four events the app captures: view_item_list (viewing a collection), remove_from_cart, view_cart and add_shipping_info. It also says new data has been added to five events the app already collected, without naming the five. And it says disconnecting the integration in the app’s settings stops all Google Analytics data from the app, including purchase events.
Neither page promises that view_item, add_to_cart, begin_checkout and purchase all fire on your store, once each, with the right data. “Connected” describes a connection, not your data. The only way to know is to test. Two more things first:
- The key event star proves nothing. Google marks purchase as a key event by default. It marks add_to_cart, begin_checkout, view_item and a few others only when Ads personalisation is on and a Google Ads account is linked. A star tells you how Google treats an event, not that it fires.
- Use one route. Google calls connecting through the app strongly preferred, and describes a manual option for people who lack the right access or need to send data to several properties. Its page also tells you to check how to avoid duplicating tracking events, which is Step 0 below.
Here is how the four events line up. The right-hand column is Shopify’s own event for the same moment, from its developer documentation. I call it the closest match because the documentation does not say how any particular app maps one to the other.
| GA4 event | Google says it fires when a user | Closest Shopify event |
|---|---|---|
| view_item | views an item | product_viewed (visits a product details page) |
| add_to_cart | adds items to their cart | product_added_to_cart |
| begin_checkout | begins checkout | checkout_started |
| purchase | completes a purchase | checkout_completed (once per checkout, typically the Thank you page) |
Step 0: list every sender before you test
A test that finds two events firing is only useful if you can then remove one. So list everywhere your store can send GA4 data:
- The Google & YouTube app (Sales channels in Shopify admin). Check which property it is connected to.
- Customer events in Shopify settings. Shopify describes app pixels, installed through marketing and data apps, and custom pixels, added by hand. It also says custom pixels are unsupported by Shopify and run in a sandbox where not all functionality works.
- Your theme code, in case someone pasted a gtag or Google Tag Manager snippet years ago.
- A Google Tag Manager container, including any purchase tag.
- Additional scripts in checkout settings. Shopify says this section has been view-only since 28 August 2025, and that tracking on the old Thank you and Order status pages has to be recreated on the new ones. Its upgrade guide gave 26 August 2026 as the non-Plus deadline. That has passed, so check whether your purchase tracking came across.
- An old Google Analytics ID in Online Store > Preferences. Google’s Shopify migration article says to remove it once the property is connected through the app, to avoid duplicate tags.
- Other apps (reviews, upsells, subscriptions) with their own GA4 connection.
Our guides on moving tracking pixels to GA4 and Meta CAPI and the checklist for retiring old Shopify scripts cover migration. Here, the goal is one sender per event.
Set up a test you can trust
Use DebugView, not the standard reports. Google says purchase data becomes available in reports after about 24 hours, so DebugView is the immediate check. Google describes it as a stream of the events logged in the last 60 seconds and a per-minute archive for the last 30 minutes. To switch debug mode on for your own browser, use Tag Assistant or Tag Manager preview mode. You can also add debug_mode to the Google tag’s configuration, but Google says that flags all events on the page, so on a live store use Tag Assistant. Setting debug_mode to false does not turn it off, Google says; you have to remove it.
Mind consent. Google says events do not show in DebugView if privacy controls apply in the browser, or if consent mode is in place and the person has not agreed to Analytics cookies. Shopify says that in markets that require consent, such as the EEA and the UK, pixels run only after visitors grant the permissions the pixel needs, and that new pixels need Marketing and Analytics permissions by default. Run your main test with your cookie banner accepted, then repeat it declined and note what changes.
Choose how to place the order. Purchase only fires on a completed checkout. Two routes work:
- A test gateway or Shopify Payments’ test mode. Shopify says test orders do not show in payouts or reports, but also that customers cannot place live orders while your payment providers are in test mode. On a trading store that is a serious catch: pick a quiet time and switch it back straight away.
- A real order with a real provider, cancelled and refunded afterwards. Shopify notes the processor may charge fees.
Keep a log with a row per test: order number, time, device, payment method and what DebugView showed. You will use it again below.
Check the four events, one at a time
Test in the order a shopper moves. For each event look at three things: does it fire, how many times, and what is inside it.
view_item
It should fire once when a product page opens, with currency, value and an items array. Google’s developer documentation says each item needs only an item_id or item_name, and recommends sending both.
- Open one product. DebugView should show a single view_item.
- Note which identifier you send: product ID, variant ID or SKU. Shopify’s product_viewed event carries all three kinds. Pick one convention and check every later event uses it, or item-level reports cannot connect a product’s views to its sales.
- Change the variant on the page and see whether a new view_item fires. Either answer can be fine, but know which you have.
Common faults: it fires twice on load, fires on collection pages, or has no price so value is zero.
add_to_cart
It should fire once each time an item genuinely lands in the cart, with the right quantity and value. Shopify’s developer page for product_added_to_cart does not say whether quick-add buttons, cart drawers or AJAX adds are covered, so test every route a customer can use:
- the product page button
- a collection quick-add
- the plus button in the cart or drawer
- an upsell or cross-sell widget
- a “Buy it now” or dynamic checkout button, which may skip the cart
- a sold-out variant, where the add should fail and no event should fire
Common faults: the event fires when the cart page loads rather than on the click (a trigger based on the word cart in the address is the classic cause), fires for adds that did not happen, or fires with a value of zero.
begin_checkout
It should fire when a shopper enters checkout, carrying the cart’s items and any coupon. Google’s developer page says a coupon can be applied here to the whole order or to items.
Shopify’s developer page for checkout_started says that on stores using Checkout Extensibility the event fires every time a customer enters checkout, while on other stores it fires only the first time. Whether your GA4 begin_checkout copies that depends on how it is sent, so test it: enter checkout, go back to the cart, enter again, and count. This matters because Google defines the Checkouts metric as the number of times users triggered begin_checkout. If yours fires on every entry, that metric counts entries, not people, and a checkout-to-purchase rate built on it will look worse than the real one.
Test the fast routes too (Shop Pay, Apple Pay, Google Pay buttons). Shopify’s page does not say whether they trigger checkout_started on your store.
purchase
This is the event everything else leans on. Complete the order and check what arrives.
| Field | What to check | Why |
|---|---|---|
| transaction_id | Present, one per order, findable in Shopify | Google says it must be unique per order, dynamic, and free of customer-identifying data |
| value | A plain number, no currency symbol | Google’s missing-revenue help says symbols and text values break revenue reporting |
| currency | A three-letter ISO 4217 code such as AUD, at event level | Google says to set currency at event level whenever you send value |
| items | Every line, each with item_id or item_name, matching earlier events | Item-level revenue is built from item price and currency |
Decide in advance what value should include. Google’s sample code describes value as the sum of price times quantity for all items, with tax and shipping as separate fields, while Shopify’s export gives the total cost of each order. If the two are built differently, the difference is not an error. Pick one basis and compare like with like.
Then check how many times it fires:
- Reload the Thank you page, go back and forward, and open the order status link from the confirmation email later. Does a second purchase appear?
- Run an order through every payment method you offer, and note whether you land back on the Thank you page each time. Shopify says that if the page where the event should fire fails to load, the event does not fire at all.
- If you use an upsell or post-purchase app, run an order through it. Shopify says checkout_completed then fires on the first upsell offer page, and not again on the Thank you page. Anything listening only on the Thank you page can miss these orders.
Last, refunds. Google says purchase revenue is net of refunds, and its developer page describes a refund event that needs the transaction ID. If your tracking does not send refund events, a refund in Shopify will not reduce revenue in GA4, which is one reason GA4 revenue can sit above Shopify’s.
Common faults: a missing or empty transaction ID, value sent as text, no currency, a trigger on any page whose address contains the word thank, or two senders each firing one.
A quick funnel smoke test
Once each event passes alone, look at the funnel as GA4 counts it. Google’s ecommerce metrics page ties Items viewed to view_item, Add to carts to add_to_cart, Checkouts to begin_checkout, and Ecommerce purchases to the purchase event only. Use Ecommerce purchases for comparisons, not Transactions: Google says Transactions also counts other events that carry a value, such as refunds.
Pull the four numbers for one week. The one hard rule is that Ecommerce purchases should not exceed Checkouts, because every order passes through checkout. If they do, begin_checkout is probably missing on some route, such as an express button, or fires inconsistently. The other steps can legitimately invert: quick-add buttons let shoppers add to cart without viewing a product page, buttons that skip the cart push Add to carts below Checkouts, and Checkouts counts every entry, not every shopper. This is a smoke test, not a benchmark.
Reconcile GA4 purchases with Shopify orders, order by order
The weekly totals comparison in our other guide tells you whether there is a gap. This is how you find which orders make it up. Set aside an hour.
- Choose a window. Take the last full week that ended at least two days ago, given Google’s 24-hour note, and use the same dates in both tools.
- Export the Shopify orders. In Shopify admin, go to Orders, choose Export, then Orders by date. The export includes the order number (Name), created time, financial status, total, currency, source (web, draft order or POS) and cancelled time. Shopify emails exports by date to the store owner. Keep web orders. Keep cancelled ones for this check, because the purchase happened and GA4 would have seen it.
- Get the GA4 side. In GA4, open Explore and build a table with Transaction ID as the dimension and Ecommerce purchases and Purchase revenue as metrics, for the same dates. Google defines Transaction ID as an identifier you create for a transaction.
- Match the formats. Compare one Shopify order number with one GA4 transaction ID. Your DebugView test log tells you what your setup sends. They may be identical or differ by a prefix; adjust one side in a spreadsheet.
- Sort into three groups: in both, in Shopify only, in GA4 only.
- Look for a pattern in the odd ones. A random scatter points to general causes such as consent choices and blockers. A cluster points to a specific fault. Shopify’s Orders page can filter by payment method, so you can check each one.
A worked example (illustrative numbers)
These figures are made up to show the method; they are not from a real store. A store has 120 web orders in a week. GA4 shows 104 distinct transaction IDs. After matching, 100 are in both, 20 are in Shopify only and 4 are in GA4 only. Grouping the 20 missing orders by payment method:
| Payment method | Shopify orders | Missing from GA4 |
|---|---|---|
| Card | 70 | 5 (7%) |
| PayPal | 20 | 9 (45%) |
| Buy now, pay later | 20 | 5 (25%) |
| Shop Pay | 10 | 1 (10%) |
Overall, 20 of 120 orders (17%) are missing, and that figure hides the story. Nearly half of PayPal orders are missing, against 7% of card orders. That points at what happens when the shopper leaves to pay and comes back. Fixing the PayPal return would account for 9 of the 20; the card gap of 5 could be ordinary loss from consent choices and blockers. Look at the four GA4-only IDs too: test orders, date mismatches or a different ID format.
Duplicates: why two senders may not be caught
Google says Analytics deduplicates purchase events that have the same transaction ID, and that this works only for web streams. That helps, but it is narrower than it sounds:
- One sender, same ID, sent twice: GA4 merges them and reports look fine, but something is still sending twice. Count the purchase events in DebugView after a test order and remove the extra sender if there are two.
- Two senders, different IDs for the same order: GA4 cannot merge them. One might send the order number and another a long internal ID, or add a prefix. Every order now counts twice, your Ecommerce purchases come out at roughly double your Shopify orders, and the Transaction ID column shows two clearly different formats. This is the fault to look for when GA4 shows more purchases than Shopify.
- An empty ID: Google says never to send an empty string, because all purchase events with an empty ID are deduplicated together. Every order after the first disappears, and you see a huge shortfall with one row in your Transaction ID table. Google also warns that sending the same ID for different transactions can significantly undercount.
To find it, sort the Transaction ID table and look at the shape of the IDs, not only the counts. Two formats means two senders. Use your Step 0 list to find both, remove one, then place a fresh test order and confirm one purchase with the ID you expect.
Missing purchases: read the pattern
| Pattern | Likely cause | First check |
|---|---|---|
| Missing orders cluster on one payment method | Shopper pays off-site and does not reach the Thank you page; Shopify says the event does not fire if that page fails to load | Test that method end to end, including the return to your store |
| Missing orders start on one date | A change: theme, app, checkout upgrade or tracking edit | Compare the date with your change history; check Additional scripts and Customer events |
| Missing orders are upsell or post-purchase orders | The event fires on the first upsell page, not the Thank you page | Check whether your tag only listens on the Thank you page |
| Missing orders spread evenly across methods and devices | Consent choices, blockers and browser limits | See GA4 vs Shopify Analytics and judge whether the gap is steady |
| Purchases exist but revenue is zero or low | Value sent as text, a symbol in value, or no currency | Check value and currency in DebugView |
| One purchase row and far fewer than expected | Empty or reused transaction ID | Look at the Transaction ID column |
Shopify does not say that off-site payment returns fail. I am drawing that link from its statement about the page not loading, so treat the first row as a test, not a verdict.
Payment gateway referrals: when PayPal gets the credit
There is a third kind of tracking error that does not change your purchase count at all. It changes who gets the credit.
When a shopper leaves your store to pay at another site and then returns, GA4 can treat the return as a visit referred by the payment site. Google’s help article on unwanted referrals lists third-party payment processors as a typical case, where users return to your site after checkout on another domain. Google describes the Referral channel as arrivals through non-ad links on other sites, so the sale can land in Referral instead of the Meta ad, email or search result that brought the shopper in.
You may never see an error. What you see is a Referral channel with a few suspicious domains, and paid, email or organic purchases that look smaller than your other numbers suggest. We do not run ads or email, but a wrong channel on a purchase distorts the figures you use to judge both. Why Meta shows more sales than Shopify and email attribution across Klaviyo, GA4 and Shopify depend on this being right.
How to find it
In GA4’s Traffic acquisition report, set the dimension to Session source / medium, which Google defines as the source and medium that referred the user’s session. Sort by purchases or revenue and scan the rows with the medium referral. You are looking for domains that belong to a payment step: a wallet, a card processor, a PayPal-type service or a buy-now-pay-later provider. Do not copy a list from a blog post. The right list depends on which payment methods you have switched on, and your own report shows it.
How to fix it
Google’s steps for a web data stream, as at 31 October 2026:
- In Admin, under Data collection and modification, open Data streams, then Web, then your stream.
- Select Configure tag settings, then Show all, then List unwanted referrals.
- Choose a match type, enter the domain, and add more conditions if needed. Google says conditions use OR logic.
- Save. You need the Editor role or above on the property.
Google says you can set up to 50 unwanted referrals per data stream. Shopify’s older help page on excluding referrer domains, which does not say which version of Google Analytics it covers, gives paypal.com as an example of an external payment provider.
Cautions:
- Only add domains that are a payment step. An excluded domain is no longer reported as a referral source for anyone, so excluding one that also sends real shoppers hides them. If you are also trying to see visits from ChatGPT, be careful which domains you exclude; our guide to tracking ChatGPT traffic in GA4 on Shopify covers that.
- Expect some residue. Google explains that someone first referred by a domain before you excluded it can have a later direct visit credited to that domain, because of last-non-direct-click attribution. Judge the fix over weeks, not the next morning.
- Check afterwards. Google’s page does not state how long the change takes, so re-run the Session source / medium report after a week or two and confirm the payment domains have left the referral rows.
The one-page sign-off
Run through this when you set up GA4, and again after any theme update, app install, consent change or checkout change.
- Every sender is listed, with one sender per event.
- view_item, add_to_cart and begin_checkout each fire once per real action, from every route, with consistent item IDs.
- purchase fires once per order from every payment method, including upsell flows, with a unique transaction_id, a plain-number value, a currency code and matching items.
- DebugView checked with consent accepted, then declined.
- A week of Shopify web orders matched to GA4 transaction IDs, with missing orders grouped by payment method and date.
- Payment domains checked in Session source / medium and excluded where they should be.
- What sends what, and the date it was tested, written down.
A conversion test or a budget shift is a guess if purchases are doubled, halved or credited to the wrong channel. Three numbers Shopify founders watch assumes you can trust the data, and the problems in why attribution is broken on Shopify are easier to see once the plumbing is right.
Key takeaways
- Connected is not correct. Neither Shopify’s nor Google’s pages promise that the four events fire once, with the right data, on your store.
- Test one order in DebugView with consent accepted, then declined. Check how many times each event fires and what is inside it.
- The purchase needs a unique, dynamic transaction_id you can find in Shopify, a plain-number value, a three-letter currency code and matching items.
- Google deduplicates purchases that share an ID, so the duplicates that matter come from two senders with different ID formats. An empty ID collapses every order into one.
- Reconcile order by order, and group missing orders by payment method and date. The pattern points to the cause.
- Shopify says checkout_completed does not fire if its page fails to load, and fires on the first upsell page in post-purchase flows.
- Check Session source / medium for payment domains in the Referral channel, and exclude only those that are a payment step.
FAQs
Which GA4 events should a Shopify store check?
At minimum view_item, add_to_cart, begin_checkout and purchase, because they form the path from product page to order. Google’s recommended events list includes others, such as view_item_list and view_cart, but these four tell you whether purchases and revenue are recorded properly.
How do I check that my GA4 purchase event is firing correctly on Shopify?
Place a test order with debug mode on and watch DebugView. Confirm one purchase, with a transaction ID, a numeric value, a three-letter currency code and items. Then reload the Thank you page to see whether a second one appears, and repeat with each payment method you offer.
Why is my GA4 purchase event firing twice?
Most often two things are sending it, such as the Google & YouTube app plus a Google Tag Manager tag or an old script. Google deduplicates purchases with the same transaction ID, so duplicates that reach your reports usually carry different IDs. Check the Transaction ID column for two formats, then remove one sender.
Why are some Shopify orders missing from GA4?
Some gap is normal because of consent choices and browser blocking. Group the missing orders by payment method and date to see whether the gap is general or specific. Shopify says checkout_completed does not fire if the page where it should fire fails to load, so off-site payment methods are the first place to test.
How do I stop PayPal and other payment providers showing up as referrals in GA4?
Add the payment domains under List unwanted referrals in your web data stream’s tag settings, which Google lists as a typical use. Find the domains in your own Session source / medium report rather than copying a list, and expect some older attributions to linger.
Do I need Google Tag Manager for Shopify GA4 ecommerce tracking?
No. Google calls connecting through the Google & YouTube app strongly preferred and describes a manual option for particular needs. Tag Manager through a custom pixel is a more advanced path, and Shopify says custom pixels are unsupported by Shopify. Whichever you choose, use one route and test it.
Not sure your numbers are right?
Checking tracking against your real orders is how conversion work should start: the first phase of the six-phase forensic CRO audit in our Shopify CRO service is quantitative data analysis, and it includes a tracking check. If you would like a second pair of eyes first, book a free 30-minute diagnostic or tell us about your store. We share your Shopify store on screen and name two or three conversion leaks live, and tell you whether they are worth fixing. No pitch.
Free 30-min diagnostic
Seen enough?
Book a free diagnostic.
We'll identify exactly what's breaking your conversion rate and what to fix first. No pitch. No email gate. 30 minutes.
More from Prism3
Afterpay vs Zip vs Shop Pay Instalments: Shopify AU
Afterpay, Zip and Shop Pay Instalments compared for Australian Shopify stores: merchant fees, payouts, approval, checkout placement and a worked margin example.
AI-Referred Orders on Shopify: What Is Real and What Is Hype
What Shopify has disclosed about AI-referred orders, why the 13x headline needs context, how to find AI traffic in GA4 and Shopify, and what to do now.
AI Visibility Tools for Shopify: What They Measure and Miss
What AI visibility tools for Shopify stores really count: mentions, share of voice and citations, where the data is sampled or unstable, and how to use them.