Skip to main content

πŸ”΄ Phase 1 β€” CoreΒ Β·Β The single most important event. Drives revenue, ROAS, and Google Ads conversions.

purchase ⭐

When to push​

On the order confirmation page (/checkout/success, /order/thank-you, etc.), after the order is committed to the database.

⚠️ Exactly once per order. See idempotency.

Complete example​

window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
event: 'purchase',
ecommerce: {
transaction_id: 'ORD-2026-00123', // REQUIRED, unique
currency: 'EUR',
value: 109.00, // merchandise (excl. shipping/tax)
tax: 18.17,
shipping: 4.95,
coupon: 'SPRING10',
affiliation: 'Biosphere Online Store',
items: [
{
item_id: 'BIO-CRM-001',
item_name: 'Hydrating Day Cream',
item_brand: 'Biosphere',
item_category: 'Skincare',
item_category2: 'Face',
item_variant: '50 ml',
price: 42.00,
quantity: 2,
discount: 0
},
{
item_id: 'BIO-SER-002',
item_name: 'Radiance Serum',
item_brand: 'Biosphere',
item_category: 'Skincare',
item_category2: 'Face',
price: 25.00,
quantity: 1,
discount: 10.00
}
]
},
user_data: {
email: 'jane.doe@example.com',
phone: '+33612345678',
first_name: 'Jane',
last_name: 'Doe',
address: {
street: '12 Lilac Street',
city: 'Paris',
region: 'IDF',
postal_code: '75011',
country: 'FR'
},
external_id: 'user_12345'
}
});

Parameters​

Event level​

ParameterTypeRequired
transaction_idstringREQUIRED β€” unique per order
currencystringREQUIRED
valuenumberREQUIRED β€” merchandise, excl. shipping/tax
itemsarrayREQUIRED
taxnumberrecommended
shippingnumberrecommended
couponstringoptional
affiliationstringoptional

Item level​

All standard fields (items). Critical to include:

  • item_id (must match Meta Catalog)
  • price (after item-level discount)
  • quantity
  • discount (if item-level discount applies)

user_data REQUIRED​

Send everything you have about the customer. The more complete, the better Meta matches (target EMQ β‰₯ 8) and the more accurate the Google Ads attribution (Enhanced Conversions). See user_data.

Platforms​

PlatformNative eventNotes
GA4purchaseRevenue, ROAS, transactions
MetaPurchaseCAPI + Pixel, deduped via event_id, contents for DPA
Google AdsConversion + Enhanced ConversionsHashed user_data uploaded

The transaction_id is sacred​

Without a unique transaction_id:

  • GA4 dedupes badly β†’ revenue inflated on every refresh.
  • Meta CAPI counts twice β†’ ROAS/CPM corrupted.
  • Google Ads conversion may be rejected.

Rules:

  • Unique per order.
  • Stable (never regenerated).
  • Ideally = customer-facing order number.
  • String, max 100 chars.

Amount consistency​

value (merchandise) = Ξ£ (item.price Γ— item.quantity) - global coupons
total paid = value + tax + shipping

GA4 reports value as revenue. The total paid is reconciled by summing.

Fatal pitfalls​

  • ❌ No transaction_id or non-unique.
  • ❌ Push before DB commit β†’ ghost revenue if payment fails async.
  • ❌ Re-push on refresh β†’ double counting.
  • ❌ value includes shipping/tax β†’ inflated ROAS.
  • ❌ Cents instead of units (10900 instead of 109.00).
  • ❌ item_id β‰  Meta Catalog β†’ DPA audiences broken.
  • ❌ Pushing without user_data β†’ Meta EMQ ~ 3/10, massive signal loss.