Add Stripe Checkout to Next.js — accept payments in minutes

Create a Stripe Checkout session in Next.js, redirect users to the payment page, and handle the success callback. Works for one-time payments and subscriptions.

Stripe Checkout vs. custom forms

Stripe Checkout is a hosted payment page. You don't build a form — Stripe handles the UI, card validation, 3D Secure, Apple Pay, and Google Pay. You create a session on your server, redirect the user, and Stripe tells you when they've paid (via webhook). It's the fastest and safest way to accept payments.


Step 1: Create a product in Stripe

Open the Stripe Dashboard → Products. Click Add product. Set a name and price. Copy the Price ID (starts with price_) — you'll need it in your code.


Step 2: Create a checkout session

In your Next.js API route, create a Checkout Session and return the URL. The client redirects the user there.

app/api/stripe/create-checkout/route.ts
// app/api/stripe/create-checkout/route.ts
import Stripe from "stripe";
import { NextRequest, NextResponse } from "next/server";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  apiVersion: "2023-08-16",
});

export async function POST(req: NextRequest) {
  const { priceId, successUrl, cancelUrl } = await req.json();

  const session = await stripe.checkout.sessions.create({
    mode: "payment",
    line_items: [{ price: priceId, quantity: 1 }],
    success_url: successUrl,
    cancel_url: cancelUrl,
  });

  return NextResponse.json({ url: session.url });
}

Step 3: Redirect from the client

Call the API route from your button click handler. When you get the URL back, redirect:

Client-side button handler
const res = await fetch("/api/stripe/create-checkout", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    priceId: "price_xxx",
    successUrl: window.location.origin + "/dashboard",
    cancelUrl: window.location.href,
  }),
});
const { url } = await res.json();
window.location.href = url;

Step 4: Handle the payment

The success_url redirect alone is not enough — the user could navigate directly to that URL. Always verify payments via a webhook that fires when checkout.session.completed happens. That's where you grant access in your database.


Stripe Checkout already built

Delfy ships with Stripe Checkout, webhooks, customer portal, and post-purchase emails — all wired up. No Stripe integration from scratch needed.

Get the boilerplate
Add Stripe Checkout to Next.js — accept payments in minutes | Delfy.dev Blog