DEV Community

Michael Burrows
Michael Burrows

Posted on • Originally published at w3collective.com

Stripe payment implementation in Node.js

In this tutorial we’ll be building a simple “Buy me a coffee” app using Stripe and Node.js. Before beginning you’ll need to create a Stripe account (free) and have Node.js installed. Once complete you’ll have a fully functioning form that allows users to send you payments.

Setting up the project

Open a new terminal window and run the following commands to setup the project:

mkdir stripe-node
cd stripe-node
npm init -y
npm install body-parser ejs express nodemon stripe
Enter fullscreen mode Exit fullscreen mode

This will initiate the project using the default options and install the following packages:

  • body-parser : parse incoming form data and convert into an easy to use object
  • ejs : view engine for rendering static HTML files compatible with Express
  • express : provides a HTTP server framework for Node.js
  • nodemon : monitors files for changes and restarts the server automatically
  • stripe : allows us to use the Stripe.js library as an ES module.

Setting up the server

Create a new index.js file in the root of the project folder:

touch index.js
Enter fullscreen mode Exit fullscreen mode

First thing we’ll do is setup the Express server:

const express = require('express');
const app = express();
app.listen(3000, () => console.log('Server is running...'));
Enter fullscreen mode Exit fullscreen mode

Let’s now test the setup with the following command:

nodemon index.js
Enter fullscreen mode Exit fullscreen mode

You should see the ‘Server is running…‘ message logged in the terminal.

Setting up the frontend

The frontend will consist of two HTML pages. First the page with the form to collect the payment details (index.html) and a secondary page (success.html) that we’ll redirect the user to if the payment was successful. These HTML files will need to live inside a views folder so go ahead and create that before proceeding.

index.html should contain the following markup:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Buy me a coffee</title>
  </head>
  <body>
    <div class="flex justify-center mt-32">
      <h1>Buy me a coffee</h1>
      <form action="/charge" method="POST">
        <label for="email">Email:</label>
        <input type="email" name="email" placeholder="Email" />
        <label for="amount">$</label>
        <input type="number" name="amount" value="5" />
        <div id="payment-card"></div>
        <div id="payment-errors"></div>
        <button>Submit</button>
      </form>
    </div>
    <script src="https://js.stripe.com/v3/"></script>
    <script src="payment.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

This creates input fields for the user to enter their email and payment amount. The empty payment-card element will be populated with a form to enter credit card information from Stripe.js. This needs to be loaded directly and not bundled into our application to be PCI compliant.

success.html is just a basic file that displays a payment received message:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Buy me a coffee</title>
  </head>
  <body>
    <h1>Payment Received - Thanks!</h1>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Next modify the index.js to include ejs as follows:

const express = require('express');
const app = express();

app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
app.use(express.static('./views'));

app.listen(3000, () => console.log('Server is running...'));
Enter fullscreen mode Exit fullscreen mode

With the server running test this by going to http://localhost:3000/ in the browser.

Setting up the Stripe functionality

Create a payment.js file in the views folder. You’ll need to replace pk_test_XXXXXXXXXXXXXXXXXXXX with your publishable key which can be found in the Stripe dashboard here.

const stripe = Stripe("pk_test_XXXXXXXXXXXXXXXXXXXX"); 
const elements = stripe.elements();
const card = elements.create("card", { hidePostalCode: true });
card.mount("#payment-card");
const form = document.querySelector("form");
const errors = document.querySelector("#payment-errors");
Enter fullscreen mode Exit fullscreen mode

To complete the payment.js setup we’ll add an event listener to the form that creates a token in a hidden input field which is used to encrypt the credit card details when the data is sent to Stripe for processing:

form.addEventListener("submit", (event) => {
  event.preventDefault();
  stripe.createToken(card).then((res) => {
    if (res.error) {
      errors.textContent = res.error.message;
    } else {
      const stripeToken = document.createElement("input");
      stripeToken.setAttribute("type", "hidden");
      stripeToken.setAttribute("name", "stripeToken");
      stripeToken.setAttribute("value", res.token.id);
      form.appendChild(stripeToken);
      form.submit();
    }
  });
});
Enter fullscreen mode Exit fullscreen mode

To complete the project update index.js to create the customer and process the payment. As with the publishable key you’ll need to replace sk_test_XXXXXXXXXXXXXXXXXXXX with your secret key found in the Stripe dashboard:

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const stripe = require('stripe')('sk_test_XXXXXXXXXXXXXXXXXXXX');

app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
app.use(express.static('./views'));

app.use(bodyParser.urlencoded({ extended: true }))
app.post("/charge", (req, res) => {
    try {
      stripe.customers
        .create({          
          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);
    }
  });

app.listen(3000, () => console.log('Server is running...'));
Enter fullscreen mode Exit fullscreen mode

For testing purposes you can use “4242424242424242” as the credit card number, any expiry date in the future and any 3 numbers for the CVC. If everything has been setup correctly when you enter this information you’ll be redirected to the successful payment page.

That’s all for this tutorial. Hopefully it has given you an understanding of how to process Stripe payments in a Node.js application. There are many more configurable options available not used in this tutorial. To discover all these options the offical Stripe.js documentation is an excellent resource.

Oldest comments (0)