Shopify
PennyLens auto-detects Shopify stores — including Shopify Plus, hydrogen-fronted storefronts, and the standard Online Store 2.0 themes. Drop the SDK snippet onto your storefront and product_view and cart_add start flowing without any further wiring; connect the order-creation webhook below for reliable purchase capture.
This page covers what auto-detect actually does, what to expect on Shopify's hosted checkout, and how to recover when events aren't flowing.
When auto-detect activates
When the SDK loads, it checks two signals. Either one enables the Shopify hooks:
window.Shopify.shopis a non-empty string — present on virtually every Shopify storefront, including custom-coded themes and headless setups that ship with the Shopify JS.- A
<meta name="shopify-checkout-api-token">tag — present on Shopify's checkout pages, catching themes where thewindow.Shopifyglobal is stripped elsewhere on the site.
The check short-circuits on the first positive and silently no-ops on non-Shopify sites. The auto-detect logic ships in the core 8 KB SDK bundle.
Cart events
PennyLens intercepts the Shopify Ajax Cart API to capture cart_add without any theme modification:
/cart/add.js(and the GraphQL Storefront equivalent on hydrogen sites) — every line item added to the cart emits acart_addevent withproduct_id,variant_id,quantity, and the line total./cart/update.jsand/cart/change.js— quantity edits and removals update the cart-state model used for abandonment analysis, but don't emit duplicatecart_addevents.
Exactly one network-level interceptor is installed per page, shared with any other PennyLens e-commerce integration to avoid stacking patches.
Checkout and purchase
Shopify's checkout runs on Shopify-owned domains (or a checkout.* subdomain on Plus), inside a sandboxed context the storefront SDK can't reach. That limits what auto-detect can capture there:
checkout_step— step-by-step checkout progress is manual-only today. Shopify'scheckout.liquidsandbox blocks the SDK from injecting into the checkout iframe, so auto-detect cannot fire this event pre-Aug-2026. If you need step-level dropoff before then, wire it manually withpennylens.track('checkout_step', ...). (Shopify is sunsettingcheckout.liquidon Aug 26, 2026 in favor of the Web Pixels API, which will let PennyLens auto-capture this — this doc will update when that ships.)purchase(client-side, best-effort) — emitted when a/checkout/.../thank_you(or/checkouts/{token}/thank_you) URL loads, readingwindow.Shopify.checkoutfortotal,currency, andorder_id. That object is not guaranteed to be present on every store, so treat this as a best-effort signal, not a reliable one.purchase(server-side, recommended) — a Shopify order creation webhook delivered straight to PennyLens's ingestion service. This is the reliable path: it fires from Shopify's servers regardless of what happens in the customer's browser, and it's the only path that carries a hashed customer identity for per-customer attribution.
Without the webhook connected, purchases still capture via the client-side signal above, but customer identity stays anonymous beyond the order ID.
Connect the order-creation webhook
Set this up once per project for reliable, per-customer purchase capture:
- In PennyLens, open your project's Settings → Shopify Webhook panel.
- Copy the Webhook URL shown there.
- In Shopify Admin, go to Settings → Notifications → Webhooks and click Create webhook.
- Set Event to
Order creationand Format toJSON. - Paste the Webhook URL from step 2 into Shopify's URL field, then save.
- Shopify displays a Signing secret back to you — copy it, paste it into the Signing Secret field in PennyLens Settings → Shopify Webhook, then click Regenerate to save it.
PennyLens verifies every delivery against that signing secret (HMAC-SHA256) before accepting it, and de-dupes retries automatically — Shopify's own retry behavior on a slow response won't double-count an order.
Mutual exclusion with WooCommerce
If both Shopify and WooCommerce signals appear on the same page — usually only on agency development sites — Shopify takes precedence and the WooCommerce auto-hook silently no-ops. Manual wiring still works on dual-signal sites.
Zero-event fallback
If 24 hours after install you don't see any events in the PennyLens dashboard, walk through these in order:
- Confirm the SDK is loaded. Open your storefront's browser developer console and run
window.PennyLens. It should be defined. If it isn't, check that the snippet is in your theme'stheme.liquid<head>block — not just on/products/*pages. - Confirm Shopify is detected. In the same console, run
window.Shopify?.shop. It should be a non-empty string. If it'sundefined, your theme has stripped the standard Shopify JS — fall back to manual wiring. - Check the order-creation webhook. If the dashboard shows
cart_addevents but nopurchaseevents, the order status page redirect may be skipping the standard/thank_youroute — or you haven't connected the webhook yet. Connect the order-creation webhook (above); it captures purchases directly from Shopify's servers and doesn't depend on the customer's browser reaching/thank_you. - Headless storefronts. Hydrogen and other custom storefronts that don't set
window.Shopify.shopor render theshopify-checkout-api-tokenmeta tag won't trigger auto-detect. Use the manual snippet in the SDK reference — same API as any custom event.
Confidence indicator
Once at least one cart_add or purchase event has arrived, the dashboard Overview displays a confidence badge above the KPI row:
Shopify detected — 1,247 events captured
The badge is informational — no action required when it appears. If you don't see it after 24 hours, return to the Zero-event fallback above.
Manual wiring
If your storefront falls outside the auto-detect signals — headless hydrogen sites, custom-coded themes that strip Shopify's standard globals, or storefronts behind a CDN that hides Shopify origin scripts — wire the events manually:
pennylens.track("cart_add", {
product_id: 7281928392,
variant_id: 41827382,
qty: 1,
total: 49.0,
currency: "USD",
});
Same API as any custom event. See Event Tracking for the full reference.
Next steps
- Custom e-commerce — manual wiring for headless / custom / WooCommerce storefronts
- SaaS events — conventions for SaaS site types
- API Reference — full data model