All articles
Tutorial

How to Add Stripe Subscriptions to Next.js in Under 2 Hours

12 min readWritten by · The MVP Guy
#stripe#nextjs#typescript#payments
Muhammad Tanveer Abbas

Muhammad Tanveer Abbas

Solo SaaS Builder · 7 Products Shipped · The MVP Guy

Stripe subscriptions trip up almost every developer the first time. Here's the complete guide webhooks, customer portal, free tiers, and the edge cases that bite you in production.

Step 1: Create Products and Prices in Stripe Dashboard

Before writing any code, set up your products in the Stripe dashboard. Create a product for each tier. For each product, create a recurring price. Copy the price IDs you'll need them.

Use Stripe's test mode for everything during development. Never use live keys locally.

Step 2: Create a Checkout Session

// app/api/checkout/route.ts
export async function POST(req: Request) {
  const { priceId, userId } = await req.json();
  const session = await stripe.checkout.sessions.create({
    mode: "subscription",
    payment_method_types: ["card"],
    line_items: [{ price: priceId, quantity: 1 }],
    success_url: process.env.NEXT_PUBLIC_URL + "/dashboard?success=true",
    cancel_url: process.env.NEXT_PUBLIC_URL + "/pricing",
    metadata: { user_id: userId },
  });
  return Response.json({ url: session.url });
}

Step 3: Handle Webhooks

This is where most developers get it wrong. You must verify the webhook signature. Handle at minimum: checkout.session.completed, customer.subscription.updated, and customer.subscription.deleted.

Always make webhook handlers idempotent. Stripe can send the same event multiple times. Use the event ID to deduplicate in your database.

Step 4: Customer Portal

Don't build your own subscription management UI. Stripe's customer portal handles plan upgrades, downgrades, cancellations, and payment method updates. It takes 10 minutes to set up.

const portalSession = await stripe.billingPortal.sessions.create({
  customer: customerId,
  return_url: process.env.NEXT_PUBLIC_URL + "/dashboard",
});
redirect(portalSession.url);
The full Stripe integration checkout, webhooks, portal, and free tier logic takes about 2 hours if you follow this pattern. I've done it 4 times.

Need Stripe integrated into your MVP? I ship it in 14 days.

Need Stripe billing in your B2B SaaS?

Every MVP I build includes subscription checkout, billing portal, and webhook handling — scoped before kickoff.

Share:

Related Posts

Logo