Skip to content

Google Analytics 4 on hosted litecheckout

Hosted litecheckout can load your Google Analytics 4 tag on the checkout page and send three events to your own property. You enter a measurement ID once in Merchant Admin; litecommerce owns the loader, the event payloads, the consent defaults, and the Content-Security-Policy. There is no script field, no Tag Manager container, and nothing to paste — a hosted checkout is a payment surface, so only this reviewed, platform-owned integration runs on it.

Scope of the first release. Ordinary cart checkout at /session/<token> only. Booking and subscription checkouts, the order-status page, and the signed-in account center send nothing. The capability reaches your Preview surface with the release that carries it and production with the promotion of that same release. You can tell whether your environment has it: the Google Analytics 4 section appears under Settings → Checkout, and the anonymous organization snapshot (GET /api/v1/organizations/{slug}) carries a ga4MeasurementId key (null until you activate). If neither is present, your environment does not have the capability yet.

Configure it

  1. In Google Analytics, create or choose the GA4 property and web data stream for your store. Use a separate property for Preview (see environments below) so test orders never land in production reporting.
  2. In Merchant Admin go to Settings → Checkout → Google Analytics 4 and enter the stream's measurement ID (G-XXXXXXXXXX). Universal Analytics (UA-), Tag Manager (GTM-), and Ads (AW-) identifiers are rejected. Anyone with settings permission can enter, change, or clear the ID.
  3. Have a tenant Owner or Admin tick "My published privacy policy discloses Google Analytics use on hosted checkout." Only an Owner or Admin can record this attestation; Merchant Admin disables the box for everyone else. Until it is recorded the ID is saved but no tag renders — the public snapshot reports ga4MeasurementId: null — so Staff can enter the ID first and an Owner or Admin can attest later.
  4. Save. To turn the tag off, clear the field and save: that also clears the attestation, and the next checkout page load carries no tag. Changing the ID to a different value clears the attestation too; the new ID stays dark until an Owner or Admin records the disclosure again.

Each attestation, and each clear or change of an attested ID, is recorded in your organization's audit log with the acting user, the timestamp, and the measurement ID (the attested statement is stored verbatim on the attestation entry).

The measurement ID is public by nature (it ships in every tagged page), so once activated it is also readable on the anonymous organization snapshot (GET /api/v1/organizations/{slug}ga4MeasurementId). That projection exists to serve the hosted checkout tag. If you read it to tag your own storefront or a BYO checkout, that is your own integration with its own disclosure obligations: none of the hosted checkout's safeguards described below (the sanitized locations, the consent defaults, the Content-Security- Policy, the verified purchase) travel with the value. The attestation timestamp stays merchant-only.

Environments

You are onThe value you save reachesRecommended property
admin.preview.litecommerce.io{tenant}.preview.litecheckout.io onlya Preview-only GA4 property
admin.litecommerce.io{tenant}.litecheckout.io onlyyour production property

Each environment stores its own value, and litecheckout additionally refuses to render the tag unless the request host is exactly your tenant's canonical host for that environment — never a per-PR deployment URL or a local development host. Prefer a separate property over GA4 data filters for test traffic: a filter is permanent once applied and the filtered stream still receives the events.

What litecheckout sends

The tag loads gtag.js from www.googletagmanager.com as an ordinary asynchronous script after the page has rendered — it never blocks checkout, and a blocked or failed load leaves checkout untouched. Google serves gtag.js unversioned, so it cannot carry Subresource Integrity; the platform admits it by host allowance on the checkout-session route only. The tag runs with:

  • send_page_view: false — the automatic page view is replaced by the sanitized manual one below;
  • page_location fixed at config level to https://{your checkout host}/session; litecheckout's own in-page URL changes (after a payment-provider return and when an expired checkout is recovered in place) go through a history.replaceState reference captured before the tag loads, so the tag's history hook never sees them and a history-based page view cannot carry the checkout link — that bypass is the guard, and the sanitized location is re-applied afterwards only so later events keep it;
  • page_referrer fixed at config level to the referrer's origin only;
  • cookie_domain pinned to your exact checkout host, so _ga is never shared across tenants on litecheckout.io;
  • allow_google_signals: false and allow_ad_personalization_signals: false;
  • no user_id, no user properties, and no debug mode.
EventWhenParameters and where they come from
page_viewone manual page view per checkout page load, sent by litecheckout (litecheckout's own in-page URL changes, after a payment-provider return and when an expired checkout is recovered in place, are invisible to your stream's history-events option, so that option adds no page views here)page_location = https://{tenant}.litecheckout.io/session in production and https://{tenant}.preview.litecheckout.io/session on Preview (the checkout token and every query parameter are removed); page_referrer = the referrer's origin; page_title = "Secure checkout".
begin_checkoutonce per checkout session per browser tab, when the session first renders as payablecurrency (ISO 4217, upper case); value; items.
purchaseonce per order per browser, only after the server reports the session CONFIRMED with an order numbertransaction_id = your order number; currency; value; tax; shipping; items.

Per Google's guidance, value is the sum of price × quantity over the items after discounts and excludes shipping and tax; both ride separately on purchase. A cart-level discount is allocated across the lines in proportion to their totals, so each entry in items carries item_id (the catalog variant id, or the item id when the line has no variant), item_name (the line name as it appears on the order), price (the discounted unit price), discount (the per-unit reduction, when a discount applies), and quantity. Unit prices may carry more decimals than the currency's minor unit so that item revenue and value reconcile exactly. Amounts are reported in major units at the currency's own precision (a zero-decimal currency such as JPY reports whole yen). Package component rows are excluded so item totals reconcile to the subtotal.

Why the purchase is verified and not duplicated

The purchase never fires from the Stripe return URL's redirect_status — that lands before the payment webhook and could be forged. It fires only when the authoritative session read says CONFIRMED and carries the order number, and the browser remembers each order number it has already reported so a reload, a back navigation, or a return to the confirmation page does not send it again. GA4 additionally deduplicates web-stream purchases that share a transaction_id.

What is never sent

The checkout link token, the Stripe PaymentIntent client secret, card data, the shopper's email, phone, name, addresses, customer id, and account state. Unit tests pin these exclusions on every payload and on page_location.

Enhanced measurement on your stream

GA4's enhanced measurement settings belong to your data stream and stay under your control. litecheckout neutralizes the automatically collected parameters that could otherwise carry the checkout URL: every form on the checkout page has a sanitized action (form_destination = /session), the referrer is origin-only, the outbound-click link_url can only ever be a link you configured (your store, your policies, your support contact — never a checkout or order-status link), and litecheckout's own in-page URL changes bypass the tag's history hooks, so the history-events option never sees them. If a shopper's content blocker stops the primary collection endpoint, the tag retries on www.google.com, which the checkout policy deliberately excludes; the browser then sends a Content-Security-Policy violation report to litecommerce's own collector, and no analytics hit reaches Google. If you do not want form-interaction, outbound-click, site-search, or history-based page-view events from checkout at all, turn those options off on the stream; the platform does not change your stream settings.

Before the tag loads, litecheckout declares consent-mode defaults on every checkout page: ad_storage, ad_user_data, and ad_personalization are denied everywhere; analytics_storage is granted on the notice-based posture, except for visitors in the EU member states, the EEA (Iceland, Liechtenstein, Norway), the United Kingdom, Switzerland, and the related territories (Åland, French Guiana, Guadeloupe, Martinique, Saint Martin, Réunion, Mayotte, Gibraltar, Jersey, Guernsey, Isle of Man), where it is denied and those visitors are measured without cookies.

These defaults are the same for every tenant and every shopper. A consent choice a shopper made on your storefront does not carry into hosted checkout in this release: a shopper who declined analytics on your storefront is still measured on checkout under the defaults above. If your storefront asks for opt-in consent, hold your attestation: the platform is building a handoff that carries the storefront choice into checkout, and asks opt-in storefronts to activate once it ships. Your privacy policy must describe what checkout does. litecheckout has no consent banner; the platform's /cookies notice on your checkout host lists the _ga cookies when your tag is active, and says so explicitly when it could not confirm your configuration for a request. Your privacy policy must disclose your use of Google Analytics before you activate the tag — that is what the attestation records.

Keep attribution across your storefront and checkout

Your storefront and {tenant}.litecheckout.io are different domains. This section applies to shoppers whose analytics storage is granted: Google's linker carries the _ga client id, so visitors measured without cookies in the regions listed under consent defaults start a new client on each domain whatever you configure, and their checkout is reported separately. For every other shopper, for GA4 to treat the storefront visit and the checkout as one session:

  1. Install the same measurement ID on your storefront (the Preview ID on your preview storefront, the production ID on your production storefront), in the top-level document. Google's cross-domain linker works only when the storefront tag can keep the _ga cookie and decorate the links on the page. A tag loaded in a sandboxed or opaque-origin frame can do neither, so the checkout visit starts a new client no matter what else you configure.
  2. In GA4 admin, under the web data stream's tag settings, configure your domains to include both your storefront host and your same-environment checkout host ({tenant}.litecheckout.io for production, {tenant}.preview.litecheckout.io for Preview). Google's tag then decorates navigation between them with the _gl linker parameter. This helps only when your storefront tag can decorate; otherwise it merely adds _gl to hosted checkout's "Return to store" links.
  3. Under list unwanted referrals, add stripe.com, so a shopper returning from a 3-D Secure or bank redirect is not counted as a new referral session.
  4. Make the handoff to checkout a link the shopper clicks. Google documents that the linker decorates link clicks and form submissions, not navigation triggered purely by JavaScript. If your storefront creates the checkout session and then navigates with window.location, the checkout page arrives without _gl and GA4 starts a new session attributed to a referral from your storefront. Render the session URL as an anchor once the session exists, or trigger the navigation through a real anchor click, and verify in your browser that the litecheckout URL carries _gl.
  5. Keep Google signals off on the property. The hosted tag disables them, and the checkout CSP deliberately admits no advertising endpoints, so a property with signals on produces blocked, reported requests rather than data.

The "Return to store" link on the confirmation page is an ordinary anchor, so the return trip is decorated automatically once your domains are configured.

Verify

GA4's DebugView shows only sessions running in debug mode, and the hosted tag never sets debug_mode, so enable a debug session in your own browser first (Google's Analytics Debugger extension, or the steps DebugView itself lists) — otherwise DebugView stays empty even though events are arriving. The Realtime report needs no setup and shows the same events with a short delay. Verify from a location where analytics storage is granted (or with a non-EU/EEA/UK/Swiss geolocation), otherwise the cross-domain checks below cannot pass by design. Then start a checkout on {tenant}.preview.litecheckout.io with the Preview property configured and complete a test payment. You should see one page_view whose location ends in /session with no token, one begin_checkout with the expected value and items, and exactly one purchase with transaction_id equal to the order number — and no second purchase after reloading the confirmation page. In the browser's network panel, every request to Google hosts should be free of the checkout token, the client secret, and any customer detail. Requests the checkout page's Content-Security-Policy blocks (for example advertising endpoints from a property with signals on) show as CSP violations in the browser console.

Who owns what

litecommerce owns the tag, the events and their payloads, the consent defaults, and the checkout page's Content-Security-Policy, and can remove the Google hosts from that policy in an emergency. You own the GA4 property, its data-stream settings (including enhanced measurement), your storefront tag, and your privacy disclosure. Clearing the measurement ID in Merchant Admin stops the tag on every checkout page loaded from then on; a checkout that is already open keeps the tag it loaded until that page reloads.

Limits: browser analytics versus your order ledger

GA4 counts what a browser managed to send. It undercounts and cannot be reconciled to Admin:

  • ad blockers and privacy browsers block the tag host outright;
  • a shopper who closes the tab before the confirmation renders sends no purchase;
  • visitors in the cookieless regions are measured without cookies, and denied or unsupported browsers may send nothing;
  • Safari caps script-set cookies at seven days, so returning-visitor attribution decays;
  • orders placed through POS, Merchant Admin, invoices, bookings, or subscriptions never pass through the tag;
  • refunds, cancellations, and chargebacks are not reflected.

The Orders ledger in Merchant Admin and its exports remain the only source of truth for revenue and order counts.

Not included

add_shipping_info and add_payment_info, SKU and coupon codes on the items, server-side Measurement Protocol delivery (including refund), tags on the order-status or account surfaces, Google Tag Manager, advertising pixels, a consent banner, and carrying a storefront consent choice into checkout. These are tracked follow-ups, not launch dependencies.