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

ยท

5 min read

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

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
  • Let's create a section
<section className="relative flex flex-wrap lg:h-screen lg:items-center font-sans"></section>
  • 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>

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>

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>

Add this React state to your application,

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

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>

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

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"

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;

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);
    }
  };

Import this two things to your Next application

import { loadStripe } from "@stripe/stripe-js";
import axios from "axios";

It's time to add stripePromise,

const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY!);

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;
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.

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!

Cover image - Dribbble

ย