Stripe payment gateway integration in node.js
Tags: node, javascript, webdev
Published: 2021-06-28 00:19:45

Hello guys, Today we gonna implement stripe payment gateway in node. We create simple order and pay with card. Stripe checkout gives us beautiful UI and various payment options. For better understanding **watch demo video** and support my channel 🙂.

So  let's start coding...

**Demo Video** 
{% youtube 0WM0YL8tKp4 %}

[Project Github Link](https://github.com/sk-Jahangeer/node-stripe-payment-gateway)

**Create Node.js App**
```javascript
$ mkdir node-stripe-payment-gateway
$ cd node-stripe-payment-gateway
$ npm init --yes
$ npm install express stripe
```
**Express :** Express is minimal and flexible Node.js web applicaton framework.
**Stripe :** The Stripe Node library provides convenient access to the stripe API.

**The package.json look like :**
```json
{
  "name": "node-stripe-payment-gateway",
  "version": "1.0.0",
  "description": "Implementing stripe payment gateway in node.js",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "author": "jahangeer",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "stripe": "^8.156.0"
  }
}
```
**Configure Payment Route**
In root folder, create **index.js** file
```javascript
const express = require("express");
const app = express();
const path = require("path");
const stripe = require("stripe")("Add your secret key");

const YOUR_DOMAIN = "http://localhost:8080";

// static files
app.use(express.static(path.join(__dirname, "views")));

// middleware
app.use(express.json());

// routes
app.post("/payment", async (req, res) => {
    const { product } = req.body;
    const session = await stripe.checkout.sessions.create({
        payment_method_types: ["card"],
        line_items: [
            {
                price_data: {
                    currency: "inr",
                    product_data: {
                        name: product.name,
                        images: [product.image],
                    },
                    unit_amount: product.amount * 100,
                },
                quantity: product.quantity,
            },
        ],
        mode: "payment",
        success_url: `${YOUR_DOMAIN}/success.html`,
        cancel_url: `${YOUR_DOMAIN}/cancel.html`,
    });

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

// listening...
const port = process.env.PORT || 8080;
app.listen(port, () => console.log(`Listening on port ${port}...`));
```
**Style.css**
/views/style.css
```css
.container {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    background: #f5f5f5;
}

.product {
    width: 250px;
    padding: 10px;
    height: auto;
    background-color: white;
    border-radius: 5px;
    border: 2px solid black;
}

.product_img {
    width: 100%;
    height: 250px;
    object-fit: contain;
    border-bottom: 1px solid black;
}

.description {
    display: flex;
    justify-content: space-between;
}

#btn {
    width: 100%;
    padding: 10px;
}
```
**Checkout UI**
/views/checkout.html
```html
<!DOCTYPE html>
<html>
  <head>
    <title>Buy Products</title>
    <link rel="stylesheet" href="style.css">
    <script src="https://js.stripe.com/v3/"></script>
  </head>
  <body class="container" >
      <div class="product">
        <img
          src="https://store.storeimages.cdn-apple.com/4668/as-images.apple.com/is/iphone-12-purple-select-2021?wid=470&hei=556&fmt=jpeg&qlt=95&.v=1617130317000"
          alt="iphone 12"
          class="product_img"
        />
        <div class="description">
          <h3>iPhone 12</h3>
          <h4>&#8377 100.00</h4>
        </div>
        <button type="button" id="btn">BUY</button>
      </div>
  </body>
  <script type="text/javascript">
    // Create an instance of the Stripe object with your publishable API key
    var stripe = Stripe("Add your publishable key");
    var checkoutButton = document.getElementById("btn");

    checkoutButton.addEventListener("click", function () {
      fetch("/payment", {
        headers: {'Content-Type': 'application/json'},
        method: "POST",
        body: JSON.stringify({
            "product": {
                "name": "iPhone 12", 
                "image": "https://store.storeimages.cdn-apple.com/4668/as-images.apple.com/is/iphone-12-purple-select-2021?wid=470&hei=556&fmt=jpeg&qlt=95&.v=1617130317000", 
                "amount": 100,
                "quantity": 1
            }})
      })
        .then(function (response) {
          return response.json();
        })
        .then(function (session) {
          return stripe.redirectToCheckout({ sessionId: session.id });
        })
        .then(function (result) {
          // If redirectToCheckout fails due to a browser or network
          // error, you should display the localized error message to your
          // customer using error.message.
          if (result.error) {
            alert(result.error.message);
          }
        })
        .catch(function (error) {
          console.error("Error:", error);
        });
    });
  </script>
</html>
```
**Transaction Success UI**
/views/success.html
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Transaction Sucess</title>
    <link rel="stylesheet" href="style.css">
</head>
<body class="container" >
    <div class="product">
        <img
        src="https://png.pngtree.com/png-vector/20191104/ourmid/pngtree-checkmark-icon-green-color-png-image_1952984.jpg"
        alt="succes tick mark"
        class="product_img"
      />
      <h3 style="text-align: center" >Transaction Successful</h3>
    </div>
</body>
</html>
```
**Transaction Cancel UI**
/views/cancel.html
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cancel order</title>
    <link rel="stylesheet" href="style.css">
</head>
<body class="container" >
    <div class="product">Forgot to add something to your cart? Shop around then come back to pay!</div>
</body>
</html>
```
That's it, run the server and test api with fake card details. I hope you have learned something new. 

**Thank You...**