Google Tag Manager Checkout & Purchase Page Not Working(Reformation Theme)

Topic summary

Main issue: Implementing GA4 (Google Analytics 4) via Shopify Custom Pixel + GTM (Google Tag Manager). In Shopify’s Test mode, checkout pushes appear as a raw checkout object in the dataLayer (the JavaScript array GTM reads), and standard GA4 ecommerce events (add_shipping_info, add_payment_info, purchase) aren’t visible in the console.

What’s implemented: Custom Pixel subscribes to Shopify analytics events—checkout_shipping_info_submitted, payment_info_submitted, checkout_completed—and pushes GA4-formatted ecommerce payloads (transaction_id, value, tax, shipping, currency, coupon, items). Line items are mapped (id, name, brand/vendor, category/type, variant, SKU, price, quantity). Payment type is set statically; shipping tier pulled from delivery.selectedDeliveryOptions[0].title.

Suggestion provided: Another participant advised using the updated dataLayer for Custom Pixel and shared a screenshot illustrating the purchase dataLayer. The OP confirms they are already using this approach and shared full code (with the delivery path corrected).

Status: No confirmed fix. The thread remains open. Unanswered points: why Shopify Test mode returns only the raw checkout object and why GA4 ecommerce events don’t surface in the console; no verification of GTM tag/trigger configuration discussed. An image (purchase dataLayer example) is referenced.

Summarized with AI on December 10. AI used: gpt-5.

Hi everyone,

I’m implementing GA4 using Shopify’s Custom Pixel + GTM setup.
Shopify is successfully sending the checkout data into the dataLayer, but I’m getting the raw checkout object when using Test option from shopify ,not working in the console as per the standard GA4 ecommerce events like add_payment_info, purchase, add_shipping_info, etc.

Here is the code i am using in the custom pixel:window.dataLayer = window.dataLayer || ;

// --------- Format Items ----------

function getCheckoutItems(event) {

return event.data?.checkout?.lineItems?.map((item) => ({

item_id: item.variant?.id,

item_name: item.title,

item_brand: item.variant?.product?.vendor,

item_category: item.variant?.product?.type,

item_variant: item.variant?.title || "",

item_list_id: item.variant?.sku,

price: item.finalLinePrice?.amount / item.quantity,

quantity: item.quantity,

}));

}

// --------- ADD SHIPPING INFO ----------

analytics.subscribe(“checkout_shipping_info_submitted”, (event) => {

window.dataLayer.push({

event: "add_shipping_info",

ecommerce: {

  shipping_tier:

    event.data?.checkout?.delivery?.selectedDeliveryOptions?.[0]?.title ||

    "Standard",

  items: getCheckoutItems(event),

},

});

});

// --------- ADD PAYMENT INFO ----------

analytics.subscribe(“payment_info_submitted”, (event) => {

window.dataLayer.push({

event: "add_payment_info",

ecommerce: {

  payment_type: "Online Payment", // Shopify doesn't return payment method here, so static or custom mapping

  items: getCheckoutItems(event),

},

});

});

// --------- PURCHASE EVENT ----------

analytics.subscribe(“checkout_completed”, (event) => {

window.dataLayer.push({

event: "purchase",

ecommerce: {

  transaction_id: event.data?.checkout?.order?.id,

  affiliation: "Online Store",

  value: event.data?.checkout?.totalPrice?.amount,

  tax: event.data?.checkout?.totalTax?.amount,

  shipping: event.data?.checkout?.shippingLine?.price?.amount || 0,

  currency: event.data?.checkout?.currencyCode,

  coupon:

    event.data?.checkout?.discountApplications?.[0]?.title || "",

  items: getCheckoutItems(event),

},

});

});

If anyone knows about this problem & solution, please help me to resolve it. Thanks in advance.

Use the updated datalayer for custom pixel to get all ecommerce events on console.

Yes @J_mah I am using the same. Here is my full code for your reference:
window.dataLayer = window.dataLayer || ;

// --------- Format Items ----------

function getCheckoutItems(event) {

return event.data?.checkout?.lineItems?.map((item) => ({

item_id: item.variant?.id,

item_name: item.title,

item_brand: item.variant?.product?.vendor,

item_category: item.variant?.product?.type,

item_variant: item.variant?.title || "",

item_list_id: item.variant?.sku,

price: item.finalLinePrice?.amount / item.quantity,

quantity: item.quantity,

}));

}

// --------- ADD SHIPPING INFO ----------

analytics.subscribe(“checkout_shipping_info_submitted”, (event) => {

window.dataLayer.push({

event: "add_shipping_info",

ecommerce: {

  shipping_tier:

    event.data?.checkout?.delivery?.selectedDeliveryOptions?.[0]?.title ||

    "Standard",

  items: getCheckoutItems(event),

},

});

});

// --------- ADD PAYMENT INFO ----------

analytics.subscribe(“payment_info_submitted”, (event) => {

window.dataLayer.push({

event: "add_payment_info",

ecommerce: {

  payment_type: "Online Payment", // Shopify doesn't return payment method here, so static or custom mapping

  items: getCheckoutItems(event),

},

});

});

// --------- PURCHASE EVENT ----------

analytics.subscribe(“checkout_completed”, (event) => {

window.dataLayer.push({

event: "purchase",

ecommerce: {

  transaction_id: event.data?.checkout?.order?.id,

  affiliation: "Online Store",

  value: event.data?.checkout?.totalPrice?.amount,

  tax: event.data?.checkout?.totalTax?.amount,

  shipping: event.data?.checkout?.shippingLine?.price?.amount || 0,

  currency: event.data?.checkout?.currencyCode,

  coupon:

    event.data?.checkout?.discountApplications?.[0]?.title || "",

  items: getCheckoutItems(event),

},

});

});