One place for all settings. Click Save and your store uses them right away. The app embed is only an on/off switch.Fill in the settings, then copy the code from Checkout Pixel into Settings › Customer events.
Sends every checkout event: dl_user_data, dl_begin_checkout, dl_add_contact_info, dl_add_shipping_info, dl_add_payment_info and dl_purchase.
Sends orders to your server container from Shopify Flow, so purchases are tracked even when the thank-you page never loads: ad blockers, closed tabs, the Shop app, Draft orders, POS, dropshipping and other apps. Meta, TikTok and Google Ads deduplicate it against the browser purchase by order ID.
Uses the Server container URL from the Settings tab: not set
With “Attach tracking IDs to orders” on in Settings, the body also carries the visitor's marketing IDs (user_id, fbp, fbc, ttp, gclid, UTMs…) under marketing, so server-side purchases match like browser ones.
It also sends new_customer (true/false) and customer_type for Google Ads new customer acquisition, customer_ltv (customer's lifetime spend), and cost_of_goods + profit from each product's cost per item (Products › Cost per item) for profit (POAS) bidding.
Second workflow: trigger Refund created › Send HTTP request, same URL and header. Sends event_name: refund with the order ID, refunded value, items and refund_type full/partial, so GA4 and Google Ads subtract refunded revenue.
Third workflow: trigger Order cancelled › add a condition Order › Total refunded amount equal to 0 (cancellations with a refund are already sent by the Refunds workflow) › Send HTTP request, same URL and header. Sends event_name: order_cancelled: use it in sGTM to retract Google Ads conversions and remove unpaid or COD orders from reports.
Flow can't send HTTP requests on the Basic plan. Use Settings › Notifications › Webhooks › Create webhook (Order payment, JSON) to the same server URL instead. The server container then needs a client that reads Shopify's order format.
Open the store with ?hrdl_debug=1 at the end of the URL. A debug panel opens in the bottom-right corner with every dl_* event, green/orange/red checks (event_id, user_id, currency, item_id/product_id/variant_id, prices, _fbp, _ga, fbclid › _fbc, UTMs, new/returning), consent state and cookie extender status. Click an event to see its full data, or Copy to share the log. Close or ?hrdl_debug=0 stops it. Checkout events are not shown in the panel (Shopify sandboxes checkout pixels): use GTM Preview there.
Open the store once with ?hrdl_internal=1. That browser then sends marketing.traffic_type = internal on every event, including checkout. Map it to the GA4 traffic_type parameter or add an exception trigger in GTM. ?hrdl_internal=0 clears it.
Logged-in shoppers use their Shopify order count and total spent. Guests use Shopify's first-order flag on the thank-you page, plus this browser's purchase history. dl_purchase carries ecommerce.purchase.actionField.new_customer and customer_ltv, and every event has user_properties.customer_type, customer_order_count and customer_total_spent.
Ad blockers, closed tabs and orders from the Shop app, Draft orders or POS never reach the thank-you page. The Order Webhook sends those orders server-side with the same order ID, so nothing is counted twice.
Safari limits cookies set by scripts to 7 days. The extender restores them on every visit from its backup, and the Stape Cookie Keeper option (Settings) restores them server-side using the 1-year Shopify client ID.
With Consent Mode on, Google tags wait for the Shopify cookie banner in the EU/EEA, UK and Switzerland. Cookies are only extended for categories the visitor accepted, and strict mode holds events until consent.
Use the format of your product feed: Product ID for most Meta catalogs, shopify_{country}_productID_variantID for the Google & YouTube channel feed. The country is filled in from the store's market.
No. The script loads deferred from Shopify's CDN (about 12 KB compressed) and does not block the page.
NexFeb GTM & DataLayer by NexFeb · nexfeb.com · support@nexfeb.com