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.
| Channel / lever | What the verified data shows | Confidence | Move 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. | CONFIRMED | CUT 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. | UNVERIFIED | Don'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. | MODELLED | HOLD don't scale, don't cut — fix the event |
| Google web / Search | 1,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. | UNVERIFIED | Brand-defence only £25–30/day; run the 28-day test before any verdict |
| Email / ActiveCampaign | Highest 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." | CONFIRMED | Keep 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). | CONFIRMED | Under-analysed find what drives it (ASO/brand/content) |
| The checkout itself | Not 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. | CONFIRMED | Healthy see 🔬 Checkout autopsy |
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.
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.
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.
| # | The step | What the data says |
|---|---|---|
| 1 | We 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 |
| 2 | We 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 |
| 3 | People 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 |
| 4 | Meanwhile 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 |
| 5 | The 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 |
| 6 | And 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 |
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).
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.
| Question | Short 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 move | Why |
|---|---|---|
| 1 | Freeze 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 |
| 2 | Match 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 |
| 3 | Instrument 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 |
| 4 | Optimise the biggest leak first — the ~60% drop on quiz screen 1. Measure lead→trial weekly. | fix the funnel before buying traffic to it |
| 5 | Fix deliverability (DMARC, ~15 min) so the warm list — the audience that actually converts — reliably lands. | protects the channel that works |
| 6 | Put spend controls in place — hard daily caps, weekend lock, a daily spend alert. | so a month's budget can't run ahead unseen again |
| 7 | Only 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 |
| Decision | Call | Why |
|---|---|---|
| Allocate more ad budget this month? | NO | Lifetime 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? | NO | it converts real attempts at 72%; switching risks live sales |
| Start affiliate acquisition now? | NOT NOW | a good later lever, but it splits focus before the core funnels are shipped. Focus beats breadth this month. |
| Reintroduce paid? | AFTER the funnels convert | with matched offers, on a measurable funnel, scaling only what shows a real Cost-per-Trial |
| Control | The rule |
|---|---|
| One north-star metric | MRR, and its driver lead→trial per funnel — reviewed weekly. If work doesn't move one of these, it's a distraction. |
| Paid-spend gate | Hard 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 rule | No 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 rule | Audiences that don't know us yet → free trial / £9.99 / 50% off. Lifetime & annual → warm/existing only. |
Two funnels decide MRR:
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:
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.
| Channel | June · full month | July · 1–7 (MTD) | Note |
|---|---|---|---|
| Facebook / Meta | £2,466 | £2,113 | acct act_710789699289834 "TMA NEW" · verified to the penny |
| — Prospecting (QLG, cold) | £1,860 | £207 | 3 sales in June (ROAS 0.03) → turned down in July |
| — Retargeting (July-4 sale) | £0 | £1,362 | didn't exist in June · 14 sales, £2,223 |
| — App installs | £427 | £545 | 0 sales both months |
| — Other | £179 | £0 | — |
| Google Ads | £670 | £995 | via GA4 link (no native token; GA4-recorded cost) |
| — UAC app installs | £670 | £810 | 0 sales — cheap geos |
| — Remarketing | £0 | £186 | July-4 promo |
| TikTok / Apple Search Ads | — | — | TikTok not running; ASA spend not API-accessible (small) |
| TOTAL PAID | £3,136 | £3,108 | June ~£105/day · July ~£444/day |
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.
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 / line | Spend · July MTD | Tracked return | Read — July (since launch) |
|---|---|---|---|
| Meta — July-4 retargeting | £1,362 | 14 sales · £2,223 | the sale engine · winners 2.4–4.8× |
| Meta — QLG prospecting | £207 | 2 sales | turned down — fine |
| Meta — app-install | £545 | 0 sales | 🔴 live bleed |
| Google — UAC cheap-geo | ~£810 | 0 sales | 🔴 live bleed |
| Google — remarketing | £186 | warm | keep |
| Total paid | £3,108 | ~£444/day (7d) | — |
| Web sales (Stripe, both accts) | — | 63 · $10,927 | the lifetime cart |
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 / line | Spend · June | Tracked return | Read — June (pre-launch) |
|---|---|---|---|
| Meta — QLG prospecting | £1,860 | 3 sales · ROAS 0.03 | 🔴 the month's biggest line → almost nothing |
| Meta — app-install | £427 | 0 sales | 🔴 waste |
| Meta — other | £179 | 0 sales | — |
| Google — UAC cheap-geo | £670 | 0 sales | 🔴 waste |
| Meta/Google — retargeting | £0 | — | didn't exist yet |
| Total paid | £3,136 | ~£105/day (30d) | — |
| Web sales (Stripe, both accts) | — | 148 · $7,522 | normal subscription renewals |
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.
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.
| What it actually is | Count | % of total | Meaning |
|---|---|---|---|
| Page-load ghosts — a PaymentIntent is auto-created the instant the checkout page opens, before any card is entered | 5,165 | 98.3% | not buyers — an instrumentation artifact |
| Real payment attempts — a card was actually entered | 85 | 1.6% | the only rows that carry signal |
| → succeeded (paid) | 61 | — | paid |
| → failed (card declined) | 24 | — | card-side declines |
| 3DS pending / canceled | 3 | — | — |
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"):
| Decline reason | Count | What it means |
|---|---|---|
generic_decline | 6 | bank 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_exceeded | 4 | too many attempts too fast — fraud-flag behaviour |
do_not_honor | 3 | bank hard-refused |
incorrect_number / incorrect_cvc | 3 | mistyped card |
transaction_not_allowed / insufficient_funds | 2 | card 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.)
| Source | Real sales | Declines | Page-load ghosts | Read |
|---|---|---|---|---|
| unknown (warm / direct / email) | 52 | 15 | 2,024 | the owned audience — already knows TMA |
| ActiveCampaign (email) | 5 | 0 | 68 | warm list |
| Facebook / Instagram | 4 | 0 | 1,021 | mostly warm retargeting |
| Google (cheap-geo installs) | 0 | 8 | 1,815 | low-awareness · cards decline the £297 charge |
| Audience Network / Threads | 0 | 0 | 233 | no completions |
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.
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.
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.
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.
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.
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.
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.)
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).
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.
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.
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.
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.
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.)
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.
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.
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.
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.
| Blind spot | Why it matters | How 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-enterers | The 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 revenue | Can't split one-time lifetime cash from recurring subs → MER is fuzzy. | Product-level Stripe export (price/product per PI) |
| Retargeting incrementality | Deciding whether to scale it is currently a coin-flip. | The 20% holdout test (cart actions) — starts now |
| Why organic converts so well | Best channel; drivers unknown. | ASO report + GA4 organic/brand-search breakdown |
| Apple Search Ads | 27 installs → 2 purchases = best paid install ratio on tiny spend. Under-tested. | Small controlled ASA test in high-LTV geos (after MMP events wired) |
Full line-by-line breakdown is on the Overview → "Ad spend breakdown" table. This is the platform summary for the selected month.
| Platform | Spend | Where it goes | Tracked purchases* |
|---|---|---|---|
| Meta / Facebook | £2,113£2,466 | £1,362 retargeting · £545 app-install · £207 QLG£1,860 QLG · £427 app-install · £179 other | 163 |
| Google Ads | £995£670 | ~£810 UAC installs · £186 remarketing£670 UAC installs | 0 (installs only) |
| TOTAL | £3,108£3,136 | of which ~£1,355 (July 7d)~£1,097 (June) is app-installs → 0 sales = the confirmed cut | 163 |
*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).
| Account | Completed | Revenue (USD) | Note |
|---|---|---|---|
| Account 1 — main checkout | 60146 | $10,086$6,946 | new cart: 5,219 PIs, mostly page-load shellsold checkout: only 169 PIs, 86% succeeded — no shells |
| Account 2 — Thrivecart recovery | 32 | $841$576 | failed-payment recovery link; no UTM forwarded |
| TOTAL web | 63148 | $10,927$7,522 | one-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).
| Month | Web revenue | Paid ad spend | Web ÷ spend | Note |
|---|---|---|---|---|
| June (full month) | $7,522 | £3,136 ≈ $3,983 | 1.89× | renewals, cold prospecting |
| July (1–7, MTD) | $10,927 | £3,108 ≈ $3,947 | 2.77× | lifetime sale (one-time cash) |
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
| Recurring rail | Active subs | MRR (USD) | Note |
|---|---|---|---|
| Stripe web subscriptions | 572 | $8,265/mo | active subs net of already-cancelling (110 excluded) · annual + quarterly + monthly (lifetime one-time excluded) |
| App store (RevenueCat) | 191 | $2,791/mo | Apple + Google Play |
| TOTAL recurring MRR | 763 | ≈ $11.1K/mo | gross 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.
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.
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).
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:
| Week | Checkout PIs | With utm_source | With gclid | Completed sales | …source-tagged | Read |
|---|---|---|---|---|---|---|
| W18–W26 (early May–late Jun) | ~400 | 0 | 0 | ~350 | 0 | no tracking existed — renewals |
| W27 (~1 Jul) — go-live | 4,495 | 2,502 (~56%) | 1,546 | 61 | 6 | tags firing at the top |
| W28 (6 Jul) | 733 | 628 (~86%) | 224 | 16 | 2 | only ~8 tagged sales total — too small to split |
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.
| Status | Count | What it is |
|---|---|---|
requires_source (empty shell) | 5,165 | minted on page-load, no card ever entered — NOT a failed buyer |
succeeded | 288 | real completed payment ($21,442) |
canceled | 9 | — |
requires_action | 1 | 3DS pending |
⚠️ 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) | Completed | Revenue | Checkout intents (page-loads) | Read |
|---|---|---|---|---|
| unknown / no source | 280 | $19,066 | 2,049 | mostly pre-1-Jul renewals — no source existed |
| Email / ActiveCampaign | 4 | $1,188 | 65 | highest completion rate (~6%) — the closer |
| Facebook paid | 3 | $891 | 498 | low same-session completion |
| Instagram paid | 1 | $297 | 510 | low same-session completion |
| Google Ads | 0 | $0 | 1,809 | most intent of any paid channel, 0 tracked sales |
| Meta Audience Network / Threads / email-tag | 0 | $0 | 234 | negligible |
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.
| Status | Count | Revenue | Note |
|---|---|---|---|
| succeeded | 5 | $1,417 | all "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.
Four forces make this table unreadable for sourcing right now:
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.
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.
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 bucket | Spend | ROAS | Purchases · value | Verdict |
|---|---|---|---|---|
| Retargeting — NA-EU-AU (July-4 sale) | £187 | 4.77× | 4 · £893 | best — but n=4; holdout-test before scaling |
| Retargeting — WW API | £252 | 2.65× | 3 · £669 | holdout-test |
| Retargeting — WW EXU | £229 | 2.36× | 6 · £541 | holdout-test |
| Retargeting — WW LLU (Hot) | £238 | 0.51× | 1 · £120 | pause — below breakeven |
| QLG prospecting (US/UK/MC), ADV+ | ~£1,372 | 0.03–0.13× | — | HOLD — optimising on Lead not Purchase; fix CAPI to judge |
| App-Install — AP (Asia-Pacific) | £131 | — | 1,581 installs | CUT — £0.08 installs, 0 purchases |
| App-Install — SA / SP-LATAM | ~£269 | — | 666 installs | CUT — cheap-geo junk |
| App-Install — US / UK / AU (higher-cost geos) | ~£417 | — | 273 installs | conditional — keep only if AppsFlyer D7 shows revenue |
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.
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.
| Bucket | Spend | What it is | Verdict |
|---|---|---|---|
| UAC app-installs (AP / SA / SP-LATAM / US / UK) | ~£1,460 | optimises to installs, cheap geos | CUT — $0 AppsFlyer revenue/90d |
| Remarketing (July-4 promo) | £174 | warm | keep |
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.
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).
| Source | Installs | Attributed revenue | Read |
|---|---|---|---|
| Organic | 884 | $3,968 | best buyers — ~2.9% install→purchase |
| Facebook Ads | 2,835 | $480 | huge install volume, tiny revenue — cheap geos drag it |
| Apple Search Ads | 27 | $200 | strong ratio on tiny volume — worth a test |
| Google Ads | 1,193 | $0 | converts on WEB not in-app — see checkout tab |
| TOTAL | 4,939 | $4,648 | D5–D7 window |
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.
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.
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.
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.
| Step | Count | Rate | Read |
|---|---|---|---|
| Sessions | 3,969 | — | top of funnel |
| First visits | 3,627 | — | — |
| Leads (generate_lead) | 508 | 12.8% | vs 28% target |
| Add-to-cart | 302 | 7.6% | of sessions |
| begin_checkout | 0 | — | event not firing on quiz host |
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.
Same offer, two very different audiences — the CRM problem in one table:
| Track | Open | Click-to-open | Read |
|---|---|---|---|
| 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× |
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.