Documentation
Docs

Set up a paywall

Learn how to set up a paywall for your supastarter application.

Per default, supastarter includes a free plan which means that users can access your application after signing up without any payment.

If your SaaS should not be accessible for free or only with a trial of a paid plan, you can set up a paywall.

All you need to do is to set requireActiveSubscription to true in the payments config:

packages/payments/config.ts
export const config: PaymentsConfig = {
  billingAttachedTo: "user",
  requireActiveSubscription: false, 
  requireActiveSubscription: true, 
  plans: {
    // ...
  },
};

This removes the free plan and redirects users to the /choose-plan page after the signup (and the onboarding flow) until they have purchased a plan.

Which subscriptions grant access

Payment provider webhooks store a normalized subscription status on each purchase (see Subscription status). With the paywall enabled, only these statuses unlock the app:

  • active
  • trialing
  • canceling (canceled at the end of the billing period, but the period has not ended yet)

One-time purchases (for example a lifetime plan) always grant access.

Subscriptions in a lapsed state (incomplete, past_due, unpaid, or paused) or that have ended (canceled or expired) no longer unlock the app:

  • Users who still have a plan on record are redirected to the billing page (/settings/account/billing, or /[organizationSlug]/settings/billing when billingAttachedTo is "organization"). There they can see the subscription status and open the customer portal to update their payment method.
  • Users without any plan are redirected to /choose-plan.

The paywall check runs in the app layout at apps/saas/layouts/app.vue. It skips the billing pages (detected with isSubscriptionBillingPath from @repo/payments/lib/subscription-status), so they stay reachable for users whose subscription has lapsed.