Faiz Khan | Portfolio | Fullstack Developer

Faiz Khan | Next.js | Freelancer | Web Developer | Fullstack Developer | Portfolio | Web Development | Portfolio Website | Blog | Software Development | Personal Website | Software Engineer | React | Typescript | Node.js | Python | MongoDB | TailwindCSS | Express.js

Faiz Khan | Portfolio

Explore the portfolio of Faiz Khan, showcasing my skills, projects, and experience as a fullstack developer

Next.js | React | Typescript | Node.js | TailwindCSS | Python | AWS | GCP | Docker | AI

Payment Systems

Integrating Payment Systems with Next.js: Stripe, PayPal, and More

Integrating Payment Systems with Next.js: Stripe, PayPal, and More
0 views
4 min read
#Payment Systems

Introduction

Integrating payment systems into your web application is crucial for e-commerce and subscription-based services. With Next.js and its powerful App Router, you can efficiently manage server-side and client-side code, making it easier to integrate payment solutions like Stripe and PayPal. In this guide, we’ll cover how to integrate these payment systems into a Next.js application using the App Router for a seamless transaction experience.

Part 1: Setting Up Your Next.js Project

Start by creating a new Next.js project if you haven't already:

bun x create-next-app@latest my-payment-app

Navigate to your project directory:

cd my-payment-app

Part 2: Integrating Stripe

Stripe is one of the most popular payment gateways due to its simplicity and extensive features. Here’s how to integrate Stripe into your Next.js application:

  1. Install Stripe Packages

    Install the Stripe Node.js library for server-side interactions and the Stripe JavaScript library for client-side interactions:

    bun add stripe
    bun add @stripe/stripe-js
  2. Set Up Stripe in API Routes

    Create an API route for handling payments in your app/api directory:

    // app/api/checkout/route.ts
    
    import { NextResponse } from 'next/server';
    import Stripe from 'stripe';
    
    const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
      apiVersion: '2022-08-01',
    });
    
    export async function POST(request: Request) {
      const { amount } = await request.json();
    
      try {
        const paymentIntent = await stripe.paymentIntents.create({
          amount,
          currency: 'usd',
          payment_method_types: ['card'],
        });
    
        return NextResponse.json({ clientSecret: paymentIntent.client_secret });
      } catch (error) {
        return NextResponse.json({ error: error.message }, { status: 500 });
      }
    }
  3. Add Stripe to Your Frontend

    In your page or component, set up the Stripe.js and Elements to handle the payment UI:

    // app/page.tsx
    
    'use client';
    
    import { loadStripe } from '@stripe/stripe-js';
    import { Elements, CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
    import { useState } from 'react';
    
    const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!);
    
    function CheckoutForm() {
      const stripe = useStripe();
      const elements = useElements();
      const [loading, setLoading] = useState(false);
    
      const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
        event.preventDefault();
    
        if (!stripe || !elements) return;
    
        setLoading(true);
    
        const response = await fetch('/api/checkout', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ amount: 5000 }), // amount in cents
        });
    
        const { clientSecret } = await response.json();
    
        const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
          payment_method: {
            card: elements.getElement(CardElement)!,
          },
        });
    
        if (error) {
          console.error(error);
          setLoading(false);
        } else if (paymentIntent?.status === 'succeeded') {
          console.log('Payment succeeded!');
          setLoading(false);
        }
      };
    
      return (
        <form onSubmit={handleSubmit}>
          <CardElement />
          <button type="submit" disabled={!stripe || loading}>
            {loading ? 'Processing...' : 'Pay'}
          </button>
        </form>
      );
    }
    
    export default function Page() {
      return (
        <Elements stripe={stripePromise}>
          <CheckoutForm />
        </Elements>
      );
    }

Part 3: Integrating PayPal

PayPal is another widely-used payment gateway. Follow these steps to integrate PayPal into your Next.js application:

  1. Install PayPal SDK

    Add the PayPal SDK to your project:

    bun add @paypal/checkout
  2. Set Up PayPal in Your Frontend

    Create a component to handle PayPal payments:

    // app/page.tsx
    
    'use client';
    
    import { useEffect } from 'react';
    import Script from 'next/script';
    
    export default function Page() {
      useEffect(() => {
        if (window.paypal) {
          window.paypal.Buttons({
            createOrder: () => {
              return fetch('/api/paypal/create-order', {
                method: 'POST',
              }).then(res => res.json()).then(data => data.orderID);
            },
            onApprove: async (data: any) => {
              await fetch('/api/paypal/capture-order', {
                method: 'POST',
                body: JSON.stringify({ orderID: data.orderID }),
              });
    
              alert('Payment successful!');
            },
          }).render('#paypal-button-container');
        }
      }, []);
    
      return <div id="paypal-button-container"></div>;
    }
  3. Set Up PayPal API Routes

    Create API routes for handling PayPal transactions:

    // app/api/paypal/create-order/route.ts
    
    import { NextResponse } from 'next/server';
    
    export async function POST() {
      const res = await fetch('https://api-m.sandbox.paypal.com/v2/checkout/orders', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${process.env.PAYPAL_CLIENT_SECRET}`,
        },
        body: JSON.stringify({
          intent: 'CAPTURE',
          purchase_units: [{ amount: { value: '50.00' } }],
        }),
      });
    
      const data = await res.json();
      return NextResponse.json({ orderID: data.id });
    }
    // app/api/paypal/capture-order/route.ts
    
    import { NextResponse } from 'next/server';
    
    export async function POST(request: Request) {
      const { orderID } = await request.json();
    
      const res = await fetch(`https://api-m.sandbox.paypal.com/v2/checkout/orders/${orderID}/capture`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${process.env.PAYPAL_CLIENT_SECRET}`,
        },
      });
    
      const data = await res.json();
      return NextResponse.json(data);
    }

Part 4: Handling Payments Securely

  • Environment Variables: Ensure your API keys and secrets are stored securely in environment variables (.env.local file).
  • Server-Side Validation: Perform server-side validation and payment verification to prevent fraud and ensure secure transactions.

Conclusion

Integrating payment systems like Stripe and PayPal into your Next.js application can significantly enhance your e-commerce platform by providing smooth and secure transaction experiences. By leveraging Next.js's App Router, you can efficiently handle payment processes, manage API routes, and create a seamless user experience. With these integrations, you're well-equipped to handle payments in your Next.js application, offering your users a reliable and professional payment experience.