feat(paywall): in-panel upgrade UI with Stripe Checkout and auto-activation - #26
Merged
Conversation
…vation Adds the conversion surface for free users (closes #10): - Persistent "Upgrade" pill in a new shared PanelHeader (SetupPage + ScorePage), plus upgrade entry points in the settings Plan row and the shared ProUpsell card (promoted from SubscoresPage) - PaywallModal on a new accessible Dialog primitive (focus trap, Escape, aria-modal): benefit list, monthly/annual selector ($5/mo, $50/yr), checkout/waiting/success/error states, no dark patterns - OverQuotaNotice bound to the locked AI state: reset timing + upgrade CTA for free users, reset timing only for Pro - Checkout flow: billing client for /billing/checkout + /billing/session claim polling with backoff and give-up fallback, persisted pending session resumed on panel mount; activation flips all surfaces to Pro via the existing entitlement storage sync, no reload needed - Pins the extension ID via manifest "key" so the chrome-extension:// origin is stable for the backend CORS allowlist - Pro users never see any upgrade surface; component tests cover free, over-quota, checkout, and Pro states (458 tests green) Verified end-to-end against staging: test-card payment -> webhook -> claim -> activate -> panel flips to Pro without reload. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #10.
What
The full conversion surface for free users in the side panel:
PanelHeader(used by SetupPage + ScorePage), plus entry points in the settings Plan row (with free-quota display) and the sharedProUpsellcardPaywallModalon a new accessibleDialogprimitive (focus trap, Escape, aria-modal, focus restore): five benefit rows, keyboard-navigable monthly/annual selector ($5/mo, $50/yr, both prices equally visible, honest Stripe caption), and checkout/waiting/success/error statesOverQuotaNoticebound to the locked AI state: friendly copy + reset timing + upgrade CTA for free users; reset timing only (no CTA) for over-quota Pro usersbilling.tsclient +checkout-store.tsstate machine: creates the session, opens Stripe Checkout in a new tab, polls the claim endpoint (4s→10s backoff, 10-min give-up with a manual-activation fallback), auto-activates the minted license; the existing entitlement storage sync then flips every surface to Pro with no reload. Pending sessions persist and resume on panel reopen."key"gives a stablechrome-extension://origin for the backend CORS allowlist (survives CWS publishing)Testing
🤖 Generated with Claude Code