DEV Community

Cover image for Let's make a Sponsor page with Next JS and Stripe
Dhairya Shah
Dhairya Shah

Posted on • Originally published at codewithsnowbit.hashnode.dev

Let's make a Sponsor page with Next JS and Stripe

Today, let's build a sponsor page with Next JS and Stripe.

Wish you all the best 🙌

Introduction

Next JS - Next.js is an open-source web development framework built on top of Node.js enabling React-based web applications functionalities such as server-side rendering and generating static websites.

Stripe - Stripe is a payment service provider that accepts credit cards, digital wallets and many other payment methods.

Both tools are such an amazing thing and I believe you will love them.

Setting up Next JS application

Just like React, let's create the next app including Tailwind CSS for styling our app, so we will use with-tailwindcss

npx create-next-app -e with-tailwindcss my-sponsors-site
Enter fullscreen mode Exit fullscreen mode

Setting up Stripe

We are going to use Stripe for accepting payments. Let's head up to the Stripe and sign up/in.

  • Head over to the left corner and create account for your application Create account

*Grabbing API Keys *

  • Go to the Developers tab at the top right to the navigation - Go to developers tab
  • Then go to the API keys section, then you will be able to see your SECRET API keys.

API Section

  • Keep them safe 🔐
*Tada 🎉 You have just completed 1/4 part 🙌*

It's time for the front-end

So, we are going with a simple and slick UI; you can definitely change it as per your taste 🍟. Here's a glance at the design.

glance at the design

  • Go to your project directory, and open your prefered text editor/IDE
  • Go to pages/index.tsx and remove all the piece of code under return() and add these <> </> brackets inside it. Here's what your code should look like.
import type { NextPage } from 'next'
import Head from 'next/head'
import Image from 'next/image'

const Home: NextPage = () => {
  return (
    <>

    </>
  )
}

export default Home

Enter fullscreen mode Exit fullscreen mode
  • Let's create a section
<section className="relative flex flex-wrap lg:h-screen lg:items-center font-sans"></section>
Enter fullscreen mode Exit fullscreen mode
  • Inside it let's add a DIV
<div className="w-full px-4 py-12 lg:w-1/2 sm:px-6 lg:px-8 sm:py-16 lg:py-24"></div>
Enter fullscreen mode Exit fullscreen mode

Let's add some text

<div className="max-w-lg mx-auto text-center">
      <h1 className="text-2xl font-bold sm:text-3xl">Sponsor me!</h1>

      <p className="mt-4 text-gray-500">
      Lorem ipsum dolor sit amet consectetur adipisicing elit.
      </p>
</div>
Enter fullscreen mode Exit fullscreen mode

demo 1

Adding Form Card

<div className="max-w-md mx-auto mt-8 mb-0 space-y-4">
      <div>
        <label  className="sr-only">Enter amount (USD)</label>

        <div className="relative">
          <input
            type="number"
            className="w-full p-4 pr-12 text-sm border-gray-200 rounded-lg shadow-md"
            placeholder="Enter amount (USD)"
            onChange={e => setAmount(parseInt(e.target.value) * 100)}
          />

          <span className="absolute inset-y-0 inline-flex items-center right-4 text-gray-400">
            $
          </span>
        </div>
      </div>

      <div className="flex items-center justify-between">
        <p></p>
        <button
          className="inline-block px-5 py-3 ml-3 text-sm font-medium text-white bg-blue-500 rounded-lg"
          onClick={checkoutSession}
          disabled={!amount}
          role="link"
        >
          Sponsor
        </button>
      </div>
    </div>
Enter fullscreen mode Exit fullscreen mode

Add this React state to your application,

const [amount, setAmount] = useState<number | null>(0)
Enter fullscreen mode Exit fullscreen mode

New look 🎉

new look

Adding image

Let's create another DIV outside the container DIV and right above the closing tag of </section>

 <div className="relative w-full h-64 sm:h-96 lg:w-1/2 lg:h-full bg-cover">
    <img
      className="absolute inset-0 object-cover w-full h-full"
      src="bg.webp"
      alt="BG"
    />
  </div>
Enter fullscreen mode Exit fullscreen mode

Image source - Dribbble

Final looks of the website 🙌
Final looks

*Tada 🎉 You have just completed 2/4 part 🙌*

Setting up Stripe checkout

Install these packages

npm i axios @stripe/stripe-js stripe

// OR

yarn add axios @stripe/stripe-js stripe

Enter fullscreen mode Exit fullscreen mode

We are going to perform check out using Stripe as soon as the user clicks the button 🤩 excited about that?

First of all, we need to set up the most important thing.

Setting up environment variables

We can create .env.local file and store our SECRET API keys. The benefit of saving them in .env file as they are not get pushed to the repository when you commit changes.

STRIPE_SECRET_KEY="stripe secret key"
NEXT_PUBLIC_STRIPE_PUBLIC_KEY="stripe publishable key"
Enter fullscreen mode Exit fullscreen mode

Make sure to restart the server after adding values in the .env.local file

Setting up an API endpoint

Let's create an API to process the payment with Stripe. Therefore, create a new file inside pages/api as checkout.js.

And add the following piece of code to it -

const stripe = require("stripe")(`${process.env.STRIPE_SECRET_KEY}`);
import { NextApiRequest, NextApiResponse } from "next";


const paymentHandler = async (req: NextApiRequest, res: NextApiResponse) => {
  const { amount } = req.body;
  const url = "http://localhost:3000";

  const items = [
    {
      price_data: {
        currency: "usd",
        product_data: {
          name: `Sponsoring SnowBit`,
        },
        unit_amount: amount,
      },
      quantity: 1,
    },
  ];

  const session = await stripe.checkout.sessions.create({
    line_items: items,
    mode: "payment",
    success_url: `${url}/success`,
    cancel_url: url,
  });

  res.status(200).json({ id: session.id });
};

export default paymentHandler;
Enter fullscreen mode Exit fullscreen mode

Implementing API to our front-end

Let's create a function

  const checkoutSession = async () => {
    const stripe = await stripePromise;
    const checkoutSession = await axios.post("/api/checkout", {
      amount: amount,
    });

    const result = await stripe?.redirectToCheckout({
      sessionId: checkoutSession.data.id,
    });

    if (result?.error) {
      alert(result?.error.message);
    }
  };
Enter fullscreen mode Exit fullscreen mode

Import this two things to your Next application

import { loadStripe } from "@stripe/stripe-js";
import axios from "axios";
Enter fullscreen mode Exit fullscreen mode

It's time to add stripePromise,

const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY!);
Enter fullscreen mode Exit fullscreen mode

The payment should work now 🎉

Creating Success Page

Create a file success.tsx and add the following code to it -

const ThankYou = () => {
    return (
      <div className="flex justify-center items-center h-screen">
        <h1 className="text-4xl mx-auto animate-bounce font-bold">
          Thank you for supporting!  
        </h1>
      </div>
    );
  };

  export default ThankYou;
Enter fullscreen mode Exit fullscreen mode
*Tada 🎉 You have just completed 3/4 part 🙌*

Testing

Use Stripe Testing Cards to test payment

*Tada 🎉 You have just completed 4/4 part 🙌*

Conclusion

Tada! You have now created a sponsor page.

Important links

GitHub Repository

Feel free to reach me out via Twitter - @codewithsnowbit

🌏 Let's connect

Stay tuned for the next article. Stay safe and Happy Coding!

If you enjoyed and find my content helpful, then you can check this out
Buy me a coffee

Cover image source - Dribbble

Top comments (0)