Integrating Stripe Payment using Node.js and Express.js

» What is Stripe?

  1. Stripe is a popular payment gateway that makes it easy to accept payments online allowing businesses to securely accept online payments.

  2. It supports various payment methods, including credit cards, Apple Pay, and Google Pay.

  3. If you’re a developer looking to accept online payments, Stripe is an amazing solution.

» Set Up a Stirpe Account

  1. Visit stripe.com. and sign up for an account. Once you’re signed in, you’ll have access to the Stripe Dashboard, where you can manage your transactions.

  2. Move to Stripe Dashboard and make sure you are in test mode and not in live mode.

  3. You will see API keys section, there you will have two keys 1. Publishable key 2. Secret key.

  4. We will need secret key, so save that.

» Visit github for Repository

  1. Visit my github repository and clone the repository with the command.
git clone github_repo_name
  1. After cloning, open the folder in Visual Studio.

  2. In terminal, navigate to server folder present in the repository and run the command npm install to install the required dependencies.

npm install
  1. Now you should make sure that you have node_modules folder in the server folder.

» Setting Server Side

  1. In Server folder, create a file and name it server.js

  2. Let’s Start writing the code:

The first requirement will be to load and configure the .env file using the dotenv package we just downloaded. Next, we want to import the express module and create an instance of the Express application. Create a new Express application that represents our server, and it will be done using const app = express()

require('dotenv').config()

const express = require('express')

const app = express()

app.use(express.json())

Now we want to add a middleware to the Express application. express.json() is a built-in middleware that parses incoming requests with JSON payloads.

We will also import the Cors middleware and add it to the Express application using app.use(). cors() allows requests from different origins to access our server’s resources. This is necessary when making requests from a client-side application hosted on a different domain as in our case the front end will be hosted at port 5500 and the server will be hosted at 3000.

const cors = require('cors')

app.use(
    cors({
        origin: 'http://localhost:5500'
    })
)

The next thing we will do is to create a variable called stripe which will require the stripe package. We retrieve the secret key from the environment using process.env.STRIPE_SECRET_KEY, which allows us to keep our sensitive information separate from the codebase.

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY)

Create a .env in server folder and add your API key. Bring the API key from stripe dashboard.

STRIPE_SECRET_KEY=YOUR_SECRET_KEY

Create a storeItems map is created to store the available items for purchase. In our example, there is only one item with an ID of 1, but you can expand this map to include more products.

const storeItems = new Map([
    [1, { priceInCents: 1000, name: 'The Ultimate Docker Course' }],
])

Next, we will set the express application up a route at /create-checkout-session to handle the creation of a checkout session when a POST request is made to that endpoint. Inside the route handler, Stripe’s checkout.sessions.create method is called to create a session. The session configuration includes details like payment method types (in this case, card payments), line items (the products to be purchased), success URL, and cancel URL.

app.post('/create-checkout-session', async (req, res) => {
    try {
        const session = await stripe.checkout.sessions.create({
            payment_method_types: ['card'],
            mode: 'payment',
            line_items: req.body.items.map(item => {
                const storeItem = storeItems.get(item.id)
                return {
                    price_data: {
                        currency: 'usd',
                        product_data: {
                            name: storeItem.name
                        },
                        unit_amount: storeItem.priceInCents
                    },
                    quantity: item.quantity
                }
            }),
            success_url: `${process.env.CLIENT_URL}/success.html`,
            cancel_url: `${process.env.CLIENT_URL}/cancel.html`
        })
        res.json({ url: session.url })
    } catch (e) {
        res.status(500).json({ error: e.message })
    }
})

As you will see above in our code we have a success URL and cancel url set to ${process.env.CLIENT_URL}/success.html This is coming from the .env file. This is checking for success and cancel page in the client folder.

So let’s set this client URL in the .env like this

CLIENT_URL=http://localhost:5500/client

What this does, is to take customers to the success.html file if payment was succeeded and if it was canceled it will take them to the cancel page which is in the client folder.

Finally, the application will starts listening on port 3000, and a message will be logged to the console indicating that the server is running.

app.listen(3000, () => {
    console.log('Server is listening on port 3000')
})

And this is all for server-side code. Let us now fetch the checkout session when the user clicks on the PAY button so that they can be redirected to the stripe checkout page.

» Setting Up Client Side

  1. You will see script.js file in client folder, Open it and let’s write the code for client side.

This is initially what our file looks right now

const button = document.querySelector('button');

button.addEventListener('click', () => {
    console.log('clicked')
});

Now, let’s change this, Within the event listener, we will make a fetch() request to our server at ‘http://localhost:3000/create-pay-session’. This URL corresponds to the route we defined in our Express server to create the checkout session.

const button = document.querySelector('button');

button.addEventListener('click', () => {
    fetch('http://localhost:3000/create-checkout-session', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            items: [
                { id: 1, quantity: 1 },
            ]
        })
    }).then(res => {
        if (res.ok) return res.json()
        return res.json().then(json => Promise.reject(json))
    }).then(({ url }) => {
        // console.log(url)
        window.location = url
    }).catch(e => {
        console.error(e.error)
    })
});

We will set the method of the request to ‘POST’ and provide the headers, ‘Content-Type’ as ‘application/json’. The body of the request contains the items we want to purchase. In this example, we have one item with an ID of 1 and a quantity of 1.

Once the request is sent, we chain a series of then() methods to handle the response. First, we check if the response is OK using res.ok. If it is, we parse the response body as JSON using res.json().

Finally, we assign the window.location to the obtained URL, which effectively redirects the customer to the Stripe Checkout page to complete the payment.

However, If the response is not OK, we will catch method that will allow us to handle any errors that occur during the checkout process.

Now we are also done with our client side, let’s test the stripe payment checkout.

Open the terminal, run the command, npm start to start the server.

npm start

Open http://localhost:5500/client/index.html in browser and click on pay, and check the stripe payment.


And That’s it! You’ve successfully learned how to intergrate stripe payment into your website.

Thank You and Happy coding!😊