The Movement Athlete · Growth Intelligence

Full Channel Analysis — every source, verified & combined

A CMO-grade read on where the paid money goes and what it returns — now built on direct live access to every source, including read-only API access to both Stripe accounts. Where a number can't be trusted, it carries a confidence tag: CONFIRMED MODELLED UNVERIFIED. The honest headline: measurement is the binding constraint, so most channel verdicts are UNVERIFIED — two are not.

FINAL · 7 Jul 2026 · use the June / July toggle below — July MTD = since the Lifetime launch, June = pre-launch baseline · Meta reconciles to Ads Manager to the penny · attribution live since 1 Jul · run through the Growth Fleet + Skeptic gate
📅 Month
Showing July month-to-date (1–7 Jul, 7 days) — the lifetime cart, attribution, and the recent changes all went live this month. This is the current setup. Per-day rates shown because July is 7 days vs June's 30. Showing June (full month, 30 days) — the pre-launch baseline: old prospecting, no attribution yet. Compare against July to see what the launch changed.
£3,108£3,136
Paid spend · July 1–7 = ~130% of the $3k/mo budget in 7 daysPaid spend · all June (~£105/day)
~$11.1K
Total MRR (the real north star) — web $8,265 (Stripe, 572 subs) + app $2,791 (RevenueCat, 191) · net of already-cancelling subs
~£2.2K~£0.1K
the ads' actual tracked return (~0.72×) — not the $11K saleJune ads returned almost nothing (3 sales / £1.9k)
$10.9K$7.5K
Web sales · July (Stripe) — ~$10.3K one-time lifetime + ~$0.9K recurringWeb sales · June (Stripe) — recurring renewals (148)
72%
Checkout completion (real card-entry attempts) — healthy, not the leak
~£1,355~£1,097
app-install spend · July 7d → 0 sales (cut now)app-install spend · all June → 0 sales
⚡ Fastest win — 15 minutes, no code
Fix the email deliverability issue (broken DMARC) →
Domain publishes three conflicting DMARC records; inbox providers ignore the policy. ~15-min DNS change at SiteGround. Step-by-step guide →
💷 Full ad-spend breakdown (June vs July, verified to the penny) →
Every pound by channel + what each month's spend returned, with the June / July toggle. Open the Paid ads analysis tab →

TL;DRThe CMO read — verified against live data, 7 Jul

🔴 The one finding everything else hangs on: attribution is brand-new and hasn't reached the sale yet.

Source tracking only went live ~1 July (alongside the lifetime cart). Everything before that carries no source — not a bug, the feature simply didn't exist, and most completions are subscription renewals (a rebill has no marketing source).

👉 So don't read any blended "% unknown" over old data.

In the two weeks since go-live, the tracking is firing at the top — ~55% of checkout sessions carry a utm_source, ~34% a gclid.

But it isn't surviving to the completed sale yet — only ~8 completed purchases carry a source. Two weeks + single-digit attributed sales is far too little to split purchases by channel, so most channel verdicts below are honestly UNVERIFIED.

The keystone (next tab): carry the tag through to the sale, then watch the weekly trend.

The channel scoreboard (what we can and can't say)

Channel / leverWhat the verified data showsConfidenceMove this week
Cheap-geo app-installs
Meta AP/SA/LATAM + Google UAC
£0.08 installs (Meta AP: 1,581 installs for £131), 0 purchases; AppsFlyer attributes $0 to Google and only $480 to all of Meta over 90d. UAC/UAC-style buys optimise to installs, not buyers.CONFIRMEDCUT today reallocate the ~£1,700/mo
Meta July-4 retargeting
warm: quiz leads, engaged, visitors
Tracked ROAS 2.4–4.8× on the winners (matches Meta Ads Manager) — but that's 3–6 conversions during a live sale where email hits the same people. Looks great; could be last-click credit for sales email would've closed anyway.UNVERIFIEDDon't scale blind run a holdout first (see cart actions)
Meta QLG prospecting
cold quiz lead-gen, ADV+
Pixel ROAS 0.03–0.13 — but it's optimising on Lead, not Purchase, so the algorithm is buying form-fillers, not buyers. Can't judge the channel until that's fixed.MODELLEDHOLD don't scale, don't cut — fix the event
Google web / Search1,809 checkout page-loads (most intent of any paid channel) → 0 same-session completions, 0 gclid sales. Could be cross-device loss, could be cheap-geo card declines, could be email stealing the close — or the traffic genuinely doesn't convert. Unknowable today.UNVERIFIEDBrand-defence only £25–30/day; run the 28-day test before any verdict
Email / ActiveCampaignHighest completion rate per checkout session (~6%). But under last-click it steals the source's credit — a Google/Meta buyer closed via recovery email books as "email."CONFIRMEDKeep never rank cold channels by last-click
Organic (app)Best buyers by far: ~2.9% install→purchase vs ~0.05% for paid installs (AppsFlyer 90d). Biggest single attributed revenue source ($3,968/90d).CONFIRMEDUnder-analysed find what drives it (ASO/brand/content)
The checkout itselfNot the bottleneck — real attempts complete at 72% (61/85). The "94% empty" figure is page-load ghost PaymentIntents, an instrumentation artifact. Real fix = create the PI at "Pay" click.CONFIRMEDHealthy see 🔬 Checkout autopsy
⚠️ Three ways this whole plan could still be wrong (read before acting)
  1. The constraint is offer×audience match, not the checkout. We tested the "checkout is the bottleneck" hypothesis forensically (see 🔬 Checkout autopsy): real attempts complete at 72% — the checkout is healthy. The thousands of "shell" PaymentIntents are page-load artifacts (no card ever entered), not recoverable hesitations. The real leak is upstream: recently-acquired install audiences (retargeted 7–14 days, but who don't know us yet) were sent a £297 lifetime offer and bounced or had their card declined (Google: 8 attempts, 8 declines, 0 sales). Fix the offer-to-audience match and the funnel before pouring more into ad channels.
  2. These are sale-period economics — they may not generalise. Every positive signal here (retargeting 2.4–4.8×, email closes, the strong MER) is measured during a $297 lifetime promo that closes 12 Jul. At normal $157 annual pricing, warm-retargeting urgency drops and these numbers likely contract. Steady-state performance is unverified and is the more important question for the 30 days after the cart.
  3. Fixing attribution might reveal paid is structurally weak, not just mis-measured. Once the tag survives to the sale, the source-tagged buyers might turn out to be mostly organic/direct/email-reactivated people who simply arrive without a UTM — not cross-device paid buyers. If so, the real lever is retention + email, not paid scaling. Have a plan for a worse picture, not just a better one.
✅ The two calls that ARE safe to make now

1. Cut cheap-geo app-installs today (Meta AP/SA/SP-LATAM + Google UAC). Unambiguous: £0.08 junk installs, $0 attributed revenue over a full 90-day window. No measurement fix needed. 2. Pause the losing retargeting set (LLU, 0.51×) and redirect that budget — but into a holdout-tested retargeting push, not a blind scale.

📖July 1–7 — the full analysis & the pivot

The complete story of the first week of July, start to finish, with the data behind every step — nothing hidden. What we did, what happened, why, the answers to every question that came up, and the plan from here.

🎯 The story in one line

We drove cheap app-installs, then retargeted those recent installs (last 7–14 days) with a £297 lifetime offer — but those people don't know TMA yet, so it's the wrong offer for them — while spend ran at ~5.7× the intended daily pace.

The checkout was never the problem (real attempts convert at 72%). The two real issues were the offer×audience match and the spend controls.

Lifetime was meant to build runway — instead ~£3–4k went to acquiring audiences that couldn't convert it. All fixable.

What happened, step by step

#The stepWhat the data says
1We bought cheap app-installs to build volume — the cheapest traffic, mostly low-cost geos (Asia-Pacific, LATAM, SA). These users install from an ad and mostly never open or engage.Meta app-install AP: 1,581 installs at £0.08 each. Google ~90% cheap-geo Universal App Campaigns. volume, not relationship
2We then retargeted those recent installs (7–14 days) with the £297 LIFETIME offer.Retargeting £1,362 → 14 tracked sales. The pixel calls them "warm," but they have no relationship with TMA — they installed and never learned the product. warm by pixel, unaware by relationship
3People who don't know us yet can't say yes to a £297 lifetime. It's the highest-commitment, highest-trust offer we sell — for someone who already loves the product, not someone who just installed it.Google-sourced checkout: 8 attempts, 8 card declines, 0 sales, every one a £297 charge. Every real buyer already knew us (warm list / email / direct). the mismatch, proven
4Meanwhile spend ran ahead of budget — a whole month's budget in one week, peaking over the weekend.£3,108 in 7 days = ~130% of the $3k/mo budget, ~5.7× the intended daily pace. a control gap
5The sale still "looked" like 2.25× ROAS — because the lifetime offer landed on the warm email list and existing members, and the ads got the credit.Of ~£9k promo revenue, ~45–55% was the ~44k email list, ~20–25% existing members; the ads' own tracked return was ~£2.2k (≈0.72×). the offer worked; the ads didn't
6And it wasn't the checkout's fault. The "thousands didn't convert" is a tracking artifact.Of 5,253 July PaymentIntents, 98% are page-load ghosts; of 85 real card-entries, 61 paid = 72% completion. checkout healthy

What we can say — separating fact from hypothesis (the level-headed version)

✅ CONFIRMED (traceable to a number)
  • The payment step works — 72% completion on real card-entries (n=85). Don't rebuild the checkout.
  • £3,108 spent in 7 days = ~130% of the monthly budget; cheap-geo app-installs returned 0 sales.
  • "2.25× ROAS" is a promo MER, not ad ROAS — it credits the ads for email/organic sales. The ads' tracked return was a floor of ~0.72× (retargeting slice 1.63×). True value sits somewhere in 0.72×–2.25× and is unknowable until measurement is fixed.
🔧 CONFIRMED DEFECT — fix regardless of the "healthy" verdict

The checkout mints a PaymentIntent on page-load. This fabricates the ghost rows and blinds every attribution number in this report. It's the keystone fix (create the PI at "Pay" click).

💡 LEADING HYPOTHESIS — not yet proven: offer × audience mismatch

The best-supported story: we retargeted recent installs (7–14d) + cheap-geo clicks — who don't know TMA yet — with a £297 lifetime, a customer offer. Every real buyer already knew us; Google's 8 attempts all declined.

Why it's a hypothesis, not a fact: it's inferred from the campaign mix over ~1-week-old, 97%-blind attribution — a "balked at £297" is currently indistinguishable from a "junk page-load ghost."

The test that settles it: run the same audience at a first-yes offer (£9.99 / free trial) vs £297. If the first-yes converts materially better → mismatch confirmed. If both stay near zero → the audience is genuinely junk. Either way you'll know, cheaply.

Two more judgement calls (sound, but not data-readouts)
  • Buying more traffic for a leaky funnel is backwards. ~60% drop on quiz screen 1 is a funnel problem; another channel just loses more people at the same door. Fix the screen first. (Caveat: the funnel events are currently broken, so the exact drop-off needs the instrumentation fix to trust.)
  • Six analytics tools, but the two funnels that decide MRR aren't visible end-to-end. Making web quiz→paywall→pay and app install→onboarding→paywall→subscribe visible and converting is the north star.

The questions that came up — the short answers

QuestionShort answer
Did ~5k land on checkout and none convert — is the checkout broken?NO 98% are page-load ghosts; real attempts complete at 72%
Are there ~12 failed transactions from Google? Why?~8 verified all £297, all card-side declines (cheap-geo cards). Not a bug
Is ~6k completely unattributed?No — ~2k and 97% are ghosts; only ~52 real unknown buyers
Do we switch to a different checkout for the promo?NO it works — switching risks the sales we're getting
Was it an offer×audience mismatch (recent installs → lifetime)?YES they don't know us yet — needs a trial / £9.99 / 50% off, not lifetime
Do we allocate more ad budget this month?NO freeze paid; more spend burns the runway lifetime was meant to build

Full forensic detail (all 5,253 PaymentIntents classified, decline reasons, source-by-source) is in the 🔬 Checkout autopsy tab. Spend by channel & month is in the 💷 Paid ads analysis tab.

The pivot — what to do, in order

#The moveWhy
1Freeze paid. Cut app-installs + cold prospecting + Google UAC now; keep only warm retargeting capped to the 12 Jul cart close; then near-£0. No extra budget.stops the bleed; keeps runway
2Match offer to audience going forward. Audiences that don't know us yet get a first-yes: 7-day free trial / £9.99 get-started / 50% off. Lifetime & annual = warm/existing only.the core error, fixed as a rule
3Instrument the two funnels (web quiz→paywall→pay; app install→onboarding→paywall→subscribe) — the RN analytics brief. 1–2 weeks.can't optimise what you can't see
4Optimise the biggest leak first — the ~60% drop on quiz screen 1. Measure lead→trial weekly.fix the funnel before buying traffic to it
5Fix deliverability (DMARC, ~15 min) so the warm list — the audience that actually converts — reliably lands.protects the channel that works
6Put spend controls in place — hard daily caps, weekend lock, a daily spend alert.so a month's budget can't run ahead unseen again
7Only then, reintroduce paid — matched offers, on a measurable funnel, scaling only what shows a real Cost-per-Trial.paid works once the funnel + measurement do

The straight calls

DecisionCallWhy
Allocate more ad budget this month?NOLifetime existed to build runway; more spend on audiences that can't convert burns it. ~£0 after the warm cart closes.
Switch checkout for the promo?NOit converts real attempts at 72%; switching risks live sales
Start affiliate acquisition now?NOT NOWa good later lever, but it splits focus before the core funnels are shipped. Focus beats breadth this month.
Reintroduce paid?AFTER the funnels convertwith matched offers, on a measurable funnel, scaling only what shows a real Cost-per-Trial

Governance — so this can't recur

ControlThe rule
One north-star metricMRR, and its driver lead→trial per funnel — reviewed weekly. If work doesn't move one of these, it's a distraction.
Paid-spend gateHard in-platform daily caps + weekend lock (caps set by Fri 5pm) + any change >£20/day pre-approved + a daily automated spend alert (buildable free off the Meta API). A month's budget can't vanish in a weekend unseen again.
No-new-tools ruleNo new tracking tool, channel, or tactic until the two funnels are visible end-to-end.
Definition of "done"A moved metric, not "it's live / it's tested / it's running."
Offer×audience ruleAudiences that don't know us yet → free trial / £9.99 / 50% off. Lifetime & annual → warm/existing only.
The North Star for the rest of the month

Two funnels decide MRR:

  • Web: quiz → paywall → pay
  • App: install → onboarding → paywall → subscribe

Make them visible, then make them convert. Nothing else matters until they do — not a new checkout, not more ad channels. MRR is the only metric.

The sequence:

  • Week 1–2 — instrument both funnels (RN analytics brief)
  • Week 2–4 — optimise the leaks (the ~60% quiz screen-1 drop first)
  • Then — paid, with matched offers

💷Paid ads analysis — where the money goes

Every pound of measurable ad spend, by channel, for June (full month) vs July (month-to-date, 1–7 Jul). Meta verified to the penny against Meta Ads Manager; Google read via the GA4 link. Use the June / July toggle at the top for the per-month "what it returned" view below.

Ad spend — both months side by side

ChannelJune · full monthJuly · 1–7 (MTD)Note
Facebook / Meta£2,466£2,113acct act_710789699289834 "TMA NEW" · verified to the penny
  — Prospecting (QLG, cold)£1,860£2073 sales in June (ROAS 0.03) → turned down in July
  — Retargeting (July-4 sale)£0£1,362didn't exist in June · 14 sales, £2,223
  — App installs£427£5450 sales both months
  — Other£179£0
Google Ads£670£995via GA4 link (no native token; GA4-recorded cost)
  — UAC app installs£670£8100 sales — cheap geos
  — Remarketing£0£186July-4 promo
TikTok / Apple Search AdsTikTok not running; ASA spend not API-accessible (small)
TOTAL PAID£3,136£3,108June ~£105/day · July ~£444/day
The one-line read

June spent £3,136 over 30 days (~£105/day), mostly on cold prospecting that returned almost nothing. July has spent £3,108 in just 7 days (~£444/day) — 4× the daily rate — but redirected into retargeting (working) while still bleeding ~£1,355 on app-installs (0 sales). Similar monthly total, very different mix and pace.

📅What each month's spend returned — July (since launch)— June (pre-launch)

July (1–7, MTD) = since the Lifetime cart + attribution + the recent changes went live. This is the current setup — judge decisions on this. (7 days.)June (full month) = the pre-launch baseline: cold prospecting, no attribution yet. Use it to see what the launch changed. (30 days.)

Channel / lineSpend · July MTDTracked returnRead — July (since launch)
Meta — July-4 retargeting£1,36214 sales · £2,223the sale engine · winners 2.4–4.8×
Meta — QLG prospecting£2072 salesturned down — fine
Meta — app-install£5450 sales🔴 live bleed
Google — UAC cheap-geo~£8100 sales🔴 live bleed
Google — remarketing£186warmkeep
Total paid£3,108~£444/day (7d)
Web sales (Stripe, both accts)63 · $10,927the lifetime cart
🔴 The live bleed, right now (July)

Meta app-install £545 + Google UAC ~£810 = ~£1,355 in the first 7 days of July → 0 sales (~£195/day going out the door during the sale). Cut it, move it to the retargeting winners for the cart close.

Channel / lineSpend · JuneTracked returnRead — June (pre-launch)
Meta — QLG prospecting£1,8603 sales · ROAS 0.03🔴 the month's biggest line → almost nothing
Meta — app-install£4270 sales🔴 waste
Meta — other£1790 sales
Google — UAC cheap-geo£6700 sales🔴 waste
Meta/Google — retargeting£0didn't exist yet
Total paid£3,136~£105/day (30d)
Web sales (Stripe, both accts)148 · $7,522normal subscription renewals
What June tells you

Nearly the whole month's ad spend (£1,860 prospecting + £1,097 installs = £2,957 of £3,136) returned 3 tracked sales and 0 install-sales. The $7,522 web revenue was subscription renewals, not ad-driven. June is the "before" — the launch (July) is the correction, though app-installs are still bleeding.

🔬Checkout autopsy — what the 5,253 July PaymentIntents actually show

A forensic pass on the live lifetime checkout, pulled directly from Stripe. Several questions came up about whether the checkout is failing, why Google traffic isn't completing, and how much revenue is "unattributed." Here are the answers — straight from classifying every July PaymentIntent.

Every July checkout PaymentIntent, classified

What it actually isCount% of totalMeaning
Page-load ghosts — a PaymentIntent is auto-created the instant the checkout page opens, before any card is entered5,16598.3%not buyers — an instrumentation artifact
Real payment attempts — a card was actually entered851.6%the only rows that carry signal
  → succeeded (paid)61paid
  → failed (card declined)24card-side declines
3DS pending / canceled3
✅ The payment step is not the leak: real attempts complete at 61 / 85 = 72% CONFIRMED (n=85)

When a card is actually entered, the checkout clears it 72% of the time. The impression that "thousands landed and almost nobody bought" comes from the page-load PaymentIntents — 98% of rows are created before anyone touches a card.

So: don't rebuild the checkout — the payment step works. But "healthy" is a narrow claim: 72% is on n=85, a warm one-week cohort, and it only measures card-entry→success (the ghost rows erase how many people reached the page and left before entering a card — we can't see that yet). Re-verify after the fix below.

Two real things to fix (regardless of the word "healthy"):

  • The page-load PI — an instrumentation defect that fabricates every ghost row and blinds every attribution number in this report. Create the PI at "Pay" click (Measurement fix-plan, Rank 1). This is the keystone.
  • The 3DS declines — see below; worth a config check, not automatically "the card's fault."

The 24 real declines — mostly card-side, but check the 3DS ones

Decline reasonCountWhat it means
generic_decline6bank refused, no reason given (common on low-trust cards)
authentication_failure (3DS)6⚠️ check this failed 3-D Secure — could be the card, OR a 3DS/SCA config issue (return-URL, challenge iframe on mobile) that hits international cards hardest
card_velocity_exceeded4too many attempts too fast — fraud-flag behaviour
do_not_honor3bank hard-refused
incorrect_number / incorrect_cvc3mistyped card
transaction_not_allowed / insufficient_funds2card can't / won't cover a £297 charge

⚠️ This breakdown is all 24 real declines, not Google-specific. 6 of 24 were 3DS authentication failures — that sits on the checkout/SCA boundary, not unambiguously card-side. Worth a quick engineering check of the 3DS return-URL + challenge flow on mobile/international before concluding "it's all the cards." (n=8 for Google is a pattern, not a rate.)

Who completed vs who bounced — by source

SourceReal salesDeclinesPage-load ghostsRead
unknown (warm / direct / email)52152,024the owned audience — already knows TMA
ActiveCampaign (email)5068warm list
Facebook / Instagram401,021mostly warm retargeting
Google (cheap-geo installs)081,815low-awareness · cards decline the £297 charge
Audience Network / Threads00233no completions
The pattern in the data: an offer × audience mismatch
  • Every completed sale came from an audience that already knew TMA (warm/direct 52, email 5, retargeting 4).
  • The paid audiences that didn't convert were recently-acquired app-installs (retargeted 7–14 days) + cheap-geo clicks — "warm" by the pixel, but with no real relationship to TMA (installed from a cheap ad, never engaged).
  • Google-sourced traffic: 8 attempts, 8 declines, 0 sales, every one a £297 charge the card refused.

A £297 lifetime is the highest-commitment offer in the catalogue — it converts people who already love the product, not people who don't know it yet.

Those audiences convert on a low-friction first step — a 7-day free trial, £9.99 get-started, or 50% off month one — then move up the ladder. The takeaway is an offer×audience matching rule, not a checkout problem.

Q&A — the questions that came up, answered from the raw data

"Thousands landed on checkout and almost none converted — is the checkout broken?" → No

98% of the 5,253 July PaymentIntents are page-load ghosts (created before a card is entered). Of the 85 real attempts, 61 succeeded — a 72% real completion rate. Healthy checkout; the scary number is a measurement artifact.

"There are ~12 failed transactions from Google — is that right, and why?" → Directionally yes; it's the cards

Google July PaymentIntents: 1,824 total → 1,815 ghosts, 8 real attempts, 0 succeeded, all £297. Every decline is card-side (card_velocity_exceeded, do_not_honor, generic_decline, incorrect_number, authentication_failure) — the signatures of cheap-geo, low-trust cards refusing a large charge. Not a checkout error; a traffic-quality / offer-fit issue.

"Should we switch to a different checkout for the rest of the promo?" → No

It converts real attempts at 72%. Switching mid-cart would risk the sales that are landing to fix a problem that isn't there. The only change worth making is the page-load-PI instrumentation fix — and that can wait until after the cart closes.

"Around 6k appears completely unattributed — is that correct?" → It's ~2k, and 97% are ghosts

July "unknown source" = 2,093 PaymentIntents; 2,024 are page-load ghosts, leaving 52 real unknown buyers (the warm/direct audience arriving without a UTM). The page-load design inflates the "unattributed" figure. The number that matters: of ~63 real July web sales, only ~8 carry any ad source, because source-tracking went live only ~1 Jul and doesn't yet survive to the completed sale — which the Measurement fix-plan closes.

🔧The measurement fix-plan

This is the keystone. Until steps 1–3 land, every CAC / ROAS / Cost-per-Trial by channel is UNVERIFIED and can't drive a spend decision. Ranked by impact. Steps 1–2 are the upstream fix that makes everything downstream possible.

RANK 1 Stop minting PaymentIntents on page-load — create at "Pay" click, with metadata

The root of the 94%-shells + why the tag doesn't survive to the sale. Today the PI is created on checkout page-load, before the user has an identity or any UTM attached — so it can never carry attribution and it inflates "abandoned." Move stripe.createPaymentIntent() into the Pay-Now click handler. At that point inject into metadata: utm_source, utm_medium, utm_campaign, utm_content, gclid, fbclid, user_id, user_email_hash (sha256), session_id — pulled from sessionStorage captured at landing. (Note from the Skeptic: this fixes the same-session capture only. Cross-device/ATT/direct still feed "unknown" — so expect improvement, but the residual is MODELLED, not zero.)

RANK 2 Server-side first-touch persistence (the cross-device fix)

A user clicks a Google/Meta ad on mobile, checks out on desktop → the gclid/fbclid is gone. Fix: on first landing with any UTM/click-id, POST /attribution/first-touch storing {email_hash_or_session_id, utm_*, gclid, fbclid, landing_ts, landing_url}. On login/email entry, bind that record to user_id. At Pay-click (Rank 1), JOIN it into the PI metadata. Closes the multi-device gap for anyone whose email you capture before purchase — which is everyone (trial requires email).

RANK 3 Google Enhanced Conversions (server-side, hashed email) — this also SETTLES the "does Google work?" question

On the Stripe payment_intent.succeeded webhook, POST to the Google Ads Conversion API with {conversion_action, conversion_time, conversion_value, user_identifier:{hashed_email}}. Matches to Google's identity graph cross-device, no gclid needed. Run 28 days, then read Google Ads → Conversions → "Purchase (Enhanced)". If conversions appear, the loopback was broken (Google was under-credited); if still 0, Google genuinely isn't sourcing buyers. Either way we finally know. Retire the broken AC→Google plugin.

RANK 4 Meta CAPI — fire Purchase (not Lead), server-side, with dedup

On payment_intent.succeeded, POST to Meta Conversions API: event_name:"Purchase", value, currency, user_data:{em:sha256(email), external_id:sha256(user_id), fbc:fbclid_from_PI, fbp:cookie}, event_id:"stripe_"+payment_intent_id. The event_id must match the pixel's so you dedup, not double-count. Then switch the QLG prospecting campaign objective from Lead → Purchase once CAPI shows ≥50 purchase events/week (Meta needs that volume to learn). Until then HOLD QLG — the channel is unproven, not proven-bad.

RANK 5 RevenueCat → Amplitude (unlock cohorts) — events connected but firing at ~3% of reality

Live proof it's broken (Amplitude, last 30d): af_purchase = 5, af_start_trial = 3, af_subscribe = 5, auth_register_succeeded = 4 — against 188 real RevenueCat subs and thousands of signups. The events exist; they under-fire by 30–60×. (begin_checkout = 6,769 fires on page-load and is inflated — same shell story as Stripe.)

Fix: RevenueCat dashboard → Integrations → Amplitude. Enable rc_initial_purchase, rc_trial_started, rc_renewal, rc_cancellation, rc_expiration. Critical: RevenueCat app_user_id MUST equal the Amplitude user_id, or events land on orphan profiles. Also verify auth_register_succeeded fires on the real signup path. Then you can finally build "paid subscriber" cohorts and compare D1/D7/D30 retention — the data that tells you what to build next.

RANK 6 RevenueCat → AppsFlyer webhook (fix the 6× conversion undercount)

30 af_purchase events in 90 days vs 188 real subs = ~6× undercount (the "T5 gap"). RevenueCat → Integrations → AppsFlyer; enable Purchase/Subscription/Renewal/Cancellation. Confirm rc_app_user_id = AppsFlyer customer_user_id (the join key). After 7 days, AppsFlyer revenue-by-source becomes trustworthy and Meta app-install ROAS can finally be judged on real D7 revenue.

RANK 7 Repoint UAC / cheap-geo optimisation (or cut)

Google UAC is set to optimise for Installs. Once Rank 6 confirms af_purchase flows, switch UAC bidding to in-app purchase (tROAS/tCPA). Until then, pause the cheap-geo UAC — it's buying the wrong thing. (This is the code-free "cut today" from the Overview; no wiring needed to pause.)

Execution order
  1. Ranks 1+2 (PI-at-Pay-click + first-touch persistence) — the upstream fix everything depends on.
  2. Ranks 3+4 (Google Enhanced Conversions + Meta CAPI Purchase) — parallel, off the same Stripe webhook.
  3. Ranks 5+6 (RevenueCat → Amplitude + AppsFlyer) — parallel, dashboard connectors.
  4. Rank 7 + cut cheap-geo — no code, do today.
  5. 28 days later: read Google EC, AppsFlyer revenue, Amplitude cohorts → then make channel verdicts.

🎆Live lifetime cart — actions for the final days (closes ~12 Jul)

DO NOW Cut cheap-geo app-installs, reallocate to the cart

Pause Meta AP / SA / SP-LATAM app-install sets (~£400/mo) + Google UAC cheap-geo (~£1,300/mo). CONFIRMED junk ($0 revenue/90d). Free ~£1,700/mo of budget for the retargeting window — via the holdout test below, not a blind scale.

DO NOW Run a 20% holdout on the winning retargeting audience — before you scale a penny

The retargeting ROAS (2.4–4.8×) is 3–6 people during a sale where they're also getting the email sequence — classic last-click illusion. The cheap test: create a 20% suppression (holdout) audience inside the NA-EU-AU retargeting set now, run 3–4 days. If the exposed group converts materially better than the held-out group → retargeting is incremental, scale it for the last-call. If they convert the same → email was closing them anyway and extra retargeting spend is waste. Costs nothing but suppression logic; must start immediately given the 12 Jul close.

P1 Google: brand-defence only during the cart

Keep brand-name search live (£25–30/day) so competitors can't conquest your terms while a cart is open. Do not spin up category Search as a "test" — you can't get a learnable read in 5 days with broken tracking. Category Search waits for Enhanced Conversions (Rank 3) + a full 28-day window.

P1 Creative for the final days (warm audiences only)

Sequence to the close: Day 1–2 ownership + proof ("own it forever", one real testimonial), Day 3 price-anchor (own-once vs pay-forever math), Day 4–5 deadline / last-call only. One offer line on every unit: "One payment. Lifetime access. No monthly bill — ever." Segment the message (quiz-abandoners ≠ trial-expired ≠ engaged-no-purchase). Frequency-cap warm pools (2× → 3× on last days) or you fatigue them. No aging angle; no banned blue.

ADeep insights — what the verified data says

  1. Attribution is the meta-problem — but it's new, not "97% broken." Source tracking went live ~1 Jul; it now tags ~55–86% of checkout sessions but has only reached ~8 completed sales so far (the rest of the window is pre-tracking renewals). Every CAC/ROAS-by-channel stays unreliable until the tag survives to the sale and a few more weeks accrue. This is the keystone. CONFIRMED
  2. The "abandoned cart" number is mostly a mirage. 5,165 of 5,463 PaymentIntents are empty page-load shells (a PI is minted when someone lands, before they decide to pay). Raw "5,000 abandoned" is not 5,000 failed buyers and is not a conversion rate. CONFIRMED
  3. Google web is genuinely unresolved — don't overclaim in either direction. 1,809 checkout intents → 0 tracked sales, 0 gclid completions. That is not "Google proven to work" (an earlier draft said that, on one screenshot — it's now contradicted by the full pull), nor a clean "Google failed." It's UNVERIFIED — the 28-day Enhanced-Conversions test settles it.
  4. Cheap-geo installs are the one confirmed waste. Meta AP: 1,581 installs @ £0.08 → 0 purchases; Google UAC → $0 AppsFlyer revenue/90d. Organic converts ~40–60× better than paid installs. CONFIRMED cut.
  5. Meta retargeting is the best-looking signal — and the least trustworthy at face value. ROAS 2.4–4.8× (reconciles to Meta Ads Manager, campaign-to-date) but n=3–6, during a sale, with email in the mix. Holdout-test it; don't scale on the raw number. UNVERIFIED
  6. Email/AC is the closer, not the source. Highest completion rate per session (~6%) — but under last-click it books other channels' buyers as its own. Keep it; never rank cold acquisition by it. CONFIRMED
  7. Organic is the real demand proof and it's under-analysed. Biggest attributed revenue, best conversion ratio, and we don't know its drivers (ASO? brand? content?). Worth a dedicated look. CONFIRMED
  8. Blended MER ≈ 2.8× but it's promo-inflated. One-time lifetime cash sits in the numerator; recurring-only MER is likely materially lower and UNVERIFIED. Don't read the sale window as steady-state health. (See Combined tab for the math + caveats.)
  9. The one number that unlocks everything: source-tagged Cost per Trial. The North-Star metric (<$20). It doesn't exist yet because trials aren't tagged by channel. The fix-plan creates it.

BBlind spots — what we still can't see

Blind spotWhy it mattersHow to close it
True source of completed sales (once the tag survives)Only ~8 tagged sales so far; can't rank any channel until the weekly count grows.Fix-plan Ranks 1–3 (metadata at Pay-click + first-touch + Enhanced Conversions), then 3–4 weeks of accrual
Checkout completion rate for real card-enterersThe likely #1 lever. Can't compute it from raw PI rows (shells drown it).Once PIs are created at Pay-click (Rank 1), succeeded ÷ card-entered becomes real
Plan-mix inside Stripe web revenueCan't split one-time lifetime cash from recurring subs → MER is fuzzy.Product-level Stripe export (price/product per PI)
Retargeting incrementalityDeciding whether to scale it is currently a coin-flip.The 20% holdout test (cart actions) — starts now
Why organic converts so wellBest channel; drivers unknown.ASO report + GA4 organic/brand-search breakdown
Apple Search Ads27 installs → 2 purchases = best paid install ratio on tiny spend. Under-tested.Small controlled ASA test in high-LTV geos (after MMP events wired)

🧩Everything in one place

Total paid spend — July (1–7, MTD)June (full month), live & verified

Full line-by-line breakdown is on the Overview → "Ad spend breakdown" table. This is the platform summary for the selected month.

PlatformSpendWhere it goesTracked purchases*
Meta / Facebook£2,113£2,466£1,362 retargeting · £545 app-install · £207 QLG£1,860 QLG · £427 app-install · £179 other163
Google Ads£995£670~£810 UAC installs · £186 remarketing£670 UAC installs0 (installs only)
TOTAL£3,108£3,136of which ~£1,355 (July 7d)~£1,097 (June) is app-installs → 0 sales = the confirmed cut163

*Pixel/platform "tracked purchases" are undercounted (web + app complete off-pixel) AND partly last-click-inflated. Treat as directional only. Separate accounts = no spend double-count; the double-count risk is on conversions (one buyer touches both platforms; both claim credit).

Web revenue — Stripe, both accounts · July (1–7, MTD)June (full month) CONFIRMED

AccountCompletedRevenue (USD)Note
Account 1 — main checkout60146$10,086$6,946new cart: 5,219 PIs, mostly page-load shellsold checkout: only 169 PIs, 86% succeeded — no shells
Account 2 — Thrivecart recovery32$841$576failed-payment recovery link; no UTM forwarded
TOTAL web63148$10,927$7,522one-time lifetime (Jul) vs renewals (Jun)

The launch signal: July's first 7 days already did $10,927 of web revenue — more than all of June ($7,522), which was ordinary subscription renewals. That's the lifetime sale working — but it's one-time cash, not recurring MRR (see caveat below). Also note: June's checkout made only 169 PaymentIntents (86% succeeded); July's new cart made 5,219 (mostly page-load shells) — the shell problem is the new cart's behaviour, an engineering fix (Measurement fix-plan, Rank 1).

Web revenue vs ad spend — by month MODELLED MER

MonthWeb revenuePaid ad spendWeb ÷ spendNote
June (full month)$7,522£3,136 ≈ $3,9831.89×renewals, cold prospecting
July (1–7, MTD)$10,927£3,108 ≈ $3,9472.77×lifetime sale (one-time cash)
Do not read July's 2.77× as "the machine scales"

July's web revenue is ~$10.3K one-time lifetime cash (+ ~$0.9K recurring), not repeatable next month. June's 1.89× is closer to steady-state (renewals, not new ad-driven subs). This is a healthy sale week, not proof of scalable acquisition. The real test: does MRR grow month-on-month after the cart closes? UNVERIFIED

The real MRR — both rails (the true north star) CONFIRMED (live)

Recurring railActive subsMRR (USD)Note
Stripe web subscriptions572$8,265/moactive subs net of already-cancelling (110 excluded) · annual + quarterly + monthly (lifetime one-time excluded)
App store (RevenueCat)191$2,791/moApple + Google Play
TOTAL recurring MRR763≈ $11.1K/mogross of Stripe/Apple fees · break-even ≈ $15K/mo

Correcting the record (twice): the app-only "$2,757 MRR" understated the business — web subscriptions are the bigger rail. An earlier version of this table quoted ~$13.1K, which over-counted by including ~110 subscriptions already set to cancel at period end. The honest figure is ≈ $11.1K/mo — web $8,265 (Stripe, 572 continuing subs) + app $2,791 (RevenueCat, 191). Lifetime buyers sit on top as one-time cash ($0 MRR). Rails are additive — no double-count.

🛒Web checkout — Stripe (live, both accounts)

Now pulled directly from both Stripe accounts (read-only API) — not screenshots. Read the attribution by week, not blended — the source tags are only a couple of weeks old.

📅 Web sales in the selected month

July (1–7 MTD): 63 completed sales · $10,927 (the lifetime cart). 5,219 checkout page-loads — but almost all are page-load shells, not failed buyers. Only 8 of the 63 sales carry a source (attribution is ~1 week old).June (full month): 148 completed sales · $7,522 — ordinary subscription renewals. Only 169 checkout PaymentIntents all month (86% succeeded — the old checkout, no shells). 0 source-tagged (attribution didn't exist yet).

✅ First, the honest framing: attribution went live ~1 July

Source metadata (utm_source/gclid) only started being written the week of ~1 Jul (ISO week 27), right as the lifetime cart launched. Any "unknown source" from before is meaningless — the feature didn't exist, and most completions are subscription renewals (no marketing source by nature). Don't quote a blended unknown-% over old data. Here's the weekly truth:

WeekCheckout PIsWith utm_sourceWith gclidCompleted sales…source-taggedRead
W18–W26 (early May–late Jun)~40000~3500no tracking existed — renewals
W27 (~1 Jul) — go-live4,4952,502 (~56%)1,546616tags firing at the top
W28 (6 Jul)733628 (~86%)224162only ~8 tagged sales total — too small to split
The real, fixable gap (not "97% blind")

Since go-live the tag reaches ~55–86% of checkout sessions — good. But it reaches only ~8 of the completed sales so far, because (a) most completions are still renewals with no source, and (b) the tag doesn't survive the page-load-PI / cross-device hop to the winning payment. Fix = create the PI at Pay-click + first-touch persistence (fix-plan Ranks 1–2), then watch the weekly "source-tagged sales" climb. Do not attempt a channel split of purchases until that column is in double/triple digits.

Account 1 — status of all 5,463 PaymentIntents (last 45d)

StatusCountWhat it is
requires_source (empty shell)5,165minted on page-load, no card ever entered — NOT a failed buyer
succeeded288real completed payment ($21,442)
canceled9
requires_action13DS pending

Who completed, by source (288 succeeded over 45d)

⚠️ Read this with the weekly table above in mind: most of these 288 are pre-attribution renewals (before ~1 Jul there was no source to capture). This is NOT "97% of buyers lost their tag" — it's "most of this window predates tracking + is recurring rebills." Only ~8 of the genuinely-new, post-go-live sales carry a source so far.

Source (last-click UTM)CompletedRevenueCheckout intents (page-loads)Read
unknown / no source280$19,0662,049mostly pre-1-Jul renewals — no source existed
Email / ActiveCampaign4$1,18865highest completion rate (~6%) — the closer
Facebook paid3$891498low same-session completion
Instagram paid1$297510low same-session completion
Google Ads0$01,809most intent of any paid channel, 0 tracked sales
Meta Audience Network / Threads / email-tag0$0234negligible

gclid: 1,769 checkout page-loads carried a Google click-id → 0 tracked completions — but this is only the ~2 weeks since go-live, against a completed-sale set still dominated by renewals. It's a flag to watch, not proof Google fails (see the Google tab: UNVERIFIED). The 28-day Enhanced-Conversions test settles it.

Account 2 — Thrivecart recovery

StatusCountRevenueNote
succeeded5$1,417all "unknown" — Thrivecart forwards no UTM/gclid

Recovery volume is small (5 in 45d) — the earlier idea that "most failed buyers recover via Thrivecart" is false. But note the tracking gap: recovered sales lose all channel attribution. If it grows, pass the original utm_source/gclid into the Thrivecart link.

🔴 Why "completed by channel" can't be trusted yet

Four forces make this table unreadable for sourcing right now:

  • Attribution is only ~2 weeks old — most completions predate it or are renewals with no source.
  • Page-load PIs — the tag is captured before payment, so 94% are shells and it doesn't survive to the winning payment.
  • Cross-device loss — clicked a Google ad on mobile, paid on desktop → arrives with no gclid.
  • Last-click robbery — a Google/Meta buyer closed via recovery email books as "email/AC."

So Google's 0 is a measurement-artefact candidate, not proof of failure; email's ~6% is partly other channels' buyers. The fix-plan (Ranks 1–3) resolves these — then the weekly source-tagged-sales trend becomes the metric.

⚠️ But also: even ignoring attribution, the checkout may be the constraint

Update (8 Jul forensic): the checkout is not the leak — real card-entry attempts complete at 72% (61/85). The 5,000+ intents are page-load ghosts, not failed buyers. The real upstream leak is offer×audience match: recently-acquired install audiences (retargeted 7–14 days, but who don't know us yet) were sent a £297 lifetime offer and bounced or had their card declined. Full breakdown in the 🔬 Checkout autopsy tab.

📈Meta / Facebook Ads — July MTD (£2,113)June (£2,466), live

Source: Meta Marketing API, ad account "TMA NEW". Spend-by-window is on the Overview → "Selected window" table (it responds to the toggle). The per-campaign table below is campaign-to-date, unified attribution and reconciles to the penny with Meta Ads Manager — the retargeting campaigns only exist in the last ~7 days, so campaign-to-date ≈ the 7-day window. (Earlier this doc showed last_30d retargeting numbers, which exclude today — that's why they drifted from the live Ads Manager screen; fixed.)

Campaign bucketSpendROASPurchases · valueVerdict
Retargeting — NA-EU-AU (July-4 sale)£1874.77×4 · £893best — but n=4; holdout-test before scaling
Retargeting — WW API£2522.65×3 · £669holdout-test
Retargeting — WW EXU£2292.36×6 · £541holdout-test
Retargeting — WW LLU (Hot)£2380.51×1 · £120pause — below breakeven
QLG prospecting (US/UK/MC), ADV+~£1,3720.03–0.13×HOLD — optimising on Lead not Purchase; fix CAPI to judge
App-Install — AP (Asia-Pacific)£1311,581 installsCUT — £0.08 installs, 0 purchases
App-Install — SA / SP-LATAM~£269666 installsCUT — cheap-geo junk
App-Install — US / UK / AU (higher-cost geos)~£417273 installsconditional — keep only if AppsFlyer D7 shows revenue
*Why the ROAS is directional

Web/app purchases complete off-pixel (undercount → real higher) AND warm-retargeting audiences are simultaneously in the July-4 email sequence (last-click → some "retargeting" sales were email's → overstated). The undercount argument cuts both ways, which is exactly why the winners need a holdout test, not a blind scale.

Verdict: CUT cheap-geo app-installs + LLU retargeting (confirmed). HOLD QLG (unproven, wrong optimisation event). HOLDOUT-TEST the retargeting winners before scaling. One priority: pause LLU + cheap-geo → redirect into a holdout-validated NA-EU-AU push for the cart close.

🔍Google Ads — July MTD (£995)June (£670)

Read through GA4 (Google Ads is linked to the GA4 property — there is no separate Google Ads token). ~90% of spend is UAC (app installs) in the same cheap geos as Meta.

BucketSpendWhat it isVerdict
UAC app-installs (AP / SA / SP-LATAM / US / UK)~£1,460optimises to installs, cheap geosCUT — $0 AppsFlyer revenue/90d
Remarketing (July-4 promo)£174warmkeep
The honest Google verdict — two separate questions

1. UAC app-installs = CUT CONFIRMED. Optimises to installs not buyers; $0 attributed revenue over a full 90-day window. Same failure as Meta's cheap-geo. Pause now; if you keep any Google app spend later, repoint it to a purchase event (fix-plan Rank 7).

2. Google web / Search = UNVERIFIED UNVERIFIED. On the web cart Google drove 1,809 checkout intents — the most of any paid channel — but 0 tracked completions and 0 gclid sales. That could be cross-device loss, cheap-geo card declines, email stealing the close, or genuinely non-converting traffic. We cannot tell today. So: do not kill it, do not scale it. Run brand-defence only during the cart (£25–30/day), and settle it properly with the 28-day Enhanced-Conversions test (fix-plan Rank 3).

Correction on the record: an earlier draft of this doc said "Google Ads works — proven by a gclid purchase." The full 45-day pull contradicts that single data point (1,769 gclid intents → 0 sales). The honest status is UNVERIFIED until the Enhanced-Conversions test runs — not a win, not a loss.

📱App attribution — AppsFlyer (last 90 days)

Where iOS + Android installs come from, and whether they convert. Install counts are accurate; conversion events are undercounted until the RevenueCat→AppsFlyer webhook is wired (fix-plan Rank 6).

SourceInstallsAttributed revenueRead
Organic884$3,968best buyers — ~2.9% install→purchase
Facebook Ads2,835$480huge install volume, tiny revenue — cheap geos drag it
Apple Search Ads27$200strong ratio on tiny volume — worth a test
Google Ads1,193$0converts on WEB not in-app — see checkout tab
TOTAL4,939$4,648D5–D7 window
The signal that matters: the install→purchase RATIO

Organic ~2.9% vs paid installs ~0.05% — a 40–60× gap. Paid app-installs (especially cheap geos) buy volume that doesn't buy. Organic is the real demand. Conversion event counts are still undercounted (30 af_purchase/90d vs 188 real subs = the T5 gap) — read revenue columns, not event counts, and wire Rank 6 to make Facebook's real app revenue visible.

💳App revenue — RevenueCat (live)

The source of truth for the app-store subscription rail (Apple + Google Play). This is one of two recurring rails — the web subscriptions run through Stripe and are the bigger one.

📌 The app rail is only part of MRR

RevenueCat MRR $2,791 is app-store only. Add Stripe web subscriptions $8,265/mo (572 continuing subs)true total MRR ≈ $11.1K/mo. See the Combined tab for the full MRR table.

App rail — now (live)
  • App MRR $2,757 (Apple + Play)
  • 188 active subscriptions
  • 4 active trials
  • $4,092 revenue / 28d
Top of the app funnel (28d)
  • 5,757 "new customers"
  • 6,381 active users
  • → only 4 active trials
🔴 "5,757 new customers → 4 trials" is mostly a bot artefact — don't read it as demand

The registration-bombing (fixed 7 Jul) inflated "new customers" with junk signups. The real recurring business is the 188 active subs / $2,757 MRR. Ignore "new customers" as a demand metric until identity is clean. The genuine activation question — do real app users start trials — needs the trial event wired (fix-plan) before it can be answered.

🎯Quiz funnel — GA4 (last 30 days, quiz host)

StepCountRateRead
Sessions3,969top of funnel
First visits3,627
Leads (generate_lead)50812.8%vs 28% target
Add-to-cart3027.6%of sessions
begin_checkout0event not firing on quiz host
Two things

1. Lead rate 12.8% vs a 28% target — the quiz hook is leaving leads on the table (CRO opportunity; the flow is being redesigned). 2. begin_checkout = 0 on the quiz host — checkout is on checkout.themovementathlete.com and its events don't report here. Part of the same measurement gap: until user_id is standardised across quiz → checkout → RevenueCat, you can't follow a quiz lead to a purchase.

📧Email / CRM — the July 4 signal

Same offer, two very different audiences — the CRM problem in one table:

TrackOpenClick-to-openRead
Customers / members (~1.8–2K)24–29%12.9–13.3%offer converts trusting users
Leads — full-list blasts (44.7K)10–18%0.3–0.5%list damage: hard bounces + unsubs
Leads — story email (Dave)19%2.1%story beats offer 4–7×
⚡ Deliverability — the DMARC fix (verified live)

SPF and DKIM are fine. The real issue: the domain publishes three conflicting DMARC records, so inbox providers ignore the policy entirely and trust erodes. ~15-minute DNS cleanup at SiteGround. → Step-by-step fix guide. (Bot signups: fixed 7 Jul — not a factor.)

The lesson: the offer works on people who trust the brand (customers ~13% CTO). Cold-lead blasts damage the list and (via last-click) steal other channels' attribution credit. Keep promo sends to engaged segments; warm cold leads with story/value first; fix deliverability so it all lands.