How to Integrate Stripe in Next.js
Integrating Stripe into a Next.js application allows you to handle payments seamlessly. Stripe provides a robust and developer-friendly API for handling subscriptions, one-time payments, and invoicing. This guide walks you through the process of integrating Stripe into a Next.js application step-by-step.
Prerequisites
-
Basic knowledge of Next.js.
-
A Stripe account: Sign up at Stripe.
-
Node.js installed: Make sure you have Node.js installed on your machine.
-
Next.js application: If you don’t have one, create it by running:
npx create-next-app@latest stripe-integration cd stripe-integration
-
Install Stripe SDK: Install the Stripe Node.js SDK and the frontend package:
npm install stripe @stripe/react-stripe-js @stripe/stripe-js
Step 1: Create a Stripe Account and Get API Keys
- Go to the Stripe Dashboard.
- Navigate to API keys under the Developers section.
- Copy the Publishable Key and Secret Key.
Step 2: Backend Setup
Stripe needs a secure server to handle sensitive operations like creating a payment intent. Next.js API routes work well for this purpose.
-
Create an API route for Stripe payment intent:
mkdir pages/api/stripe touch pages/api/stripe/create-payment-intent.js
-
Add the following code to
create-payment-intent.js
:const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); export default async function handler(req, res) { if (req.method !== 'POST') { res.setHeader('Allow', 'POST'); return res.status(405).end('Method Not Allowed'); } try { const { amount } = req.body; const paymentIntent = await stripe.paymentIntents.create({ amount, currency: 'usd', automatic_payment_methods: { enabled: true, }, }); res.status(200).json({ clientSecret: paymentIntent.client_secret }); } catch (error) { res.status(500).json({ error: error.message }); } }
-
Add your Stripe secret key to an
.env.local
file:STRIPE_SECRET_KEY=your_secret_key
-
Restart your Next.js development server to apply the new environment variables:
npm run dev
Step 3: Frontend Setup
The frontend interacts with Stripe to handle user payments.
-
Set up the Stripe provider:
import { Elements } from '@stripe/react-stripe-js'; import { loadStripe } from '@stripe/stripe-js'; const stripePromise = loadStripe('your_publishable_key'); function MyApp({ Component, pageProps }) { return ( <Elements stripe={stripePromise}> <Component {...pageProps} /> </Elements> ); } export default MyApp;
Replace
your_publishable_key
with your actual Stripe publishable key. -
Create a payment form component:
mkdir components touch components/CheckoutForm.js
import { CardElement, useStripe, useElements } from '@stripe/react-stripe-js'; import { useState } from 'react'; const CheckoutForm = () => { const stripe = useStripe(); const elements = useElements(); const [isProcessing, setIsProcessing] = useState(false); const [error, setError] = useState(null); const handleSubmit = async (event) => { event.preventDefault(); setIsProcessing(true); const { error: backendError, clientSecret } = await fetch('/api/stripe/create-payment-intent', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ amount: 1000 }), // $10 in cents }).then((res) => res.json()); if (backendError) { setError(backendError); setIsProcessing(false); return; } const { error: stripeError, paymentIntent } = await stripe.confirmCardPayment(clientSecret, { payment_method: { card: elements.getElement(CardElement), }, }); if (stripeError) { setError(stripeError.message); setIsProcessing(false); } else { alert('Payment successful!'); setIsProcessing(false); } }; return ( <form onSubmit={handleSubmit}> <CardElement /> <button type="submit" disabled={!stripe || isProcessing}> {isProcessing ? 'Processing...' : 'Pay $10'} </button> {error && <div style={{ color: 'red' }}>{error}</div>} </form> ); }; export default CheckoutForm;
-
Use the
CheckoutForm
component in a page:import CheckoutForm from '../components/CheckoutForm'; export default function Home() { return ( <div> <h1>Stripe Payment Integration</h1> <CheckoutForm /> </div> ); }
Step 4: Testing Payments
-
Use Stripe’s test cards to simulate transactions. For example, use:
- Card Number:
4242 4242 4242 4242
- Expiry: Any future date
- CVC: Any 3 digits
- Card Number:
-
Run the application:
npm run dev
-
Navigate to
http://localhost:3000
and test the payment flow.
Conclusion
Congratulations! You’ve successfully integrated Stripe into your Next.js application. You can now customize and expand this setup to include subscriptions, webhooks, or other advanced Stripe features.