Let's make a Sponsor page with Next JS and Stripe
Tags: react, javascript, webdev
Published: 2022-03-11 08:55:01

Today, let's build a sponsor page with [Next JS](https://nextjs.org/) and [Stripe](https://stripe.com/).

Wish you all the best 🙌

## Introduction

[Next JS](https://nextjs.org/) - 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](https://stripe.com/) - 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`
```bash
npx create-next-app -e with-tailwindcss my-sponsors-site
```

## Setting up Stripe
We are going to use [Stripe](https://stripe.com/) 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](https://cdn.hashnode.com/res/hashnode/image/upload/v1646925476515/59f3ENvF-.png)

**Grabbing API Keys **
- Go to the **Developers** tab at the top right to the navigation -
![Go to developers tab](https://cdn.hashnode.com/res/hashnode/image/upload/v1646925726038/JDK3qF99_.png)
- Then go to the **API keys** section, then you will be able to see your **SECRET** API keys.

![API Section](https://cdn.hashnode.com/res/hashnode/image/upload/v1646925978609/0ilPR_pgx.png)

- Keep them safe 🔐

<center>*Tada 🎉 You have just completed 1/4 part 🙌*</center>

## 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](https://cdn.hashnode.com/res/hashnode/image/upload/v1646926503150/GZWyeB6m1.png)

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

```js
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

```html
<section className="relative flex flex-wrap lg:h-screen lg:items-center font-sans"></section>
```

- Inside it let's add a DIV

```html
<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 
```html
<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](https://cdn.hashnode.com/res/hashnode/image/upload/v1646927577325/KKB6ZbZYh.png)

### Adding Form Card

```html
<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,
```js
const [amount, setAmount] = useState<number | null>(0)
```

New look  🎉

![new look](https://cdn.hashnode.com/res/hashnode/image/upload/v1646927734374/B9IwaHu1C.png)

### Adding image
Let's create another DIV outside the container DIV and right above the closing tag of `</section>`
```html
 <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](https://dribbble.com/shots/14571080-Save-Your-Money)

Final looks of the website 🙌
![Final looks](https://cdn.hashnode.com/res/hashnode/image/upload/v1646927926277/QqRuuro-v.png)


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

## Setting up Stripe checkout
### Install these packages
```bash
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 - 
```js
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
```js
  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
```js
import { loadStripe } from "@stripe/stripe-js";
import axios from "axios";
```

It's time to add stripePromise,
```js
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 -
```js
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;
```

<center>*Tada 🎉 You have just completed 3/4 part 🙌*</center>

### Testing
{% embed https://www.youtube.com/watch?v=IiF7zGn1isE %}

Use [Stripe Testing Cards](https://stripe.com/docs/testing) to test payment

<center>*Tada 🎉 You have just completed 4/4 part 🙌*</center>

## Conclusion
Tada! You have now created a sponsor page.

### Important links 
[GitHub Repository](https://github.com/codewithsnowbit/sponsor-site-stripe)


Feel free to reach me out via Twitter - [@codewithsnowbit](https://twitter.com/codewithsnowbit)
### 🌏 Let's connect
- [GitHub](https://github.com/codewithsnowbit)
- [Twitter](https://twitter.com/codewithsnowbit)
- [YouTube](https://www.youtube.com/channel/UCNTKqF1vhFYX_v0ERnUa1RQ?view_as=subscriber)


> 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7242fho13cwcxlh8jutn.png)](https://www.buymeacoffee.com/codewithsnowbit)


Cover image source - [Dribbble](https://dribbble.com/shots/17285458-Money-illustration)