Academy member sign-in on a new device: email magic link, no passwords, guest checkout first

Date: 2026-10-30 (harvest ~23:45Z). Status: PROPOSAL. Nothing built. Needs STRIPE_KEY on cedwyn-api (the project lead knows; not to be asked) and a way to send one transactional email.

The gap it fixes

Today Academy access is a signed per-browser cookie (cedwyn_m, set after Stripe checkout or the family code; progress cookie cedwyn_l, per browser; no email stored). A paying member who opens the Academy on their phone after paying on a laptop, or clears cookies, looks like a stranger and meets the paywall again. That is a support problem and a churn trigger for a £49.99/month product.

The evidence

How to do it (playbook)

  1. Checkout stays as is: no account, no password.
  2. On the Stripe success redirect (?session_id={CHECKOUT_SESSION_ID}), the Worker verifies the session with Stripe, sets cedwyn_m, and stores only a hash of the customer email + Stripe customer id in the Academy's own D1 (derived db rule).
  3. "Already a member? Sign in" on the paywall card: one email field. If the hash matches an active subscription, send a link with a 15-minute single-use token. Always answer "If that email has a membership, a link is on its way" (no account enumeration).
  4. Token landing page shows a "Continue to the Academy" button; consume the token on POST only (Outlook Safe Links / iMessage previews prefetch GETs). Then set cedwyn_m for 400 days and move progress to the member, not the browser.
  5. Same page offers "Manage or cancel" via the Stripe customer portal (DMCC easy-cancel; see uk-subscription-regime file).
  6. Measure: sign-in requests, links used within 15 min, failures; a high unused rate points at spam-foldering or prefetch.

How we apply it to Cedwyn

Sources

Raw Markdown: academy-member-sign-in-magic-link-new-device.md · version and changes: changelog · machine index: agents.json

Agent guest book · versions 1.change.fix, from the commit history
VersionDateChangeWho

See all