Domina la implementación de scripts en el checkout de Shopify para capturar los eventos cruciales de tu e-commerce: add_to_cart, begin_checkout y purchase. Configura un rastreo avanzado y sin pérdidas para inyectar datos ultraprecisos en tu estrategia de Google Ads.
Accede a la lección en vídeo de la membresía. Cada martes, jueves y sábado aprende con una clase nueva. Puedes identificarte en este enlace o suscribirte a los cursos.
Contenido de la lección
(Recordar que este contenido es la escaleta)
Todos los eventos del checkout usan analytics.subscribe() de la API de Shopify Customer Events para escuchar los eventos nativos del sistema. Cada suscripción recibe un objeto event con event.data.checkout o event.data.cartLine según el evento.
purchase (checkout_completed) → GA4 + Google Ads
Es el evento más crítico. Extrae transaction_id, value, tax, shipping y coupon del objeto order:
analytics.subscribe('checkout_completed', (event) => {
const order = event.data.checkout;
const transactionId = String(order.order.id);
const value = parseFloat(order.totalPrice.amount);
const currency = order.currencyCode;
const tax = parseFloat(order.totalTax?.amount || 0);
const shipping = parseFloat(
order.delivery?.selectedDeliveryOptions?.[0]?.cost?.amount ||
order.shippingLine?.price?.amount || 0);
const coupon = order.discountApplications?.[0]?.title || '';
// → GA4 via Measurement Protocol
sendGA4(getClientId(), [{
name: 'purchase',
params: { transaction_id: transactionId, value, tax,
shipping, currency, coupon,
items: mapItems(order.lineItems) }
}]);
// → Google Ads conversion
gtag('event', 'conversion', {
send_to: GOOGLE_ADS_ID + '/' + CONVERSION_PURCHASE,
value, currency, transaction_id: transactionId
});
});
begin_checkout (checkout_started) → GA4 + Google Ads
analytics.subscribe('checkout_started', (event) => {
const checkout = event.data.checkout;
sendGA4(getClientId(), [{
name: 'begin_checkout',
params: { currency: checkout.currencyCode,
value: parseFloat(checkout.totalPrice.amount),
coupon: checkout.discountApplications?.[0]?.title || '',
items: mapItems(checkout.lineItems) }
}]);
gtag('event', 'conversion', {
send_to: GOOGLE_ADS_ID + '/' + CONVERSION_BEGIN_CHECKOUT,
value: parseFloat(checkout.totalPrice.amount),
currency: checkout.currencyCode
});
});
add_to_cart (product_added_to_cart) → GA4 + Google Ads
Este evento usa event.data.cartLine en lugar de event.data.checkout. El item_id se construye con buildItemId() a partir de cartLine.merchandise:
analytics.subscribe('product_added_to_cart', (event) => {
const cartLine = event.data.cartLine;
const value = parseFloat(cartLine.merchandise.price.amount) * cartLine.quantity;
const currency = cartLine.merchandise.price.currencyCode;
sendGA4(getClientId(), [{ name: 'add_to_cart', params: { currency, value,
items: [{ item_id: buildItemId(cartLine.merchandise.product.id,
cartLine.merchandise.id),
item_name: cartLine.merchandise.product.title,
price: parseFloat(cartLine.merchandise.price.amount),
quantity: cartLine.quantity }] } }]);
gtag('event', 'conversion', {
send_to: GOOGLE_ADS_ID + '/' + CONVERSION_ADD_TO_CART,
value, currency });
});
add_shipping_info y add_payment_info → solo GA4
Estos dos eventos solo van a GA4 via Measurement Protocol, no generan conversión en Google Ads. add_shipping_info extrae el shipping_tier del campo delivery.selectedDeliveryOptions o shippingLine.title. add_payment_info extrae el payment_type de checkout.transactions[0].paymentMethod.name.
| Evento Shopify | analytics.subscribe() | GA4 | Google Ads |
| checkout_completed | purchase | ✓ MP | ✓ |
| checkout_started | begin_checkout | ✓ MP | ✓ |
| product_added_to_cart | add_to_cart | ✓ MP | ✓ |
| checkout_shipping_info_submitted | add_shipping_info | ✓ MP | — |
| payment_info_submitted | add_payment_info | ✓ MP | — |
| ⚠️ Deduplicación de purchase |
| • transaction_id: String(order.order.id) — GA4 y Google Ads usan este campo para deduplicar |
| • Si el usuario recarga la página de confirmación, Shopify no vuelve a disparar checkout_completed |
| • No es necesario el filtro first_time_accessed de Liquid porque Customer Events lo gestiona Shopify |
Script completo para pegar y copiar:
const GA4_MEASUREMENT_ID = 'rellena con tus datos';
const GA4_API_SECRET = 'rellena con tus datos';
const GOOGLE_ADS_ID = 'rellena con tus datos';
const CONVERSION_PURCHASE = 'rellena con tus datos'';
const CONVERSION_ADD_TO_CART = 'rellena con tus datos'';
const CONVERSION_BEGIN_CHECKOUT = 'rellena con tus datos'';
// Enviar evento a GA4 via Measurement Protocol
function sendGA4(clientId, events) {
fetch(
'https://www.google-analytics.com/mp/collect?measurement_id=' +
GA4_MEASUREMENT_ID + '&api_secret=' + GA4_API_SECRET,
{
method: 'POST',
body: JSON.stringify({
client_id: clientId,
events: events
})
}
)
.catch(err => console.error('GA4 MP error:', err));
}
// Obtener client_id del navegador
function getClientId() {
const gaCookie = document.cookie.split(';')
.find(c => c.trim().startsWith('_ga='));
if (gaCookie) {
const parts = gaCookie.trim().split('.');
if (parts.length >= 4) {
return parts[2] + '.' + parts[3];
}
}
return Math.random().toString(36).slice(2) + '.' + Date.now();
}
// Mapear items
function mapItems(lineItems) {
return lineItems.map((item, index) => ({
item_id: item.variant?.sku || String(item.variant?.id || ''),
item_name: item.title,
item_brand: item.variant?.product?.vendor || '',
item_category: item.variant?.product?.type || '',
item_variant: item.variant?.sku || '',
price: parseFloat(item.variant?.price?.amount || 0),
quantity: item.quantity,
index: index
}));
}
// Inicializar gtag para Google Ads
(function() {
window.dataLayer = window.dataLayer || [];
function gtag(){ dataLayer.push(arguments); }
window.gtag = gtag;
gtag('js', new Date());
gtag('config', GOOGLE_ADS_ID);
var script = document.createElement('script');
script.async = true;
script.src = 'https://www.googletagmanager.com/gtag/js?id=' + GOOGLE_ADS_ID;
document.head.appendChild(script);
})();
// ---- purchase → GA4 MP + Google Ads ----
analytics.subscribe("checkout_completed", (event) => {
const order = event.data.checkout;
const clientId = getClientId();
const transactionId = String(order.order.id);
const value = parseFloat(order.totalPrice.amount);
const currency = order.currencyCode;
const tax = parseFloat(order.totalTax?.amount || 0);
const shipping = parseFloat(
order.delivery?.selectedDeliveryOptions?.[0]?.cost?.amount ||
order.shippingLine?.price?.amount || 0
);
const coupon = order.discountApplications?.[0]?.title || '';
// GA4
sendGA4(clientId, [{
name: 'purchase',
params: {
transaction_id: transactionId,
value: value,
tax: tax,
shipping: shipping,
currency: currency,
coupon: coupon,
items: mapItems(order.lineItems)
}
}]);
// Google Ads purchase
gtag('event', 'conversion', {
send_to: GOOGLE_ADS_ID + '/' + CONVERSION_PURCHASE,
value: value,
currency: currency,
transaction_id: transactionId
});
});
// ---- begin_checkout → GA4 MP + Google Ads ----
analytics.subscribe("checkout_started", (event) => {
const checkout = event.data.checkout;
const value = parseFloat(checkout.totalPrice.amount);
const currency = checkout.currencyCode;
// GA4
sendGA4(getClientId(), [{
name: 'begin_checkout',
params: {
currency: currency,
value: value,
coupon: checkout.discountApplications?.[0]?.title || '',
items: mapItems(checkout.lineItems)
}
}]);
// Google Ads begin_checkout
gtag('event', 'conversion', {
send_to: GOOGLE_ADS_ID + '/' + CONVERSION_BEGIN_CHECKOUT,
value: value,
currency: currency
});
});
// ---- add_shipping_info ----
analytics.subscribe("checkout_shipping_info_submitted", (event) => {
const checkout = event.data.checkout;
sendGA4(getClientId(), [{
name: 'add_shipping_info',
params: {
currency: checkout.currencyCode,
value: parseFloat(checkout.totalPrice.amount),
shipping_tier: checkout.delivery?.selectedDeliveryOptions?.[0]?.title ||
checkout.shippingLine?.title || '',
items: mapItems(checkout.lineItems)
}
}]);
});
// ---- add_payment_info ----
analytics.subscribe("payment_info_submitted", (event) => {
const checkout = event.data.checkout;
sendGA4(getClientId(), [{
name: 'add_payment_info',
params: {
currency: checkout.currencyCode,
value: parseFloat(checkout.totalPrice.amount),
payment_type: checkout.transactions?.[0]?.paymentMethod?.name || '',
items: mapItems(checkout.lineItems)
}
}]);
});
// ---- add_to_cart → GA4 MP + Google Ads ----
analytics.subscribe("product_added_to_cart", (event) => {
const cartLine = event.data.cartLine;
const value = parseFloat(cartLine.merchandise.price.amount) * cartLine.quantity;
const currency = cartLine.merchandise.price.currencyCode;
// GA4
sendGA4(getClientId(), [{
name: 'add_to_cart',
params: {
currency: currency,
value: value,
items: [{
item_id: cartLine.merchandise.sku || String(cartLine.merchandise.id || ''),
item_name: cartLine.merchandise.product.title,
item_brand: cartLine.merchandise.product.vendor || '',
item_category: cartLine.merchandise.product.type || '',
item_variant: cartLine.merchandise.sku || '',
price: parseFloat(cartLine.merchandise.price.amount),
quantity: cartLine.quantity,
index: 0
}]
}
}]);
// Google Ads add_to_cart
gtag('event', 'conversion', {
send_to: GOOGLE_ADS_ID + '/' + CONVERSION_ADD_TO_CART,
value: value,
currency: currency
});
});
Objetivo de la lección
Implementar los cinco scripts analytics.subscribe() del Pixel Personalizado que capturan los eventos del funnel de compra y los envían a GA4 y Google Ads.
Recursos
- Eventos disponibles en Customer Events: https://shopify.dev/docs/api/customer-events/events
- Objeto checkout en Customer Events: https://shopify.dev/docs/api/customer-events/objects/checkout
- Google Ads conversion labels: https://support.google.com/google-ads/answer/6095821
- Doc interna: Sección 6 — Detalle del script (todos los subscribe)