Integrating payment schemes with stripe in nodejs
Tags: stripe, javascript, node, beginners
Published: 2022-11-06 10:22:22

Integrating payments to a project  is one of the most important and challenging part and in this article we will be looking at how to integrate payment schemes using Stripe to a nodejs project by building a Tip sending App.

## Prerequisites 
Basic Knowledge  of nodejs,express framework ,callback functions, promises, HTML & tailwind css 

## Why use stripe 
- Highly customizable and secured 
- Easy to integrate supporting almost all th payment gateways 
- Structured and easy to understand documentation 
- Sdks available for most of the programming languages like python ,ruby , nodejs , C# ,etc.
- Used by most of the leading companies for payment outsourcing 
 

## Dependencies installation 
In order to build this tip sending app we need to install the following dependencies via npm 

``` npm i express hbs stripe body-parser ```

## Folder structure 
`index.js` will be in the root directory followed by `index.html`, `pay.js` &  `success.html` under the `views` folder
![Folder Sturucture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aa1kaqudxjx3nt8yvq85.png)

## Start the server 
Inorder to create an express server add the following code to your `index.js` file 

```js
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = process.env.PORT || 5000;
app.listen(port, () => console.log('Listening on port 5000...'));

```
Now open the terminal  and use `node index.js` and your server will be started.


![Server is listening ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pwiw9bf5rv4ddfsyitpt.png)

## Create the Payment Page  
Inside the views folder create a `index.html`  and add the following code 
```html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body>
  <nav class="bg-blue-400 h-32 flex justify-center">
    <h1 class="text-white text-8xl font-mono">Send me a Tip</h1>
  </nav>

  <div class="flex justify-center my-12">
    <form action="/tip" method="POST" class="flex flex-col w-1/3">
      <input class="p-3 h-12 border-2 m-4  bg-gray border-zinc-300 rounded outline-none" type="text" name="name" placeholder=" Enter your Full Name">
      <input class="p-3 h-12 border-2 m-4  bg-gray border-zinc-300 rounded outline-none"type="email"  name="email" placeholder="Enter your Email ">
     <span>$ <input class="p-3 h-12 border-2 m-4  bg-gray border-zinc-300 rounded outline-none" type="text" name="amount" placeholder="Enter tip in USD"></span> 
      <div id="pay-element" class="bg-blue-400 p-2 h-12 m-2 rounded"></div>
      <div id="pay-errors" role="alert"></div>
      <button class="text-white bg-blue-400 p-2 m-2 rounded">Send a Tip</button>
    </form>
  </div>
  
<script src="https://js.stripe.com/v3/"></script>
<script src="pay.js"></script>
</body>
</html>
```
Here  you can see that there are two empty `div` elements having the id of `pay-element` and `pay-errors` and there we will collect the card details from the user with the help of stripe card elements. 

Now create the `pay.js` file and add the following code
```js
const stripe = Stripe('STRIPE PUBLISHER KEY'); 
const elements = stripe.elements();

var style = {
  base: {
    color: "#00000"
  }
};

/* Create a payment Element*/ 
const payment = elements.create('card', { style });

payment.mount('#pay-element');

const form = document.querySelector('form');
const errorEl = document.querySelector('#pay-errors');

const tokenHandler = token => {
  const hiddenInput = document.createElement('input');
  hiddenInput.setAttribute('type', 'hidden');
  hiddenInput.setAttribute('name', 'stripeToken');
  hiddenInput.setAttribute('value', token.id);
  form.appendChild(hiddenInput);

  form.submit();
}

/*Generate token using form data */
form.addEventListener('submit', e => {
  e.preventDefault();

  stripe.createToken(payment).then(res => {
    if (res.error) errorEl.textContent = res.error.message;
    else tokenHandler(res.token);
  })
})
``` 

Here we are using the Stripe Elements object in order to create a card element and we are passing these card elements to those empty divs.


Now let's create a success page , so that on every successful payment the user will be redirected to a confirmation page. Again in the views folder  Create a `success.html` and add the following code.


```html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="https://cdn.tailwindcss.com"></script>
  <title>Payment successful</title>
</head>

<body >
  <div class="flex flex-col items-center mt-24 text-black text-4xl">
  <h1>Your payment was successful !</h1>
    <a href="/"><button class="bg-gray-400 rounded px-4 m-3">Home</button></a>
  </div>
</body>

</html>
``` 

## Setup the handle bars 
In the `index.js` file add the following code in order to render these html pages 
```js
var hbs = require('hbs');
app.set('view engine', 'html');
app.engine('html', require('hbs').__express);
app.use(express.static(path.join(__dirname, './views')));

``` 
Let's preview our app now using `node index.js`

![Preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/no2vul6qf4gytnq97ciz.png)

For now the payment will not work as we haven't add the request to our backend 

## Implementing the stripe payment request
Inorder  to implement payments to our app now lets add the stripe module in our server code 
```js
const stripe = require('stripe')('STRIPE SECRET KEY');
/* Create a payment request using stripe */
app.post("/tip", (req, res) => {
  try {
    stripe.customers
      .create({
        name: req.body.name,
        email: req.body.email,
        source: req.body.stripeToken
      })
      .then(customer =>
        stripe.charges.create({
          amount: req.body.amount * 100,
          currency: "usd",
          customer: customer.id
        })
      )
      .then(() => res.render("success.html"))
      .catch(err => console.log(err));
  } catch (err) {
    res.send(err);
  }
});
```
Now finally use `node index.js ` to start your sever and start using the app.

![test payment ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/llmpbae52xzb6i4xhaij.png)

![payment success](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6qq1k97rpztxk3zbg1ho.png)


![stripe dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mu2v1u2odw24xfi1selb.png)

## Extra tips 
- Always use test mode during development 
- Make Sure to hide your API keys using environment variables
- Check out the Stripe Documentation [here]('https://stripe.com/docs/')