Skip to content

Route Get Pro directly to Stripe checkout - #8813

Merged
lawrencecchen merged 2 commits into
mainfrom
task-pricing-checkout-redirect
Jul 24, 2026
Merged

lawrencecchen merged 2 commits into
mainfrom
task-pricing-checkout-redirect

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Jul 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • route every public Get Pro CTA directly through Stripe checkout
  • retire the completed checkout rollout flag and remove its download fallback
  • cover the pre-client-config destination with a red/green regression test

Testing

  • cd web && bun test tests/pro-cta-link.test.tsx tests/checkout-navigation.test.tsx tests/pricing-page.test.tsx tests/app-pricing-page.test.tsx tests/billing-checkout-route.test.ts
  • cd web && bun run typecheck
  • focused ESLint
  • python3 scripts/lint-feature-flags.py
  • browser-verified pre-hydration and hydrated clicks with client config unavailable

Issues


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Route all public Get Pro CTAs directly to Stripe Checkout and remove the rollout flag and download fallback for a consistent upgrade flow. Adds a server-rendered regression test to cover pre-hydration clicks.

  • Refactors
    • Always link Pro and Team pricing CTAs to /api/billing/checkout; remove the download confirmation fallback.
    • Remove the pro-checkout-enabled-release flag and add it to scripts/retired-feature-flags.txt.
    • Simplify ProCtaLink to always start the checkout redirect and capture checkout: true.
    • Update docs and billing skill notes to reflect the launched checkout path.
    • Add a regression test validating the initial link renders to checkout before client config loads.

Written for commit ef42016. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Pro and Team pricing calls to action now always open the pricing checkout flow.
    • Checkout links consistently use the billing checkout destination.
  • Bug Fixes

    • Removed fallback navigation to the download confirmation page from pricing CTAs.
  • Documentation

    • Updated pricing guidance to reflect that checkout is launched and no longer feature-gated.
    • Retired the obsolete checkout release flag.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Pro pricing CTAs now always use the billing checkout endpoint. The checkout feature flag and fallback routing are removed, documentation is updated, and a component test verifies the checkout link output.

Changes

Pro checkout routing

Layer / File(s) Summary
Retire checkout flag
web/app/lib/feature-flags.ts, scripts/retired-feature-flags.txt, docs/pro-badge-options.html, skills/cmux-billing/SKILL.md
Removes the checkout flag definition, records it as retired, and updates related documentation.
Make CTA checkout-only
web/app/[locale]/components/pro-cta-link.tsx, web/tests/pro-cta-link.test.tsx
Removes fallbackHref, always targets checkout, records checkout: true, and tests the rendered link.
Update pricing CTAs
web/app/[locale]/pricing/page.tsx
Removes fallback destinations and feature-flag routing notes from the Pro pricing CTAs.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 warning, 2 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Cmux Algorithmic Complexity ❓ Inconclusive pending investigation need code inspection
Cmux No Ambient Global State ❓ Inconclusive placeholder pending
✅ Passed checks (22 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: routing Get Pro directly to Stripe checkout.
Description check ✅ Passed The Summary and Testing sections are complete, but the Demo Video, Review Trigger, and Checklist sections are missing.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed No Swift files are changed in the PR diff; only docs, TS/TSX, and test files were modified, so Swift actor-isolation rules don’t apply.
Cmux Swift Blocking Runtime ✅ Passed The PR changes only docs/TS files; no .swift files appear in the diff, so the Swift blocking-runtime rule is not triggered.
Cmux Browser Automation Off-Main ✅ Passed Diff only updates billing/docs/tests; no browser automation, WebKit/AppKit, or control-command routing code changed, so the off-main rule isn’t implicated.
Cmux Expensive Synchronous Load ✅ Passed The diff touches only docs, scripts, and TypeScript; no Swift files or main-actor/load paths are changed, so this Swift-specific rule is not applicable.
Cmux Cache Substitution Correctness ✅ Passed No persistence/history/undo/snapshot cache substitution found; the PR keeps fresh checkout resolution and only removes a UI fallback, with failure fallback handled in the redirect hook.
Cmux No Hacky Sleeps ✅ Passed Changed TS/JS/runtime files only reroute Pro CTAs and add a deterministic markup test; no sleeps, polling, timers, or wall-clock waits were introduced.
Cmux Swift Concurrency ✅ Passed PASS: the diff only touches docs/TS/HTML; no .swift files or Swift concurrency patterns are introduced, so the rule is not applicable.
Cmux Swift @Concurrent ✅ Passed No Swift files changed in the PR diff, so the swift-concurrent-annotation rule is not triggered.
Cmux Swift Package Boundaries ✅ Passed PASS: The diff only changes docs, scripts, and TypeScript; no Swift code or package-boundary issue is present.
Cmux Swiftpm Lockfiles ✅ Passed No SwiftPM/Xcode/.gitignore/dependency files changed in this PR, so the Package.resolved policy is not triggered.
Cmux Swift Logging ✅ Passed PR touches only docs, scripts, and web TS/TSX files; no Swift runtime code or new logging statements are present.
Cmux User-Facing Error Privacy ✅ Passed The diff only removes a retired flag and routes CTAs to checkout; it adds no user-facing error, alert, or recovery copy exposing sensitive details.
Cmux Full Internationalization ✅ Passed The only changed user-facing web surface already reads from next-intl, and the new English-only text is confined to internal/docs files exempt from localization rules.
Cmux Swiftui State Layout ✅ Passed Diff only touches docs, feature-flag text, TSX, and tests; no SwiftUI files or state/layout patterns were introduced.
Cmux Architecture Rethink ✅ Passed PASS: The diff only touches docs/web JS/TS files; no Swift files or Swift architectural changes are present, so the Swift rethink rule doesn’t apply.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed No Swift/AppKit window code changed in this PR; diff only touches docs, TSX, tests, and feature-flag text, so the auxiliary-window close-shortcut rule is not implicated.
Cmux Source Artifacts ✅ Passed All changed paths are intentional docs/source/tests/config; none are logs, build output, temp dirs, or other source-control artifacts.
Cmux No Test Or Debug Seam In Production Source ✅ Passed The PR changes only docs, TypeScript, and test files; no Swift files under Sources/ were touched, so the check is not applicable.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch task-pricing-checkout-redirect

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR completes the Stripe checkout rollout by retiring the pro-checkout-enabled-release PostHog feature flag and hardwiring every public Get Pro CTA directly to /api/billing/checkout.

  • ProCtaLink simplified: removes fallbackHref, flag evaluation (FORCED_ON/FORCED_OFF/useClientConfigFlag), and all flag-gated branching — the component now always routes to checkoutHref and records checkout: true in the PostHog event.
  • Flag properly retired: pro-checkout-enabled-release is added to retired-feature-flags.txt (enforced by CI lint), the FEATURE_FLAGS.proCheckout registry entry is removed, and documentation/skill files are updated consistently.
  • Regression test added: pro-cta-link.test.tsx uses renderToStaticMarkup to verify the pre-hydration HTML points to the checkout URL and not the former download fallback.

Confidence Score: 5/5

Safe to merge — the change is a straightforward flag retirement with no remaining branches dependent on the removed logic.

Every changed file is consistent and purposeful: the flag evaluation is fully deleted, the retired-flags blocklist is updated, docs and the billing skill are kept in sync, and the new regression test pins the pre-hydration href to the checkout URL. TypeScript would catch any callers that still pass the removed fallbackHref prop, and CI lint would catch any attempt to reuse the retired flag key. No code paths were left partially wired.

No files require special attention.

Important Files Changed

Filename Overview
web/app/[locale]/components/pro-cta-link.tsx Simplified by removing the proCheckout flag evaluation logic and fallbackHref prop; now always routes to checkoutHref, with checkout hardcoded to true in the PostHog event.
web/app/lib/feature-flags.ts Removes the proCheckout flag definition; the flag is properly retired in retired-feature-flags.txt to prevent key reuse.
web/app/[locale]/pricing/page.tsx Removes fallbackHref from two ProCtaLink usages; DOWNLOAD_CONFIRMATION_HREF import is still valid and used for the Free plan CTA.
web/tests/pro-cta-link.test.tsx New regression test using renderToStaticMarkup to verify pre-hydration HTML routes to checkout and not to the retired download fallback URL.
scripts/retired-feature-flags.txt Adds pro-checkout-enabled-release to the retired flags blocklist, preventing accidental key reuse in CI.
skills/cmux-billing/SKILL.md Updates billing skill documentation to reflect that Pro/Team pricing CTAs always route directly to /api/billing/checkout with no feature-flag fallback.
docs/pro-badge-options.html Removes the retired pro-checkout-enabled-release flag row from the badge options table and notes the checkout is now fully launched.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User clicks Get Pro CTA] --> B[ProCtaLink onClick]
    B --> C[posthog.capture checkout=true]
    C --> D{useCheckoutRedirect.start}
    D -- href starts with /api/billing/checkout --> E[preventDefault]
    E --> F[fetch /api/billing/checkout?format=json]
    F -- success --> G[window.location.assign Stripe URL]
    F -- network failure --> H[window.location.assign fallback route]
    H --> I[Server-side 302 to Stripe]

    style A fill:#f0f0f0
    style G fill:#d4edda
    style I fill:#d4edda
Loading

Reviews (1): Last reviewed commit: "route Pro pricing CTA directly to checko..." | Re-trigger Greptile

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/tests/pro-cta-link.test.tsx`:
- Around line 15-28: Add a client-side test for ProCtaLink that mocks the
redirect hook, simulates clicking the CTA, and asserts start is called with
checkoutHref and the click event, along with the unconditional checkout
analytics event. Keep the existing renderToStaticMarkup href assertions
unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2f7e5cb0-a0d7-4fa2-a7d8-ba769e93fc3b

📥 Commits

Reviewing files that changed from the base of the PR and between fc0a930 and ef42016.

📒 Files selected for processing (7)
  • docs/pro-badge-options.html
  • scripts/retired-feature-flags.txt
  • skills/cmux-billing/SKILL.md
  • web/app/[locale]/components/pro-cta-link.tsx
  • web/app/[locale]/pricing/page.tsx
  • web/app/lib/feature-flags.ts
  • web/tests/pro-cta-link.test.tsx
💤 Files with no reviewable changes (1)
  • web/app/lib/feature-flags.ts

Comment thread web/tests/pro-cta-link.test.tsx
@lawrencecchen
lawrencecchen merged commit 745534f into main Jul 24, 2026
10 checks passed
@lawrencecchen
lawrencecchen deleted the task-pricing-checkout-redirect branch July 24, 2026 05:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant