Analytics & Attribution Playbook (B2C edition)
Count every order once, judge channels on profit, and test what the ad platforms claim
Eight steps to set a break-even ROAS, fix ecommerce events, get EU consent right, send orders from your server, measure app installs after Apple’s privacy changes, reconcile store, GA4 and platform numbers, and run holdout tests. One fictional consumer brand is worked through every step.
By Saroj Jha, founder of AAJ. 19 min read, 8 steps, 8 figures, 20 references.
To see what drives profit at a consumer brand, count orders in your store, judge every channel against the return it needs to break even, and test what the ad platforms claim before you move budget. Tracking that holds up under consent rules and Apple’s privacy changes keeps those inputs honest.
What you will build
- Step 1 A break-even line Contribution per order and the ROAS every channel must beat
- Steps 2 to 5 Tracking that holds up Clean events, consent mode, server-side orders and app postbacks
- Step 6 One number per decision Store, GA4 and platform counts reconciled every month
- Steps 7 and 8 Tests and a rhythm Holdouts, an MMM-lite and a fixed review cadence
Worked example: Example Co., a fictional seed-stage brand selling refillable cleaning products online, runs through every step. Pairs with the Tracking Plan and UTM Builder and the MMM-Lite Starter Kit (free templates).
This playbook is for DTC brands, online stores, consumer subscriptions and B2C apps that spend on paid channels such as Meta, Google, TikTok, creators and affiliates. The usual symptom: the ad platforms report different numbers from your store and from GA4, attribution has felt messy since Apple’s privacy changes, and budget decisions fall back on last click or gut feel. If you sell to businesses through a sales team, the B2B edition follows leads and pipeline instead.
Step 1 of 8
Decide what counts as revenue, and what an order is worth
Settle three things in writing before you touch a tag. The first is the revenue event: an online purchase, a subscription start or a first in-app purchase. The second is the source of truth for revenue: the store platform, billing system or app backend that records every order, refund and renewal. Analytics tools and ad platforms estimate; this system counts, and every other number is checked against it (Step 6).
The third is what an order is worth after the costs that rise with it. Return on ad spend (ROAS) measured on revenue ignores those costs, so a channel can look profitable on the dashboard and lose money on every order. Take an order’s revenue and subtract product cost, pick, pack and shipping, payment fees, and the discounts and returns it carries: what is left is its contribution margin. Revenue divided by contribution is your break-even ROAS. Profit on ad spend (POAS) states the same test as contribution divided by spend, which breaks even at 1.
If repeat orders carry your profit, as they do for most subscriptions, decide how long you are willing to wait for an ad to pay back, and set the line on the contribution earned over that period rather than on the first order alone. The Unit Economics Calculator works out payback from your own retention.
Example Co. Average first order
Order revenue $65.00
- Product cost −$21.00
- Pick, pack and shipping −$10.00
- Payment fees −$2.00
- Discounts and returns −$4.00
Contribution per order $28.00
43% of revenue
Where each $65 goes, drawn to scale
- Product cost $21
- Pick, pack and shipping $10
- Payment fees $2
- Discounts and returns $4
- Contribution $28
Break-even ROAS
2.32 = $65 revenue ÷ $28 contribution
Below this, an ad loses money on the first order, whatever the platform reports.
Show the numbers as a table
| Line | Per order |
|---|---|
| Order revenue | $65 |
| Product cost | $21 |
| Pick, pack and shipping | $10 |
| Payment fees | $2 |
| Discounts and returns | $4 |
| Contribution | $28 (43%) |
| Break-even ROAS | 2.32 |
Example Co.’s average first order, from Step 1. Example Co. and its numbers are fictional.
Step 2 of 8
Map the funnel to events and fix the tracking
Name each stage of the shopping journey after the event that records it, so every report counts the same thing. Google Analytics 4 has a recommended ecommerce event for each stage, from view_item_list on a collection page through view_item, add_to_cart, begin_checkout and add_payment_info to purchase (Google for Developers[1]; Figure 2).
The purchase event carries the most weight. Google requires a transaction_id with it, and that ID is what lets GA4 drop a second copy of the same order, for example when a shopper reloads the confirmation page. Use the order number: one fixed or empty ID makes GA4 merge different orders and undercount them. Set value to the items’ price times quantity, without shipping or tax, and always send currency with it, or revenue is not computed correctly[2],[3]. Deduplication by transaction ID works for web data streams, not app streams, so an app needs its own check.
Then tag every link you control with UTM parameters under one written rule, so a channel is spelled the same way every time. The tracking setup post walks through the GA4 settings.
An event to send1 The shopper’s path, room by room
- 1
Ad click arrives
-
utm_source -
utm_medium -
utm_campaign
Which campaign sent the session?
-
- 2
Collection page
-
view_item_list -
select_item
Which products get noticed?
-
- 3
Product page
-
view_item -
add_to_cart
Does the page sell the product?
-
- 4
Cart
-
view_cart -
begin_checkout
How many carts turn into checkouts?
-
- 5
Checkout
-
add_shipping_info -
add_payment_info
Where does checkout lose people?
-
- 6
Order confirmation
-
purchase
Required with it:
transaction_id,value,currencyanditemsWhat did it earn, and from where?
-
Event names are Google Analytics 4’s recommended ecommerce events[1]; purchase parameters from Google’s event reference[3].
Step 3 of 8
Collect consent properly, and keep measuring after a no
In the EU, storing or reading information on a visitor’s device needs their consent unless it is strictly necessary for a service they asked for, and the European Data Protection Board’s guidelines make clear that the rule covers similar technologies as well as cookies[4]. Analytics and advertising tags fall under it.
Google adds its own requirement. Since March 2024, to keep using measurement, ad personalization and remarketing features for visitors in the European Economic Area, advertisers must collect their consent and pass it to Google[5]. Consent mode does the passing. Its second version sends four signals, adding ad_user_data and ad_personalization to the original ad_storage and analytics_storage (Figure 3).
It runs in one of two ways. In basic mode Google’s tags do not load until the visitor chooses, and a reject sends nothing. In advanced mode the tags load with consent denied by default and send measurements without cookies until the visitor agrees, and Google models the missing conversions with a model specific to your account rather than a general one[6]. Advanced mode recovers more of the picture, but it sends data before anyone has said yes, so the choice is a legal judgment as much as a technical one.
Visitor in Germany clicks “Reject all” v2: four signals
-
ad_storageAdvertising cookies and device identifiers Denied -
analytics_storageAnalytics cookies, such as visit duration Denied -
ad_user_dataSending user data to Google for advertising Denied -
ad_personalizationPersonalized advertising, such as remarketing Denied
Basic mode
Google tags stay blocked until the visitor chooses.
After a reject: nothing is sent.
Conversion modeling in Google Ads uses a general model.
Advanced mode
Google tags load with consent set to denied by default.
After a reject: measurements without cookies are sent.
Modeling uses a model specific to your account.
Signal descriptions and mode behaviour from Google’s consent mode documentation[6].
Step 4 of 8
Send each order from your server as well as the browser
A browser pixel misses orders: ad blockers and browser privacy settings stop some of them before they are sent. Sending the same orders from your store’s backend fills those gaps, which is why Meta recommends running its Conversions API alongside the Meta Pixel rather than instead of it[7].
Sending each order twice only works if the platform can tell the two copies apart from two orders. Meta treats a browser event and a server event as one when they carry the same event name and the same event ID and arrive within 48 hours of each other, and it keeps whichever arrived first (Figure 4). Use the order number as the ID on both sides. Server events can be sent up to seven days after the order; a request containing an older event fails as a whole[8].
Google Ads has its own route. Enhanced conversions sends the customer’s email address or phone number with the conversion, normalized and hashed with SHA-256, and Google matches it to signed-in Google accounts that engaged with your ads[9].
Browser Meta Pixel on the order page
- event_name
- Purchase
- event_id
- 10482
Server Store backend, Conversions API
- event_name
- Purchase
- event_id
- 10482
Meta checks
- Same
event_nameand sameevent_id - Received within 48 hours of the first
- Keeps the one that arrived first
1 purchase counted
Without a shared ID: the browser event says 10482, the server event says srv-7f3a, and the order counts twice.
Deduplication rules from Meta’s developer documentation[7]. Order number 10482 is Example Co.’s. Example Co. and its numbers are fictional.
Step 5 of 8
Measure app installs through Apple’s attribution
Since iOS 14.5, an app needs the person’s permission through Apple’s App Tracking Transparency prompt before it can track them or read the device’s advertising identifier[10]. Installs from people who decline carry no identifier an ad network can match. What remains is Apple’s own attribution: AdAttributionKit, available from iOS 17.4 for apps on the App Store and alternative app marketplaces, and the older SKAdNetwork, which works alongside it; Apple now points app campaigns to AdAttributionKit[11],[12].
Both report an install to the ad network as signed postbacks that contain no user or device data, at least 24 to 48 hours after the event, and include detailed values only when Apple’s crowd-anonymity thresholds are met[13]. An install can send up to three postbacks, one per conversion window. Only the first, which covers the first two days, can carry a fine value from 0 to 63; the later two carry low, medium or high[14]. So the work is deciding what those values mean: which actions in the first two days predict a customer worth having, and what counts as low, medium and high after that (Figure 5).
Days after install
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
Postback 1 Days 0 to 2
A fine value from 0 to 63 if the install clears Apple’s higher privacy tiers, otherwise low, medium or high. Arrives 24 to 48 hours after the window closes.
Example Co. 10 account created, 20 refill plan chosen, 40 and up a first refill ordered, higher for bigger orders
Postback 2 Days 3 to 7
Low, medium or high only. Arrives 24 to 144 hours after the window closes.
Example Co. High: a refill ordered. Medium: plan active. Low: app opened
Postback 3 Days 8 to 35
Low, medium or high only. Arrives 24 to 144 hours after the window closes.
Example Co. Same map as postback 2
Show the numbers as a table
| Postback | Window | Value it can carry | Arrives after the window closes |
|---|---|---|---|
| 1 | Days 0 to 2 | Fine (0 to 63) or coarse | 24 to 48 hours |
| 2 | Days 3 to 7 | Coarse only | 24 to 144 hours |
| 3 | Days 8 to 35 | Coarse only | 24 to 144 hours |
Apple’s AdAttributionKit and SKAdNetwork documentation[11],[13]; day ranges and delays as listed in Adjust’s SKAdNetwork 4 guide[14]. Value map: Example Co. and its numbers are fictional.
Step 6 of 8
Reconcile the numbers, and match each view to a decision
Each month, set three counts side by side: orders in your store, purchases in GA4, and the purchases each ad platform claims (Figure 6). They will not match, and the gaps tell you something. GA4 counts fewer than the store, because some visitors decline consent and some browsers block tags. The platforms together claim more, because each credits the orders it touched under its own rules, so Meta and Google can both claim the same order. Watch the two ratios over time: a sudden move in either is a tracking fault until proven otherwise.
Choosing an attribution model will not settle which number is right. Since November 2023 GA4 has offered three: data-driven, paid and organic last click, and Google paid channels last click. First click, linear, time decay and position-based are no longer available, and all three exclude direct visits unless the path was direct only[15]. Use each view for the decision it can support:
| Decision | View to use | Why |
|---|---|---|
| Revenue, orders and contribution | Store or billing system | It records every order and refund |
| Funnel and on-site changes | GA4 | One rule for every channel, though consent gaps lower its counts |
| Ads, ad sets and creative within one platform | That platform’s own reporting | Fast and detailed, but it grades its own work |
| Budget between channels | Holdout tests and an MMM-lite (Step 7) | The only views that measure what the spend caused |
- 4,000 Shopify Every order, the source of truth
- 3,300 GA4 Purchases it recorded
- 5,000 TikTok 600 Google 1,500 Meta 2,900 Ad platforms Purchases each one claims
- 700 fewer in GA4 (82.5%): mostly visitors who declined consent and browsers that block tags
- 1,000 more claimed by the platforms (125%): each counts orders it touched under its own rules, so one order can be claimed twice
Show the numbers as a table
| Source | Orders or purchases | Against Shopify |
|---|---|---|
| Shopify | 4,000 | 100% |
| GA4 | 3,300 | 82.5% |
| Meta (claimed) | 2,900 | |
| Google (claimed) | 1,500 | |
| TikTok (claimed) | 600 | |
| All platforms (claimed) | 5,000 | 125% |
Heights are drawn to scale. One month of Example Co.’s orders. Example Co. and its numbers are fictional.
Step 7 of 8
Test what the channels claim
Only an experiment shows what a channel caused. In 15 large advertising experiments at Facebook, the observational methods advertisers commonly rely on generally overestimated what the ads achieved compared with randomized tests, and in some cases significantly underestimated it[16]. The test that fits most consumer brands is a holdout: switch a channel off, or cut it, for a matched group of regions or customers for a few weeks, and compare orders there with orders elsewhere. A scale test does the reverse, raising spend in some regions to see whether orders follow.
Write the plan before you start: the channel, the regions, the length, the metric (store orders, not platform conversions) and the result that would change your budget, set against your break-even ROAS from Step 1. Divide the extra revenue the test shows by what the channel cost, and you have its incremental ROAS. The incrementality testing guide covers matching regions and reading the result.
Tests are slow: one or two channels a quarter. A marketing mix model fills the gaps between them. It is a regression of weekly orders on weekly spend by channel, and it estimates each channel’s contribution without tracking anyone. A light version is worth building once you have about a year of weekly data, spend that varied, and three or more channels; calibrate it with your test results. Google’s open-source Meridian, for example, supports calibration with experiments and runs at national or regional level[17]. The MMM-Lite Starter Kit sets up a simpler version.
Claimed by the platform Tested incremental ROAS Tested, below break-even Break-even ROAS, 2.32 (Step 1)
Meta prospecting, web $30,000 a month
Claimed 6.3 Tested 2.6Google brand search $4,000 a month
Claimed 11.4 Tested 0.65Google Shopping and Performance Max $12,000 a month Not tested yet
Claimed 4.3TikTok $8,000 a month Not tested yet
Claimed 4.9
Return on ad spend: revenue per $1 of spend
Show the numbers as a table
| Channel | Monthly spend | Claimed ROAS | Tested ROAS |
|---|---|---|---|
| Meta prospecting, web | $30,000 | 6.3 | 2.6 |
| Google brand search | $4,000 | 11.4 | 0.65 |
| Google Shopping and Performance Max | $12,000 | 4.3 | Not tested yet |
| TikTok | $8,000 | 4.9 | Not tested yet |
| Break-even (Step 1) | 2.32 | 2.32 |
Claimed ROAS is each platform’s reported revenue divided by spend; tested ROAS comes from Example Co.’s holdouts in Step 7. Example Co. and its numbers are fictional.
Step 8 of 8
Run one dashboard and a fixed review rhythm
Put the numbers from Steps 1 to 7 on one screen with three tabs: a performance overview built on store data and contribution, a channel view that sets each platform’s claims beside its tested result, and an experiment log of what was tested, what it showed and what changed (Figure 8). Lead with marketing efficiency, store revenue divided by all ad spend, and with contribution after marketing: no single platform’s attribution can inflate either.
Then decide who may change the plumbing. Name one owner each for analytics events, pixel and server settings, consent configuration, dashboard logic and the attribution settings in each ad platform, and log every change, because an unlogged change in tracking looks exactly like a change in performance.
- Overview
- Channels
- Experiments
Last month, Example Co.
- Revenue $260,000 From Shopify, after refunds
- Orders 4,000 2,400 new, 1,600 returning
- Marketing efficiency 4.33 Revenue ÷ $60,000 total ad spend
- Cost per new customer $25 $60,000 ÷ 2,400 new customers
- Contribution after marketing $52,000 $112,000 at $28 an order, less ad spend
- Weekly, 30 minutes Spend against budget, orders and contribution, tracking alerts. Decide small shifts and creative changes.
- Monthly, 60 minutes The reconciliation from Step 6 and test results. Decide next month’s budget split and the next test.
- Quarterly One new holdout test, the model refresh, and a review of who can change what.
Show the numbers as a table
| Measure | Last month | How it is worked out |
|---|---|---|
| Revenue | $260,000 | From Shopify, after refunds |
| Orders | 4,000 | 2,400 new, 1,600 returning |
| Marketing efficiency | 4.33 | Revenue ÷ $60,000 total ad spend |
| Cost per new customer | $25 | $60,000 ÷ 2,400 new customers |
| Contribution after marketing | $52,000 | $112,000 at $28 an order, less ad spend |
Example Co.’s dashboard, first tab. Contribution uses the $28 per order from Step 1. Example Co. and its numbers are fictional.
What changes by stage?
Pre-seed
Your store’s reports are your analytics. Send a clean purchase event with the order number, tag every link, and know your contribution per order (Steps 1 and 2).
Seed
Once paid spend matters: consent mode for EU visitors, server-side purchases, a monthly reconciliation and a first holdout test on your largest channel (Steps 3, 4, 6 and 7).
Series A–B
An MMM-lite calibrated by a test each quarter, a conversion-value map for any app, and named owners for every tracking setting (Steps 5, 7 and 8).
What mistakes should I avoid?
- Judging channels on revenue ROAS. Compare each with the break-even ROAS your contribution margin sets (Step 1).
- A purchase event without the order number. Reloads count as new orders (Step 2).
- A cookie banner that is not wired to the tags. Test it from an EU address (Step 3).
- Browser and server events with different IDs. Meta cannot match them, so orders count twice (Step 4).
- Adding up what the platforms claim. Count orders in the store (Step 6).
- Cutting or scaling a channel on attribution alone. Run a holdout first (Step 7).
Common questions
If I send events from my server, do I still need a cookie banner?
Yes, if you have visitors in the EU. The consent rule covers storing or reading information on the visitor’s device, and the European Data Protection Board’s 2024 guidelines confirm[4] it reaches tracking pixels and tracking links as well as cookies. Server-side sending changes the route the data takes, not whether the browser identifiers it carries needed consent. Pass each visitor’s consent choice to your server and forward to ad platforms only the events that choice covers.
Is GA4 enough, or do I need a paid attribution tool?
For most seed-stage consumer brands, GA4 alongside your store’s order data and the platforms’ own reports is enough. Multi-touch attribution tools follow the same clicks and cookies that consent choices and Apple’s rules remove, so they cannot see the journeys GA4 misses, and none of them measures what a channel caused. Spend money on tests first; consider a tool once you run more channels than you can test, and ask its vendor how it checks its numbers against experiments.
How much do I need to spend before a lift test is worth running?
Less than many founders expect. Google’s Conversion Lift based on users needs a campaign budget of at least $5,000, at least 1,000 observed conversions in the account and, Google recommends, 14 days or more[18], and it is not available to every account. A holdout you run yourself across regions has no minimum spend, but the channel’s likely effect must be larger than the normal week-to-week swing in orders in those regions; if it is not, run longer or test a bigger change.
How do I track subscription renewals and repeat orders?
Send them from the system that records them, not from a browser, because a renewal or a reorder in an app happens without a web page. GA4’s Measurement Protocol accepts these server-to-server events to add to your tagging, not replace it, and Google now points new server-to-server integrations to its Data Manager API[19]. Mark each purchase new or returning with GA4’s customer_type parameter[3] so first orders and repeat orders can be reported apart.
Should my app show Apple’s tracking prompt?
Only if the app tracks in Apple’s sense: linking data from your app with other companies’ data for targeted ads or ad measurement, or sharing it with data brokers[10]. If it does, you need permission first, and without it the advertising identifier reads as all zeros[20]. AdAttributionKit and SKAdNetwork need no prompt and work whatever the person chose[11]. Apple also forbids fingerprinting, deriving data from a device to identify it, including by SDKs inside your app.
Should I ask customers how they heard about us?
Yes, as a complement to tracking. One question after checkout, “How did you first hear about us?”, with a free-text box, picks up word of mouth, podcasts, creators and group chats that leave no click to track. Treat the answers as a direction rather than a count, since only some customers answer and memory is imperfect. Code the free text into channels each month with the Self-Reported Attribution Coder and compare the shares with your test results.
Use with this playbook
Playbooks
- Paid Media Budget Allocation Playbook: Turn tested ROAS into a channel split with a target cost per customer.
- Website and Conversion Optimization Playbook (B2C edition): Fix the funnel stages your events in Step 2 expose.
- Customer Onboarding and Retention Playbook: Grow the repeat orders that decide your payback line.
Articles
- Tracking Setup for Startups: GA4, UTMs and Events Done Right: Day-one GA4 settings, key events and UTM rules.
- Incrementality Testing for Startups: Prove Your Ads Actually Work (2026 Guide): Design a geo holdout and read it honestly.
- MMM-Lite: Marketing Mix Modeling for Startups (No Data Science Team Required): When a small media mix model is worth building.
- Privacy and Advertising Rules for Startup Marketers: What to Check Before You Launch: Consent and ad rules beyond the EU.
Templates and tools
- Tracking Plan and UTM Builder: Events, parameters and UTM rules for Step 2.
- MMM-Lite Starter Kit: A media mix model in Python for Step 7.
- Unit Economics Calculator: Contribution, payback and lifetime value for Step 1.
- Self-Reported Attribution Coder: Code “how did you hear about us?” answers into channels.
References
- Google for Developers. “Measure ecommerce,” Google Analytics 4 developer guide. Official documentation. developers.google.com
- Google Analytics Help. “[GA4] Minimize duplicate key events with transaction IDs.” Official documentation. support.google.com
- Google for Developers. “Recommended events: Google Analytics 4 event reference.” Official documentation. developers.google.com
- European Data Protection Board (2024). “Guidelines 2/2023 on Technical Scope of Art. 5(3) of ePrivacy Directive,” version 2.0, adopted 7 October 2024. edpb.europa.eu
- Google Tag Manager Help. “Mapping ad_storage to ad_user_data.” Official documentation. support.google.com
- Google for Developers. “Consent mode overview.” Official documentation. developers.google.com
- Meta for Developers. “Handling Duplicate Pixel and Conversions API Events.” Official documentation. developers.facebook.com
- Meta for Developers. “Server Event Parameters,” Conversions API. Official documentation. developers.facebook.com
- Google Ads Help. “About enhanced conversions.” Official documentation. support.google.com
- Apple Developer. “User privacy and data use.” App Store guidance. developer.apple.com
- Apple Developer. “AdAttributionKit.” Official documentation. developer.apple.com
- Apple Developer. “SKAdNetwork,” StoreKit. Official documentation. developer.apple.com
- Apple Developer. “Receiving ad attributions and postbacks,” AdAttributionKit. Official documentation. developer.apple.com
- Adjust Help Center. “How SKAdNetwork 4 works.” Vendor documentation of Apple’s conversion windows. help.adjust.com
- Google Analytics Help. “[GA4] Get started with attribution.” Official documentation. support.google.com
- Gordon, B. R., Zettelmeyer, F., Bhargava, N. and Chapsky, D. (2019). “A Comparison of Approaches to Advertising Measurement: Evidence from Big Field Experiments at Facebook.” Marketing Science, 38(2), 193–225. doi:10.1287/mksc.2018.1135
- Google. “Meridian.” Open-source marketing mix modeling framework, GitHub repository. github.com
- Google Ads Help. “Set up Conversion Lift based on users.” Official documentation. support.google.com
- Google for Developers. “Measurement Protocol (Google Analytics 4).” Official documentation. developers.google.com
- Apple Developer. “advertisingIdentifier,” AdSupport framework. Official documentation. developer.apple.com
Count the orders once, then let tests move the budget
Want a second pair of eyes on your tracking, consent setup and first holdout test before you move spend? AAJ can review them against your own store data.
Or start on your own with the free Tracking Plan and UTM Builder.