Add Payments With Stripe using Node Js

Add Payments With Stripe using Node Js

Payment integration into your web apps has always been a difficult task for me until I found Stripe's Charges API. In this article, we will discuss how we can leverage the Charges API to accept payments from users.

Pre Requisites

Understanding the basics of promises and how to set up an Express Server

Installation

To set things up, we need a few things. We will create a Node Js based API which will handle user information and process the payments through stripe. In order to do that, we will need "express" for the server and "nodemon" to automatically restart the server when we make changes. We will need "cors" for allowing our frontend application to securely connect to our backend server. And of course, we'll use "stripe" to access all the cool features of the Stripe payment system.

$ npm i express nodemon stripe cors

Before setting up routes, let's suppose we are making a registration system where the user has to pay $50 before completing the registration. The information required from the user for signing up is username, email, password, isPaid for payment confirmation, and phone. Here is what our code is going to look like:

const express = require('express')
const cors = require('cors')
const mongoose = require('mongoose')
const stripe = require('stripe')('YOUR_STRIPE_SECRET_KEY')

const app = express()

app.use(cors())
app.use(express.json())

mongoose.connect('YOUR_MONGODB_CONNECTION_STRING', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

const UserSchema = new mongoose.Schema({
  username: { type: String, required: true },
  password: { type: String, required: true },
  email: { type: String, required: true },
  phone: { type: String, required: true },
  paymentId: { type: String },
  isPaid: { type: Boolean, default: false },
})

const User = mongoose.model('User', UserSchema)

app.post('/api/users', async (req, res) => {
  const { username, password, email, phone } = req.body
  const user = new User({ username, password, email, phone })
  try {
    const paymentIntent = await stripe.paymentIntents.create({
      amount: 5000,
      currency: 'usd',
      metadata: { username, email },
    })
    user.paymentId = paymentIntent.id
    await user.save()
    res.json({ clientSecret: paymentIntent.client_secret })
  } catch(err) {
    console.log(err)
    res.status(500).json({ error: 'Unable to create payment intent'})
  }
})

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

In the above snippet, we have set up an express server, created a User model, and added a route '/api/users'. When this route is accessed by the frontend, a payment intent is created at the backend based on the information coming from the frontend. Stripe then generates a client_secret which is sent back to the frontend and the paymentIntentId is stored in the database. After this process, a payment form appears at the frontend which is powered by stripe, the user is asked to enter the card details into that form and that information is then sent to another endpoint which is explained in the snippet below:

app.post('/api/payments', async (req, res) => {
  const { paymentId } = req.body;
  const user = await User.findOne({ paymentId });

  if (!user) {
    return res.status(404).json({ error: 'User not found' });
  }

  const payment = await stripe.paymentIntents.retrieve(paymentId);

  if (payment.status === 'succeeded') {
    user.isPaid = true;
    await user.save();
    res.json({ message: 'Payment succeeded' });
  } else {
    res.json({ error: 'Payment not succeeded' });
  }
})

The route '/api/payments' is accessed after the signup process is completed and it receives a paymentId in the request's body. That paymentId is used to find the user data associated with that payment from the database. Stripe provides the functionality to retrieve the status of the payment based on the paymentId. After receiving the payment information, we can check the status of the payment, if it says "succeeded" then the isPaid value of the user is updated to true otherwise it stays the same and this route sends the response "Payment succeeded" for successful payment and vice versa.

By following the steps mentioned above, we can successfully setup an express server that can handle payments using Stripe. For more information, visit the official documentation of Stripe.