Stripe Subscriptions
Let's Start by Setting Up Stripe Checkout to Enable Subscriptions¶
We’ll leave the job of granting user access to our custom webhook.
Prerequisites¶
You should already have: - A configured Stripe account - A ready database
🛠️ Setup¶
- In your Stripe dashboard, go to:
[More +] > [Product Catalog] > [+ Add Product] -
Enter the product name and set a monthly price (or any pricing model you use), then click [Save Product].
-
After saving the product, go to the [Pricing] section and copy the Price ID (it starts with
price_
). - Add this ID to the first plan in the
stripe.plans
array inside yourconfig.js
file.
🧾 Page Setup¶
Open the file /dashboard/page.js
and paste the following code:
import ButtonAccount from "@/components/ButtonAccount";
import ButtonCheckout from "@/components/ButtonCheckout";
import config from "@/config";
export const dynamic = "force-dynamic";
export default async function Dashboard() {
return (
<main className="min-h-screen p-8 pb-24">
<section className="max-w-xl mx-auto space-y-8">
<ButtonAccount />
<h1 className="text-3xl md:text-4xl font-extrabold">
Subscribe to get access:
</h1>
<ButtonCheckout
mode="subscription"
priceId={config.stripe.plans[0].priceId}
/>
</section>
</main>
);
}
🧪 Payment Test¶
After that, open this URL in your browser: http://localhost:3000/dashboard
- Log in, click the payment button, and try the test card:
4242 4242 4242 4242
.
🔄 Access Handling¶
The webhook at /api/webhook/stripe/route.js
listens to Stripe events and handles granting or revoking access to the user accordingly.
- Check the
hasAccess
field in theUser.js
model (for NextAuth) orhas_access
column in theprofiles
table (for Supabase).
✅ Note: You must have the Webhook running locally during development for this to work correctly.
🧩 Webhook Customization¶
You can customize the logic inside /api/webhook/stripe/route.js
to:
- Send abandoned cart emails
- Deduct user balance
- Trigger specific email or notification flows
🧾 Subscription Management¶
Users can manage their subscriptions (cancel, change payment method...) via the <ButtonAccount />
component.