Skip to content

Record a checkout source on every Cloud checkout - #1115

Merged
helpcodeai merged 1 commit into
mainfrom
fix/checkout-source-metadata
Oct 15, 2026
Merged

helpcodeai merged 1 commit into
mainfrom
fix/checkout-source-metadata

Conversation

@helpcodeai

@helpcodeai helpcodeai commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Every Cloud checkout now names the place it started, so Stripe can count checkouts and completions per entry point, including the first-success offer (#1078). Website side: HelpCode-ai/anythingmcp-website#396.

Why trial_source never showed up

The plumbing from #1078 and website #380 worked, but only on one path: a click on the first-success card that went to /start-trial?source=first_success and pressed the button on that same visit. No other way into a checkout sent a source. That covers the trial banner, Settings > License, the ended-trial wall, "add a card" after Approve, the sign-up prompt, the chat's setup links, and every pricing link from the app and from the emails. The card and the email also shared one value.

Production since 13 Oct:

  • 6 card clicks, 200 offer emails and 104 checkout links, every one of them via=app.
  • The one person who clicked the card and then checked out did so 52 minutes later, through another entry point that sent no source.

What changes

  • Allow-list CHECKOUT_SOURCES in license-checkout.ts, mirrored in frontend/src/lib/checkout-source.ts. Values: first_success_banner, first_success_email, trial_banner, license_page, trial_ended_wall, post_approve, signup_prompt, trial_limit, starter_pack, chat_setup, start_trial, app. The old first_success is still accepted, for emails already sent and tabs already open.

  • POST /api/license/checkout-link always sends a source. It uses app when the page didn't name one.

  • Entry points each name themselves. Settings > License passes on the source of the offer email or the chat setup tools when they link there.

  • Pricing links carry ?source=:

    • from the app: app_pricing by default, or the name of the place the link sits;
    • from the emails: email_trial_warn3, email_trial_warn1, email_trial_expired and email_winback.

    The site records these as checkout_source once website chore(deps-dev): bump typescript-eslint from 8.62.0 to 8.62.1 #396 is live.

  • The offer email links with first_success_email, so it's counted apart from the card.

  • /start-trial reports start_trial_viewed (once per load) and start_trial_checkout_started, both with source and kind. Clicks from the email become measurable this way.

  • docs/operations/card-trial-offer.md gets the source table, the deploy order, and the queries for checkouts and completions per source.

Deploy order

No hard order. The site already stores any slug it gets on an intent, so this works against today's site, with the source landing in trial_source. Deploying the website PR first is better: then every checkout lands in checkout_source, and the email and app pricing links are recorded from the start.

Checks

  • Backend: lint (no errors), tsc clean, full jest suite green (658 suites).
  • Frontend: lint (no new warnings), tsc clean, next build passes, full Playwright suite green (183). New cases cover the card's and the email's sources, the /start-trial events, the licence page passing the email's source on, and the banner, wall and pricing-link sources.

Stripe never got trial_source because only one path ever sent a source:
the first-success card to /start-trial, clicked on that same page load.
Every other way into a checkout (the trial banner, the licence page, the
ended-trial wall, post-Approve, the sign-up prompt, the chat's setup
links, the pricing links from the app and from emails) sent nothing,
and the banner and the email shared one value. In production: 6 card
clicks and 200 offer emails since 13 Oct, 104 checkout links, all 'app'.

- Allow-list of entry points (CHECKOUT_SOURCES), mirrored in the
  frontend: first_success_banner, first_success_email, trial_banner,
  license_page, trial_ended_wall, post_approve, signup_prompt,
  trial_limit, starter_pack, chat_setup, start_trial, app. The legacy
  first_success stays accepted for emails already sent.
- The checkout-link endpoint always sends a source ('app' by default).
- Each entry point names itself; Settings > License passes on the
  offer email's and the chat's source.
- Pricing-page links carry ?source=: app_pricing and the app places,
  email_trial_warn3/warn1/expired and email_winback from the emails.
- /start-trial reports start_trial_viewed and
  start_trial_checkout_started with the source and kind.
- Ops doc: the source table, deploy order and the queries to count
  checkouts and completions per source.
@helpcodeai
helpcodeai merged commit bb0ea7b into main Oct 15, 2026
15 checks passed
@helpcodeai
helpcodeai deleted the fix/checkout-source-metadata branch October 15, 2026 19:13
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 15, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant