Eugene Kostiuchenko · Performance marketing · Paid acquisition · Case study

Built the tracking end to end. Reconciled every platform number against real payments. Made every decision on cash.

Proof of method

96 22
Meta reported96 checkout events Confirmed payments22 real payments · 23%

The gap became the method: I rebuilt the tracking between launches, and on launch two Meta's purchase count matched the payment processor exactly — 7 = 7.

$22.77cost per paying customer, confirmed in the payment processor
Meta × WayForPay × Telegramthree independent attribution layers
24% / 21%the same gap — two markets, two stacks, two landing pages
Client: freelance funnel for a video-maker's online course Budget: ~$500, diagnostic Channel: Meta Ads

01 Context

A $9 tripwire whose job was to buy a customer, not turn a profit

This was a paid freelance project for a video-maker with 20+ years behind the camera. The product was a $9 mobile-filmmaking intensive — a tripwire. A tripwire is not meant to earn: its job is to convert an anonymous click into a paying customer with a contact in Telegram, so the real money can come later from an upsell (an online course at $149, or 1-on-1 mentoring at $899).

The funnel ran end to end: Meta Ads → landing page → WayForPay checkout → Telegram bot (delivery + warm-up) → upsell.

The project ran as two launches, and my role grew between them — that growth is the spine of this case:

Act 1 — Ukraine · narrow role March 26 – April 4, 2026

The landing page and payments belonged to another contractor. My zone was tracking and running the ads: two campaigns, $253.

Ten weeks between launches — not idle: the bot was rebuilt around warm-up, the tracking was fixed.

Act 2 — Poland · full ownership June 14 – July 3, 2026 · ~3 weeks

Russian- and Ukrainian-speaking diaspora. I owned everything end to end — the site, the whole measurement layer, the offer, the Telegram bot, the ads. One campaign, $248.

Both launches together came to ~$501. This was a diagnostic budget with a diagnostic goal: not to scale, but to find where the funnel breaks and test the economics of the model. Every conclusion below is calibrated to that scale — 22 purchases is a signal, not a statistic, and I treat it that way throughout.

02 Hypothesis

What each launch was actually testing

Act 1 (Ukraine)

  • Does the tripwire mechanic work on cold traffic at all?
  • Which placements produce paying customers — tested as two separate campaigns (FB+IG together vs Instagram-only) rather than editing one, to keep the before/after data clean and avoid resetting Meta's learning phase.
  • How does the upsell sell? On Ukraine it was pitched by direct message right after purchase.

The upsell hypothesis failed: direct pitches for the big course met silence. The takeaway — a buyer has to warm up and reach out themselves, which needs a nurture sequence, not a cold pitch. That became the main change for launch two.

Act 2 (Poland)

Does the funnel carry to a new, colder, more expensive market (diaspora: higher CPM), with a setup corrected for the Act 1 lessons — Instagram-only from day one, an age focus, a clean attribution signal (strict 7-day click / 1-day view, all AI creative enhancements off, manual placements) — and a bot rebuilt around multi-step warm-up instead of direct selling?

Two further questions inside the launch, not raised on Ukraine: which placement inside Instagram (Reels / Feed / Stories) buys intent cheapest, and which of three creative angles resonates. Both were answered by campaign structure — three creatives in one ad set, letting Meta's delivery optimization decide, instead of splitting a thin budget across an A/B test.

03 Setup

A tracking stack built so campaign decisions could trust the data

Top layer: I built and owned the full stack — landing page, analytics, and conversion tracking with a CAPI safeguard (GA4, GTM, Meta Pixel + one-click Conversions API) — so decisions rested on data I could verify.

The technical layer

  • Static landing on Cloudflare Pages. Page weight cut from 7.4 MB to 636 KB, LCP 2.09s (green Core Web Vitals) — ready for paid traffic.
  • One GTM container, two mirrored receivers: GA4 for funnel analytics, Meta Pixel for the ad signal. Event funnel PageView → ViewContent → InitiateCheckout → Purchase on shared triggers. The checkout trigger fired on the payment-processor URL, not the button text, so copy edits couldn't break it.
  • One-click CAPI as a safeguard against lost browser signal. It paid off: on Poland, Meta's Purchase events matched the payment processor 7 = 7 — closing the measurement gap diagnosed on Ukraine.
  • Telegram bot (SendPulse) rebuilt: product delivery + a multi-step warm-up + engagement (chat with the author) + a buyer-source step — a third attribution layer alongside Meta and WayForPay.
  • UTMs via {{ad.name}} / {{adset.name}} macros — GA4 saw traffic per creative with no manual tagging. Tagging and purchase tracking were incomplete on Ukraine; fixed on Poland, which is what opened the per-creative breakdown.
GTM container: 9 tags — GA4 and Meta Pixel funnel events, both checkout tags on the shared WayForPay-URL trigger
GTM container — mirrored Meta Pixel and GA4 funnels on shared triggers. Source: GTM
Landing page hero — $9 tripwire offer 'shoot like a pro', 10 steps in 3 lessons, Telegram delivery
Landing page, above the fold. Source: slavaiordanov.com

Campaign structure

Ukraine: two Sales / ABO campaigns optimizing for InitiateCheckout — FB+IG together vs IG-only — to isolate the placement variable. Landing and payments sat with the other contractor.

Poland: Sales / ABO, optimizing for InitiateCheckout (too few purchases to optimize on Purchase directly), $25/day, broad targeting with hard limits in Controls (geo, age 22+, languages RU+UA), 3 creatives on different angles in one ad set — natural delivery optimization instead of splitting the budget on an A/B test.

04 Metrics

The numbers, split by who reported them

Spend and clicks come from Ads Manager. Payments come from WayForPay. I keep them in separate columns on purpose — the whole point of the case is what happens when you stop trusting one and start checking it against the other.

The funnel's biggest loss is not where Meta shows it: 77% of reported checkout intent never became money.

Impressions — Meta71,090
Clicks — Meta~2,155 · CTR 3.0%
InitiateCheckout — Meta96 · 4.5% of clicks
Payments — WayForPay22 · 22.9% of IC

Bar length = conversion from the previous step, on a shared 0–100% scale. The amber step is where the platform's picture and the payment processor's picture diverge.

Source: Meta Ads Manager (impressions, clicks, InitiateCheckout) vs WayForPay (settled payments) · both launches, Mar–Jul 2026

Per-campaign performance · spend & clicks: Ads Manager · payments: WayForPay
UA · FB+IGUA · IG-onlyPL · IG-only
Roletracking + adstracking + adsfull ownership
Spend$134.96$117.88$248.05
Impressions24,59818,56627,926
CTR5.07%2.26%1.82%
CPC$0.11$0.28$0.49
InitiateCheckout (Meta)451833
Payments (WayForPay)967
CPA on real payments$15.00$19.65$35.44
Tripwire ROAS0.60x0.46x0.25x

Tripwire ROAS = revenue from the $9 product against that campaign's spend. Full-funnel ROAS (0.40x) is covered under economics below.

[◱] SCREENSHOT — Ads Manager, three campaigns with spend.
Source: Ads Manager

The headline of the whole project: Meta claimed 96 checkouts, the payment processor confirmed 22. About 77% of the platform's checkout events never became money.

Meta — checkout events reported96
WayForPay — payments confirmed22 · 23%

Bar length = absolute count of events, on a shared 0–96 scale.

Source: Meta Ads Manager (InitiateCheckout) vs WayForPay (settled payments) · both launches · UA 63→15 (24%) · PL 33→7 (21%)

Two markets, two landing pages, two stacks — the same result: ~77% of Meta's checkout events don't turn into cash. Optimizing or reporting on Meta's numbers here would have overstated the result by roughly 4×. Every decision was made on the payment processor.
[◱] SCREENSHOT — Excel daily funnel, IC (Meta) beside WFP payments.
Source: Excel · META_LANDING_FUNELL_DAILY
[◱] SCREENSHOT — WayForPay payments list, PII redacted.
Source: WayForPay

Funnel economics

  • Break-even ROAS of the tripwire is ~1.14x at ~88% margin; actual tripwire ROAS ran 0.25–0.60x — the tripwire itself loses money, and that's by design: its job is to buy the customer.
  • CAC of a paying customer: $501 / 22 = $22.77 — confirmed in the payment processor.
  • Upsell: 0 sales from 22 buyers. On Ukraine the upsell was pitched by direct message and buyers went silent. The warm-up was rebuilt between acts, but no upsell closed before the project stopped. The upsell step is the funnel's bottleneck — and that's the main honest diagnosis of these launches.
  • Funnel ROAS in cash: $198 / $501 = 0.40x — below break-even. The funnel did not pay back. The diagnostic budget bought knowledge, not profit: acquisition works, monetization doesn't, and now I know exactly where it breaks.

05 Decisions

Three calls, each made on evidence I can defend

Decision 1 · Ukraine

Cut Facebook, tighten the age — on three-layer attribution, not one number

Inside the mixed campaign, Facebook looked like the star: CTR 6.72%, clicks at $0.08 (Instagram ~3%, $0.20). An age breakdown of the same campaign added a second fact: the 65+ segment produced 28 of 45 checkout events (62%) at $1.88 — 2–3.5× cheaper than any other age. Meta doesn't cross age with placement in its breakdowns, so these were two separate signals, not one story. Sales sat in WayForPay with no placement split, and Meta had already discredited its own checkouts — so the third layer settled both: I had added a source-selection step in the bot, and every buyer named Instagram. The cheap intent — by placement and by age — was hollow. A qualitative factor backed it up: the author has no Facebook presence, so FB traffic had nowhere to warm up.

Call: drop the Facebook placement, tighten age to 45, concentrate budget on Instagram. This carried into the Poland setup from day one.

[◱] SCREENSHOT — FB/IG breakdown of the mixed UA campaign.
Source: Ads Manager
[◱] SCREENSHOT — SendPulse bot, buyer-source step.
Source: SendPulse
Decision 2 · Between acts

Rebuild the upsell mechanic and the tracking

From the failure of direct selling on Ukraine, the bot was rebuilt from selling to warming up — a multi-step sequence, engagement, a chat with the author, so the buyer ripens and reaches out. In parallel, the UTM tagging and purchase tracking that were incomplete on Ukraine were fixed — which is what produced the 7 = 7 match with the payment processor and a working per-creative breakdown on Poland.

Decision 3 · Poland

Placement, age and creative calls inside Instagram

  • Reels was the cheapest intent: 17 IC at $6.05, vs Feed 8 at $10.53 (1.74× more expensive) and Stories 8 at $7.61 → at scale, budget concentrates in Reels.
  • Age core 25–44 produced 26 of 33 IC (35–44 the best segment: 14 IC at $6.50). The Ukraine lesson applied pre-emptively: 55+ got under 5% of budget.
  • The "wow-result" creative won decisively. Inside one ad set, Meta concentrated delivery itself: the "shot-on-a-phone" video took $220 of $248 (89% of budget) and drove 32 of 33 IC at $6.88; the two other angles together got ~$28 and 1 IC. Honest caveat: the losing angles got too few impressions for a statistical verdict — the expected trade-off of running three ads in one ad set (delivery optimization, not an A/B test).

Inside Instagram, Reels bought checkout intent 1.74× cheaper than Feed.

Reels — 17 IC$6.05 per IC
Stories — 8 IC$7.61
Feed — 8 IC$10.53

Cost per InitiateCheckout by placement · bars scaled from zero · Source: Meta Ads Manager, PL campaign, Jun 14 – Jul 3, 2026

[◱] SCREENSHOT — winning creative, still frame.
Source: ad creative "snyato-na-telefon"
[◱] SCREENSHOT — PL campaign breakdown by ad.
Source: Ads Manager

06 Learnings

What held up, and what I'll name as a limit

What held up

  • Platform metrics can't be taken on faith. Reconciling against the payment processor isn't paranoia, it's basic hygiene — the 23% pattern replicated across both launches.
  • Acquisition worked: 22 paying customers at $22.77 each, every one confirmed in the payment processor.
  • Separate campaigns beat editing a live one: clean data boundaries, no learning resets. And because the campaigns ran sequentially — the mixed one Mar 26–30, IG-only from Mar 31 — auction overlap was practically absent by construction: the second launch was the implementation of a decision, not a parallel test.
  • CAPI closed the tracking gap: purchases were missing in Meta on Ukraine, and matched the payment processor 7 = 7 on Poland.

What I'll call a limit, plainly

  • Monetization didn't close: 0 upsells from 22. The warm-up was rebuilt between acts, but 7 Poland buyers and a short window before the project stopped aren't enough to validate the new mechanic. Monetization stayed unvalidated, and I say so directly.
  • Too many variables changed between acts (market, landing, offer, stack, bot mechanic) — the Poland effect can't be isolated from the new-landing effect. With more budget I'd move one variable at a time.
  • CPA rose from Ukraine ($15–20) to Poland ($35.44): the diaspora is colder and more expensive than the home market. A fact is a fact — a Poland buyer cost roughly twice as much.
  • Placement-level ROAS (FB vs IG) on Ukraine can't be computed honestly: payments sat in the processor with no placement split, and there was no deduplicated CAPI. So the Facebook call rests on bot attribution, not a ROAS figure — there is no number in this case I can't defend.
  • Learning Limited at these budgets is an accepted state, not a mistake: exiting it would have cost more than the monthly budget.

The project was stopped by the client — workload, finances, a relocation — before the upsell step gathered enough volume to conclude.

The diagnostic goal was fully met. The monetization goal was not. Both of those are true, and the case is stronger for saying so.

07 If I'd had 10× the budget

Where the next dollar would go

Not a wishlist — a direct read of where the funnel actually broke.

  • The upsell step as the main object of work. The bottleneck is found; now fix it: A/B the bot warm-up sequences (length, engagement steps, chat with the author), step-by-step analytics inside the bot, and test selling the high-ticket tier via a call request instead of a payment button.
  • Server-side CAPI via the payment-processor callback, deduplicated by event_id (orderReference), so Meta optimizes on real payments rather than inflated checkouts.
  • Switch optimization to Purchase once volume reaches ~50 purchases/week; until then, InitiateCheckout as the proxy.
  • One variable per iteration: lock the landing and offer first, then test geo, then creative angles (developing the winning "wow-result" format in Reels) — and kill criteria for every test fixed in advance, before launch.
  • Systematic tripwire → upsell conversion as the core economic metric (current base 0/22 — now a baseline exists, and a rebuilt warm-up to test against it).
  • Standardized UTM tagging and a weekly spend → cash cohort report — the same reconcile-to-money principle, but routine instead of one-off.