Member portal & subscription billing
Your membership lives at /learn/<slug> — a portal your subscribers sign into, entirely separate from the MailInApp dashboard and from any Firebase Auth account. Billing runs as real Stripe subscriptions on your own connected Stripe account, the same Connect account product checkout uses, extended here to recurring Subscriptions/Billing.
Claim your portal URL
Under Settings → Membership, claim a <slug> (3–40 characters, lowercase letters/numbers/hyphens) — the same claim-and-rename shape as a sender profile handle, just its own field. This is the URL you'll link to from campaigns and anywhere else you promote the membership; it can be renamed later without breaking existing subscribers' access.
Setting prices
Also under Settings → Membership, add one or more subscription plans — a name, a recurring amount, and a monthly or yearly interval, with an optional free trial in days. Each plan maps 1:1 to a Stripe Price on your connected account. Plans can't be deleted once created (Stripe Prices can't be deleted either), only archived — an archived plan disappears from the public subscribe page but stays valid for anyone already on it, so archiving never cuts off existing subscribers.
The subscribe flow
/learn/<slug>/subscribe?plan=<planId> is the public page you link to from a campaign — pick it as the link target for a button block, or use the built-in Subscribe studio preset (heading + text + button, same "compose existing blocks, no new block type" shape as the sports-team vertical's Scoreboard preset). A visitor picks a plan and checks out through a real Stripe Checkout session in subscription mode; on completion, a Subscriber row is created or matched by email and a welcome email goes out with a link straight into the portal.
Signing in without a MailInApp account
A subscriber never creates a MailInApp account. Signing in at /learn/<slug> is a magic link: they enter their email, and — rate-limited, and deliberately never revealing whether that email is already subscribed — a one-tap sign-in link is emailed to them through your own SMTP/branding (not Firebase's default template). Clicking it proves they own the address and signs them into the portal for that specific membership.
Watching a lesson
Every lesson play request runs a live per-request entitlement check — not a long-lived signed link the way the countdown or calendar endpoints use. Each time a subscriber opens a lesson, MailInApp checks their current subscription status before minting a short-lived playback token; losing access (a canceled or past-due subscription) takes effect on the very next request, not just at the next page load. A lesson marked free preview skips this check entirely and plays for anyone who reaches the portal.
Managing an existing subscription
/learn/<slug>/account gives a signed-in subscriber a Manage billing button that hands off to Stripe's own hosted Customer Portal — update a card, switch plans, or cancel — rather than MailInApp reimplementing subscription management itself.
What happens on billing events
- Checkout completes → subscriber row created/matched, subscription activated, welcome email sent with a link into the portal.
- Payment fails → the subscriber gets a dunning email pointing at
/learn/<slug>/accountto update their card, while Stripe automatically retries the charge — MailInApp doesn't change access on the first failure, only once Stripe itself reports the subscription as no longer active. - Subscription canceled (by the subscriber, or after dunning exhausts retries) → access to gated lessons and live sessions ends, and a cancellation email goes out with a link back to
/learn/<slug>/subscribein case they want back in.
Related
- Learning membership overview
- Courses, lessons & video
- Live sessions & webinars
- Product block — for a one-time purchase instead of a recurring membership
- Sender profile