How to Implement Stripe Payments in Next JS 15 Using the App Router

Discover how to implement Stripe payments in Next JS 15 with the new App Router. Learn with detailed code samples, actionable insights, and best practices.

KO

Kjetil Oshaug

Implementing Stripe payments in Next JS 15 with the new App Router is a game changer for modern web applications. In this guide, we dive deep into integrating Stripe’s powerful payment processing within the App Router architecture. Whether you’re a seasoned developer or just beginning your journey, you’ll find actionable code examples and practical insights that streamline your payment integration process while keeping your project secure and efficient.

Getting Started: Prerequisites and Overview

Before diving in, ensure you have a solid grasp of JavaScript, React, and the fundamentals of Next JS. Next JS 15 introduces the App Router, which redefines routing and server component management, making it ideal for scalable web applications. To implement Stripe payments, you’ll need:

Setting Up Your Next JS 15 Project with the App Router

Start by creating or upgrading your Next JS project to use the App Router. Run the following commands in your terminal:

bash
1npx create-next-app@latest stripe-nextjs-approuter
2cd stripe-nextjs-approuter
3npm run dev

This initializes a fresh Next JS 15 project that leverages the new App Router. With your project up and running, it’s time to integrate Stripe.

Installing Stripe and Required Dependencies

Add the Stripe Node.js library to your project. Open your terminal and execute:

bash
1npm install stripe @stripe/stripe-js

If you’re using TypeScript, install the corresponding type definitions as well:

bash
1npm install --save-dev @types/stripe

These dependencies allow your application to securely interact with Stripe’s API and manage payment processing.

Configuring Your Environment: Secure API Key Management

Safely store your Stripe API keys by creating a .env.local file at the root of your project. Add the following environment variables:

env
1NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=your_stripe_publishable_key_here
2STRIPE_SECRET_KEY=your_stripe_secret_key_here

Replace the placeholder values with your actual keys. This step is essential to ensure that sensitive information remains protected and isn’t exposed in your code.

Creating the Payment Checkout Page Using the App Router

With the App Router, you’ll structure your components within the app directory. Create a checkout page that initiates a Stripe payment session. Under the app directory, create a new folder called checkout and add a file named page.jsx:

page.jsx
1'use client';
2
3import { useState } from 'react';
4import { loadStripe } from '@stripe/stripe-js';
5
6const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);
7
8export default function CheckoutPage() {
9  const [loading, setLoading] = useState(false);
10
11  const handleCheckout = async () => {
12    setLoading(true);
13    try {
14      const response = await fetch('/api/create-checkout-session', {
15        method: 'POST',
16      });
17      const session = await response.json();
18      const stripe = await stripePromise;
19      await stripe.redirectToCheckout({ sessionId: session.id });
20    } catch (error) {
21      console.error('Error during checkout:', error);
22    }
23    setLoading(false);
24  };
25
26  return (
27    <div style={{ padding: '2rem' }}>
28      <h1>Secure Payment with Stripe in Next JS 15 (App Router)</h1>
29      <p>Click the button below to initiate a secure checkout session.</p>
30      <button onClick={handleCheckout} disabled={loading}>
31        {loading ? 'Processing...' : 'Pay Now'}
32      </button>
33    </div>
34  );
35}
36

This client component leverages the new App Router structure and uses the use client directive to denote client-side interactivity. It loads Stripe with your publishable key, creates a checkout session, and redirects the user to Stripe’s secure payment page.

Setting Up the API Route with the App Router

Next JS 15’s App Router simplifies API route creation by using the app directory. Create an API route for generating a Stripe checkout session. Under the app/api directory, create a new folder called create-checkout-session and add a file named route.js:

route.js
1import Stripe from 'stripe';
2
3const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
4  apiVersion: '2022-11-15',
5});
6
7export async function POST(request) {
8  try {
9    const session = await stripe.checkout.sessions.create({
10      payment_method_types: ['card'],
11      line_items: [
12        {
13          price_data: {
14            currency: 'usd',
15            product_data: {
16              name: 'Example Product',
17            },
18            unit_amount: 2000, // Amount in cents ($20.00)
19          },
20          quantity: 1,
21        },
22      ],
23      mode: 'payment',
24      success_url: `${request.headers.get('origin')}/success`,
25      cancel_url: `${request.headers.get('origin')}/cancel`,
26    });
27
28    return new Response(JSON.stringify({ id: session.id }), { status: 200 });
29  } catch (error) {
30    return new Response(JSON.stringify({ error: error.message }), { status: 500 });
31  }
32}
33

This API route replaces the traditional pages/api method, conforming to the new file-based routing system of the App Router. It securely creates a checkout session by interacting with the Stripe API, then returns the session ID to the client.

Testing Your Stripe Integration

After setting up both the client and server components, start your development server and navigate to the /checkout route. Initiate a payment to ensure the checkout flow functions as expected. Observe the console and server logs for any errors, and verify that you are properly redirected to the success or cancellation page after the transaction.

Expanding Your Integration: Advanced Customizations

Once you’ve successfully implemented the basic Stripe payment flow using the App Router, consider enhancing your integration with advanced features:

Integrate webhook handling to automatically update your system on payment events. For example, you could create a webhook endpoint by adding a new API route under app/api/webhook/route.js to listen for events like checkout.session.completed and update your database accordingly.

Explore subscription management and recurring payments to cater to businesses with subscription-based models. You might also refine the user interface to match your brand identity, ensuring a seamless user experience.

Final Thoughts and Next Steps

By following this comprehensive guide, you now know how to implement Stripe payments in Next JS 15 using the new App Router. This modern approach to routing and server components not only simplifies your project structure but also enhances performance and scalability. As you become more comfortable with this setup, consider exploring additional Stripe features such as dynamic pricing, multi-currency support, and advanced security measures.

Happy coding, and enjoy building secure, scalable payment solutions with Next JS 15 and Stripe!

More to Discover