Skip to content

Telehealth physical-therapy practiceClient work

Google Ads Was Optimising for Free Screenings. Now It Knows Who Paid.

I sent paid Stripe subscriptions to Google Ads as offline conversions for a US telehealth practice and fixed identity lost by conversion tags.

The brief

Context

A US telehealth physical-therapy practice sells through a funnel that crosses three tools: a WordPress quiz for a free screening, an embedded booking widget for an evaluation, and Stripe payment links for the paid subscription. It advertises on Google.

Google Ads could see who booked something free, but not which of those people went on to pay. I was brought in in July 2026 to close that loop. The pipeline went live and was verified against real payments in early August.

Sounds familiar?

Symptoms

The situation Telehealth physical-therapy practice
Tick what applies to you

Tick the lines that describe your case.

Describe my task

The investigation

Diagnosis

I built the container from an empty one and tested the path end to end, rather than trusting the existing configuration.

The P0 root cause: the Google Ads conversion tags (awct) were silently discarding the enhanced-conversion user data. Identity has to ride the base Google tag (awud), not the conversion tag. I moved it and verified the hashed email and phone on the wire.

Three more findings came out of the same read:

  1. On Apple mobile devices the conversion ping goes through but the hashed identity does not register — the Safari restriction the client had flagged at the start. Conversions still attributed, because the click id carried them.

  2. Evaluation bookings fired their conversion correctly, but the lead was silently never saved to the sheet: a script-load-order fallback fired the conversion and skipped the record. From the outside, nothing looked broken.

  3. The older “Book appointment” action was still present; I checked its numbers and it had recorded zero conversions in the window, so it was not double counting.

Handover

What I built

Delivery noteDelivered Aug 2026

  1. Enhanced-conversion identity, captured on site. Hashed email and phone are taken on the quiz submit and the booking success, and attached to the base Google tag. Only hashed identifiers leave the page.
  2. A 90-day first-party click cookie plus booking metadata as a backup, so the click can be recovered even in a later session.
  3. An offline feedback loop. A Stripe checkout.session.completed webhook → a Sheet → a scheduled Google Ads offline import as a “Paid Subscription” conversion, matched on hashed email or phone or the click id, with an order id so a payment cannot count twice. I delivered the offline leg on infrastructure I hosted.
  4. A booking webhook with an HMAC check and an in-process async mutex. The mutex exists because a real race turned one booking into three rows; it now produces one.
  5. Per-lead delivery telemetry. Every submission records whether the hashed identity actually reached Google — a plain yes/no, readable from a row instead of guessed.
  6. A landing prototype with three variants and a guided screening quiz, built under medical-content-safety rules. It is a prototype, not a deployed page.

Before → after

Results

Client work Done for real clients. Client details are anonymised.

These are historical delivery checks from July–August 2026. I have not re-verified the channel’s current availability; this case does not offer a public endpoint or demo.

  • Paid subscriptions traced from ad click to payment

    Jul 2026 to Aug 2026

    Before
    none — Google Ads saw free screens and evaluations only
    After
    4 subscriptions traced click → payment, 3 attributed down to the ad group
  • Root cause of the dropped identity

    Jul 2026

    Before
    conversion tags (awct) silently discarded the enhanced-conversion user data
    After
    identity carried on the base Google tag (awud), verified on the wire
  • Duplicate rows from one booking

    Jul 2026

    Before
    one booking produced three rows in a real race
    After
    an in-process async mutex; one booking, one row
  • Payment feedback into Google Ads

    Jul 2026

    Before
    none
    After
    Stripe → Sheet → Google Ads offline import, daily; a live test payment imported with zero errors
The full results table
What changedBeforeAfterRead on
Paid subscriptions traced click → paymentnone4, of which 3 down to the ad groupAug 2026
Identity routedropped on the conversion tagcarried on the base Google tag, verified on the wireJul 2026
Duplicate booking rows3 from one booking, in a real race1Jul 2026
Offline payment feedbacknonedaily Stripe → Sheet → Google Ads import; a live test payment imported with zero errorsJul 2026
Rated 5 out of 5 on Upwork.

He continually checked in on how the conversion tracking was going days and even weeks after the project ended.

Brandon L., Function Fix Upwork · 2026

Notes on the numbers

The clearest proof was a sale where the patient mistyped their email at Stripe checkout, so the email matched nothing. The phone number matched their original booking, and through that match the system recovered the ad click id and attributed the payment to the right campaign. Had it relied on email alone, that sale would have been lost.

One honesty note from the same report: I could not fully separate “Safari blocked the identity ping” from “the patient closed the page before the check ran.” Both lead to the same practical result, and the conversions still landed, because the layers cover each other.

A note from Daniilbefore you decide

What this means for a similar business

If you sell a service where the money arrives after a booking, your ad platform is probably optimising on the booking, not the payment. That is the wrong signal, and it gets worse the longer the gap between the two.

Three things fix it: capture the identity early enough that it survives the wait, send the real payment back as an offline conversion, and reconcile the two against your own payment records. Layered matching matters more than any single identifier — in this case the email failed and the phone number saved the sale.

Health businesses also have to be straight about what they treat as measurable data. This is technical implementation, not legal or medical advice; a practice should confirm its own obligations, including HIPAA, with counsel before publishing any tracking change.

— Daniil

Daniil Maximkin

Hi, I’m Daniil.

I work with you from defining the problem to implementation and handover. You talk to the person who does the work. I work in English and Russian.

Have a similar task?

Describe your task

The first answer is free, within one working day. Or write directly: next@taskfordaniel.com