Guest Checkout Rate
Also known as: Guest Order Share, Anonymous Checkout Rate, Guest vs Registered Checkout Mix, Unauthenticated Order Rate
Guest Checkout Rate is the share of completed orders placed without the shopper signing in to or creating an account, measured at order grain on the digital (web and app) purchase transaction; offline, call-centre and store-assisted orders are out of scope. It quantifies how much of realised demand the business converts anonymously, framing the trade-off between frictionless checkout and the customer identity, consent and lifecycle data an account unlocks.
Business Use Case
1️⃣ The Checkout Product Manager reviews the weekly rate split by Device Category; when mobile guest share runs materially above desktop, they prioritise removal of the account-creation interstitial and validate the change through a checkout A/B test measured on Checkout Completion Rate.,2️⃣ The CRM & Lifecycle Marketing Manager treats a rising rate as a shrinking addressable base; each month they quantify the orders arriving without a marketable profile and launch the post-purchase account-claim and consent-capture journey against that cohort.,3️⃣ The Merchandising and Loyalty team monitors the rate by Channel of Purchase (web vs app) to size the loyalty programme gap; where web orders run heavily guest relative to the app, where shoppers are typically signed in, they fund an at-checkout enrolment and app-download incentive on web checkout and track the resulting shift in Customer Retention Rate.,4️⃣ The Customer Service leadership uses the guest share to forecast order-lookup and 'where is my order' contact volume, because guest shoppers cannot self-serve from an account, and staffs the queue and self-service order-tracking page accordingly before peak trading.
Business Criticality
High
Journey / Navigation Area
Checkout
Owning Function
Product
Scope
Event
Formula
Calculation Notes
1️⃣ Grain and population: the KPI is computed on the purchase transaction, one row per completed order. The denominator is every completed order in the reporting period with no identity, consent or account-status filter applied; the numerator is the subset where checkout_type = 'guest'. begin_checkout is never used in the math — it remains a related funnel step for diagnosis only.,2️⃣ Known customer checking out as a guest: classification follows checkout_type as captured on the transaction, not the identity graph. An order placed by a shopper who has an existing account but did not authenticate counts as guest, even when email hash, loyalty id or device history later resolves to a known profile. Identity resolution may enrich the order record but must never re-label the checkout type.,3️⃣ Scope is digital orders only (web and app purchase events); offline, call-centre and store-assisted orders are not counted. CRM account status (Salesforce) is joined to digital orders purely as account enrichment, stamping a checkout type on a digital order only when neither checkout_type nor login state was captured; it is a LEFT JOIN and must never filter, join away or otherwise shrink the denominator of digital orders.,4️⃣ Exclusions applied before the ratio is formed, identically in both SQLs: test and internal QA orders (test_order = true), zero-value orders (order revenue of 0), and orders captured with order_status cancelled or voided. Refunded orders stay in both numerator and denominator because the checkout behaviour occurred.,5️⃣ Deduplication and timing: orders are keyed on transaction_id and deduplicated across retries, payment re-authorisations and confirmation-page reloads before counting. The KPI is attributed to the order timestamp in the reporting timezone, not to the session start, so orders that cross midnight or a 30-minute session timeout are still counted in the day the order was placed.,6️⃣ Express and wallet checkouts (Shop Pay, PayPal Express, Apple Pay, Amazon Pay) resolve to guest unless the platform authenticates the shopper into a store account during the flow. Document the wallet-by-wallet mapping once and hold it stable, because a payment-provider release can silently move a wallet between the two buckets and create a false trend break.,7️⃣ Post-purchase account creation offered on the order-confirmation page does not retroactively convert a guest order to a registered order. Track that conversion separately as Sign-up Rate so the checkout-friction signal and the identity-capture signal stay independent.
Technical Details
Events
| Platform | Event |
|---|---|
| Google Analytics 4 | purchase |
| Adobe | purchase (Order Confirmation) |
Data Mappings
W3 Data Layer
{
"digitalData": {
"pageInstanceID": "prod-web-checkout-confirmation",
"page": {
"pageInfo": {
"pageID": "checkout-confirmation",
"pageName": "Checkout: Order Confirmation",
"destinationURL": "https://www.example.com/checkout/confirmation",
"sysEnv": "mobile",
"language": "en-US"
},
"category": {
"primaryCategory": "checkout",
"subCategory1": "order-confirmation"
},
"attributes": {
"checkoutType": "guest",
"channelOfPurchase": "web",
"deviceCategory": "mobile"
}
},
"user": [
{
"profile": [
{
"profileInfo": {
"profileID": null,
"userName": null
},
"attributes": {
"loginState": "unauthenticated",
"authenticationMethod": "none",
"accountStatus": "guest",
"customerType": "unknown"
}
}
]
}
],
"transaction": {
"transactionID": "ORD-10045872",
"profile": {
"profileInfo": {
"profileID": null
},
"attributes": {
"checkoutType": "guest",
"loginState": "unauthenticated",
"accountCreatedAtCheckout": false
}
},
"total": {
"basePrice": 178,
"voucherCode": "SPRING10",
"voucherDiscount": 10,
"currency": "USD",
"taxRate": 0.08,
"shipping": 9.95,
"shippingMethod": "standard",
"priceWithTax": 181.44,
"transactionTotal": 191.39
},
"attributes": {
"checkoutType": "guest",
"paymentType": "paypal_express",
"fulfillmentType": "ship",
"channelOfPurchase": "web",
"deviceCategory": "mobile",
"orderStatus": "completed",
"testOrder": false
},
"item": [
{
"productInfo": {
"productID": "SKU-48219",
"productName": "Merino Wool Crew Sweater",
"sku": "SKU-48219",
"manufacturer": "Northbound",
"color": "Charcoal",
"size": "M"
},
"category": {
"primaryCategory": "Apparel",
"subCategory1": "Knitwear"
},
"quantity": 2,
"price": {
"basePrice": 89,
"voucherCode": "SPRING10",
"voucherDiscount": 10,
"currency": "USD",
"taxRate": 0.08,
"priceWithTax": 181.44
}
}
]
},
"version": "1.0"
}
}GA4 Data Layer
{
"event": "purchase",
"checkout_type": "guest",
"login_state": "unauthenticated",
"authentication_method": "none",
"account_created_at_checkout": false,
"payment_type": "paypal_express",
"fulfillment_type": "ship",
"channel_of_purchase": "web",
"device_category": "mobile",
"order_status": "completed",
"test_order": false,
"ecommerce": {
"transaction_id": "ORD-10045872",
"value": 191.39,
"tax": 13.44,
"shipping": 9.95,
"currency": "USD",
"coupon": "SPRING10",
"items": [
{
"item_id": "SKU-48219",
"item_name": "Merino Wool Crew Sweater",
"item_brand": "Northbound",
"item_category": "Apparel",
"item_category2": "Knitwear",
"item_variant": "Charcoal / M",
"item_list_name": "Search Results",
"price": 89,
"discount": 10,
"coupon": "SPRING10",
"quantity": 2,
"index": 1
}
]
}
}Adobe Client Data Layer
{
"event": "purchase",
"eventInfo": {
"path": "commerce.order"
},
"commerce": {
"purchases": {
"value": 1
},
"order": {
"purchaseID": "ORD-10045872",
"purchaseOrderNumber": "ORD-10045872",
"currencyCode": "USD",
"priceTotal": 191.39,
"taxAmount": 13.44,
"shippingAmount": 9.95,
"discountAmount": 10,
"couponCode": "SPRING10",
"orderType": "ship",
"payments": [
{
"paymentType": "paypal_express",
"paymentAmount": 191.39,
"currencyCode": "USD"
}
]
},
"productListItems": [
{
"SKU": "SKU-48219",
"name": "Merino Wool Crew Sweater",
"productCategory": "Apparel",
"productBrand": "Northbound",
"selectedOptions": "Charcoal / M",
"priceTotal": 178,
"quantity": 2,
"currencyCode": "USD"
}
]
},
"checkout": {
"checkoutType": "guest",
"authenticationMethod": "none",
"expressCheckout": true,
"accountCreatedAtCheckout": false,
"orderStatus": "completed",
"testOrder": false
},
"userAccount": {
"loginStatus": "unauthenticated",
"accountStatus": "guest",
"customerType": "unknown"
},
"device": {
"deviceCategory": "mobile"
},
"channel": {
"typeAtSource": "web",
"channelOfPurchase": "web"
}
}XDM Mapping
{
"eventType": "commerce.purchases",
"timestamp": "2026-09-17T14:32:08.000Z",
"channel": {
"_type": "https://ns.adobe.com/xdm/channels/web",
"typeAtSource": "web"
},
"commerce": {
"purchases": {
"value": 1
},
"order": {
"purchaseID": "ORD-10045872",
"purchaseOrderNumber": "ORD-10045872",
"currencyCode": "USD",
"priceTotal": 191.39,
"discountAmount": 10,
"payments": [
{
"paymentType": "paypal_express",
"paymentAmount": 191.39,
"currencyCode": "USD",
"transactionID": "ORD-10045872-PAY-1"
}
]
}
},
"productListItems": [
{
"SKU": "SKU-48219",
"name": "Merino Wool Crew Sweater",
"productCategory": "Apparel",
"priceTotal": 178,
"quantity": 2,
"currencyCode": "USD"
}
],
"web": {
"webPageDetails": {
"name": "Checkout: Order Confirmation",
"URL": "https://www.example.com/checkout/confirmation",
"siteSection": "checkout"
}
},
"device": {
"type": "mobile"
},
"identityMap": {
"ECID": [
{
"id": "79352389423048239042",
"primary": true,
"authenticatedState": "ambiguous"
}
]
},
"_experience": {
"analytics": {
"customDimensions": {
"eVars": {
"eVar27": {
"value": "guest"
},
"eVar28": {
"value": "none"
}
},
"props": {
"prop27": {
"value": "guest"
}
}
}
}
},
"_openkpis": {
"checkout": {
"checkoutType": "guest",
"authenticationMethod": "none",
"accountCreatedAtCheckout": false,
"channelOfPurchase": "web",
"orderStatus": "completed",
"testOrder": false
}
}
}SQL Queries
Google Analytics 4 (BigQuery)
-- ==========================================
-- 1. GOOGLE BIGQUERY SQL
-- ==========================================
-- KPI : Guest Checkout Rate = (Guest Orders / Total Orders) * 100
-- Grain : one row per completed order, keyed on transaction_id from the unified `purchase` event.
-- Base : EVERY completed order in the window (guest + registered + unclassified). No identity,
-- consent or account-status predicate may shrink the denominator.
-- Breakdown: Checkout Type (returned as the guest / registered / unclassified order columns),
-- Payment Type, Device Category, Channel of Purchase.
DECLARE start_date STRING DEFAULT FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY));
DECLARE end_date STRING DEFAULT FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY));
WITH purchase_events AS (
SELECT
PARSE_DATE('%Y%m%d', event_date) AS order_date,
event_timestamp,
user_pseudo_id,
device.category AS device_category,
ecommerce.transaction_id AS ecommerce_transaction_id,
ecommerce.purchase_revenue AS order_revenue,
event_params
FROM `your-project.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX BETWEEN start_date AND end_date
AND event_name = 'purchase'
),
-- Pivot the event_params array in a single pass: one row per purchase beacon, one column per parameter.
order_attributes AS (
SELECT
order_date,
event_timestamp,
user_pseudo_id,
ANY_VALUE(device_category) AS device_category,
ANY_VALUE(order_revenue) AS order_revenue,
COALESCE(
MAX(IF(ep.key = 'transaction_id', ep.value.string_value, NULL)),
ANY_VALUE(ecommerce_transaction_id)
) AS transaction_id,
LOWER(MAX(IF(ep.key = 'checkout_type', ep.value.string_value, NULL))) AS checkout_type_param,
LOWER(MAX(IF(ep.key = 'login_state', ep.value.string_value, NULL))) AS login_state,
LOWER(MAX(IF(ep.key = 'payment_type', ep.value.string_value, NULL))) AS payment_type,
LOWER(MAX(IF(ep.key = 'channel_of_purchase', ep.value.string_value, NULL))) AS channel_of_purchase_param,
LOWER(MAX(IF(ep.key = 'order_status', ep.value.string_value, NULL))) AS order_status,
LOWER(MAX(IF(ep.key = 'test_order',
COALESCE(ep.value.string_value, CAST(ep.value.int_value AS STRING)), NULL))) AS test_order_flag
FROM purchase_events, UNNEST(event_params) AS ep
GROUP BY order_date, event_timestamp, user_pseudo_id
),
-- Order grain: a re-fired purchase beacon (confirmation reload, payment re-authorisation) keeps only its first hit.
-- Exclusions are applied here, symmetrically to numerator and denominator, before the ratio is formed.
deduplicated_orders AS (
SELECT * EXCEPT (row_num)
FROM (
SELECT
a.*,
ROW_NUMBER() OVER (PARTITION BY a.transaction_id ORDER BY a.event_timestamp) AS row_num
FROM order_attributes a
WHERE a.transaction_id IS NOT NULL
AND COALESCE(a.test_order_flag, 'false') NOT IN ('true', '1')
AND COALESCE(a.order_status, 'completed') NOT IN ('cancelled', 'voided')
AND COALESCE(a.order_revenue, 0) > 0
)
WHERE row_num = 1
),
-- Scope: digital orders only. CRM (Salesforce) is account enrichment only: it stamps a checkout type on a digital
-- order that carries neither checkout_type nor login_state. LEFT JOIN, so no digital order is ever joined out of the base.
crm_order_enrichment AS (
SELECT
order_id AS transaction_id,
LOWER(account_status) AS crm_account_status
FROM `your-project.crm_salesforce.orders`
WHERE order_date BETWEEN PARSE_DATE('%Y%m%d', start_date) AND PARSE_DATE('%Y%m%d', end_date)
),
orders AS (
SELECT
d.order_date,
d.transaction_id,
CASE
WHEN d.checkout_type_param IN ('guest', 'registered') THEN d.checkout_type_param
WHEN d.login_state = 'authenticated' THEN 'registered'
WHEN c.crm_account_status IN ('guest', 'registered') THEN c.crm_account_status
ELSE 'unclassified'
END AS checkout_type,
COALESCE(d.payment_type, '(not set)') AS payment_type,
COALESCE(d.device_category, '(not set)') AS device_category,
COALESCE(d.channel_of_purchase_param, '(not set)') AS channel_of_purchase
FROM deduplicated_orders d
LEFT JOIN crm_order_enrichment c
ON d.transaction_id = c.transaction_id
)
SELECT
order_date,
payment_type,
device_category,
channel_of_purchase,
COUNT(DISTINCT transaction_id) AS total_orders,
COUNTIF(checkout_type = 'guest') AS guest_orders,
COUNTIF(checkout_type = 'registered') AS registered_orders,
COUNTIF(checkout_type = 'unclassified') AS unclassified_orders,
ROUND(100 * SAFE_DIVIDE(COUNTIF(checkout_type = 'guest'), COUNT(DISTINCT transaction_id)), 2) AS guest_checkout_rate_pct
FROM orders
GROUP BY order_date, payment_type, device_category, channel_of_purchase
ORDER BY order_date DESC, total_orders DESC;Adobe Experience Platform (AEP Query Service)
-- ==========================================
-- 2. ADOBE AEP QUERY SERVICE SQL
-- ==========================================
-- KPI : Guest Checkout Rate = (Guest Orders / Total Orders) * 100
-- Dataset : ExperienceEvent, eventType = 'commerce.purchases'; XDM paths exactly as mapped in this specification.
-- Base : EVERY completed order in the window; identity and CRM account status enrich, they never filter.
-- Breakdown: Checkout Type (guest / registered / unclassified order columns), Payment Type,
-- Device Category, Channel of Purchase.
WITH purchase_events AS (
SELECT
to_date(timestamp) AS order_date,
timestamp AS event_timestamp,
commerce.order.purchaseID AS transaction_id,
commerce.order.priceTotal AS order_revenue,
commerce.purchases.value AS purchase_count,
lower(_openkpis.checkout.checkoutType) AS checkout_type_field,
lower(_openkpis.checkout.authenticationMethod) AS authentication_method,
lower(_openkpis.checkout.channelOfPurchase) AS channel_of_purchase_field,
lower(_experience.analytics.customDimensions.eVars.eVar27.value) AS checkout_type_evar,
lower(commerce.order.payments[0].paymentType) AS payment_type,
lower(device.type) AS device_category,
lower(_openkpis.checkout.orderStatus) AS order_status,
lower(cast(_openkpis.checkout.testOrder AS STRING)) AS test_order_flag
FROM your_experience_event_dataset
WHERE eventType = 'commerce.purchases'
AND timestamp >= date_sub(current_date, 90)
AND timestamp < current_date
AND commerce.order.purchaseID IS NOT NULL
),
-- Order grain: one row per purchaseID, the first beacon wins, so a confirmation reload cannot double count.
-- Exclusions match the BigQuery query: test orders, cancelled / voided orders and zero-value orders.
deduplicated_orders AS (
SELECT *
FROM (
SELECT
p.*,
row_number() OVER (PARTITION BY p.transaction_id ORDER BY p.event_timestamp) AS row_num
FROM purchase_events p
WHERE coalesce(p.order_revenue, 0) > 0
AND coalesce(p.purchase_count, 1) > 0
AND coalesce(p.test_order_flag, 'false') NOT IN ('true', '1')
AND coalesce(p.order_status, 'completed') NOT IN ('cancelled', 'voided')
) ranked
WHERE row_num = 1
),
-- Scope: digital orders only. CRM (Salesforce) orders dataset is account enrichment only: it stamps a checkout
-- type on a digital order that carries no checkout type or authentication method.
-- LEFT JOIN by construction, so the digital order population stays whole.
crm_order_enrichment AS (
SELECT
orderId AS transaction_id,
lower(accountStatus) AS crm_account_status
FROM crm_salesforce_orders_dataset
WHERE orderDate >= date_sub(current_date, 90)
),
orders AS (
SELECT
d.order_date,
d.transaction_id,
CASE
WHEN coalesce(d.checkout_type_field, d.checkout_type_evar) IN ('guest', 'registered')
THEN coalesce(d.checkout_type_field, d.checkout_type_evar)
WHEN d.authentication_method IS NOT NULL AND d.authentication_method <> 'none' THEN 'registered'
WHEN c.crm_account_status IN ('guest', 'registered') THEN c.crm_account_status
ELSE 'unclassified'
END AS checkout_type,
coalesce(d.payment_type, '(not set)') AS payment_type,
coalesce(d.device_category, '(not set)') AS device_category,
coalesce(d.channel_of_purchase_field, '(not set)') AS channel_of_purchase
FROM deduplicated_orders d
LEFT JOIN crm_order_enrichment c
ON d.transaction_id = c.transaction_id
)
SELECT
order_date,
payment_type,
device_category,
channel_of_purchase,
count(DISTINCT transaction_id) AS total_orders,
sum(CASE WHEN checkout_type = 'guest' THEN 1 ELSE 0 END) AS guest_orders,
sum(CASE WHEN checkout_type = 'registered' THEN 1 ELSE 0 END) AS registered_orders,
sum(CASE WHEN checkout_type = 'unclassified' THEN 1 ELSE 0 END) AS unclassified_orders,
round(100.0 * sum(CASE WHEN checkout_type = 'guest' THEN 1 ELSE 0 END)
/ nullif(count(DISTINCT transaction_id), 0), 2) AS guest_checkout_rate_pct
FROM orders
GROUP BY order_date, payment_type, device_category, channel_of_purchase
ORDER BY order_date DESC, total_orders DESC;Source Data
Digital Analytics (GA4 / Adobe) + CRM (Salesforce) account enrichment
Dependencies
Prerequisite: List the dependencies required for this KPI
Report Attributes
Checkout Type (Guest / Registered) Device Category Channel of Purchase Payment Type
Recommended Reporting Views
Segment Eligibility
true
Governance
Governance
GitHub
catalog/kpis/guest-checkout-rate.yml