Sling Academy
Home/Node.js/How to add Stripe payment to NestJS

How to add Stripe payment to NestJS

Last updated: January 07, 2024

Overview

Integrating payment systems into modern web applications is central to enabling e-commerce and monetizing services. One of the most popular payment gateways today is Stripe, known for its simplicity and robust API. In this guide, we’ll learn how to seamlessly integrate Stripe’s payment processing features into a NestJS application, an emerging JavaScript backend framework that leverages Node.js.

Setting Up NestJS

Before we delve into Stripe, ensure you have Node.js installed on your system. Create a new NestJS project by running npx @nestjs/cli new payment-app. Once inside your new ‘payment-app’ directory, install the Stripe NPM package with npm install stripe.

Establishing Stripe as a Service in NestJS

It’s best practice in NestJS to encapsulate external services as injectable providers. Let’s create a Stripe service.

import { Inject, Injectable } from '@nestjs/common';
import Stripe from 'stripe';

@Injectable()
export class StripeService {
  private stripe: Stripe;

  constructor() {
    this.stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
      apiVersion: '2024-08-27',
    });
  }
}

Take notice of the environment variable STRIPE_SECRET_KEY. You’ll need to retrieve your secret key from the Stripe dashboard and include it in your application’s environment variables.

Processing a Payment

To handle payments, we’ll need to create endpoints that interact with the Stripe API. A basic payment flow involves creating a charge.

@Injectable()
export class StripeService {
  // ... existing code ...

  async createCharge(amount: number, currency: string, source: string): Promise {
    return this.stripe.charges.create({
      amount,
      currency,
      source,
    });
  }
}

Add a controller to handle requests for payment:

@Post('charge')
async chargeCard(@Body() paymentData: PaymentDto) {
  return this.stripeService.createCharge(paymentData.amount, paymentData.currency, paymentData.source);
}

Above, we assume a PaymentDto class is already defined to handle the payment data input.

Working with Webhooks

Stripe uses webhooks to notify your application of events happening on your Stripe account. Setting up a webhook endpoint involves validating Stripe events.

@Post('webhook')
@Header('Content-Type', 'application/json')
async webhook(@Req() request: Request, @Res() response: Response) {
  const sig = request.headers['stripe-signature'];

  let event;

  try {
    event = this.stripe.webhooks.constructEvent(request.body, sig, process.env.STRIPE_ENDPOINT_SECRET);
  } catch (err) {
    return response.status(400).send(`Webhook Error: ${err.message}`);
  }

  // Handle the event...
  response.status(200).send({ received: true });
}

Don’t forget to replace STRIPE_ENDPOINT_SECRET with your actual endpoint signing secret obtained from Stripe’s webhook settings.

Advanced Features

Although a simple charge creation was covered, complex applications may require subscriptions, and customer management, amongst other features. Stripe’s API is vast, and fortunately, NestJS’s modular structure allows for easy expansion of services.

To manage subscriptions:

//... stripe service methods ...

async createSubscription(customerId: string, priceId: string): Promise {
  return this.stripe.subscriptions.create({
    customer: customerId,
    items: [{ price: priceId }],
  });
}

Customer management:

//... stripe service methods ...

async createCustomer(email: string): Promise {
  return this.stripe.customers.create({ email });
}

Conclusion

In the stream of transactions, your NestJS reeds must be nimble enough to sway with the ebb and flow of commerce. Sprinkle the magic of Stripe within your NestJS pond, and your application will hum with the currents of financial exchange. This guide paddled you through the silent waters of beginning the integration, may your journey downstream handle the complexities your business demands.

Next Article: NestJS: Using Faker.js to populate database (for testing)

Previous Article: NestJS Issue: Middleware Not Working – Solutions Explained

Series: Nest.js Tutorials: From Basics to Advanced

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates