DEV Community

Cover image for Integrating Stripe into Your Nest.js Application
Ameni Ben Saada
Ameni Ben Saada

Posted on

Integrating Stripe into Your Nest.js Application

Hello everyone, This is Ameni Ben Saada, back again with a new article to share what I've recently learned. Today, we are going to talk about Stripe ( Stripe has transformed how businesses handle online payments, making it essential for modern e-commerce platforms) why we use it and how to implement it.

What is stripe ?

Stripe is a technology company that builds economic infrastructure for the internet. Businesses of all sizes—from new startups to public companies—use Stripe's software to accept payments and manage their businesses online.

It was founded in 2010 by Patrick and John Collison and has quickly become one of the top payment processors globally. Stripe is known for its developer-friendly approach, making it easy to set up and use.

Why Use Stripe?

  • Ease of Use: Stripe makes it easy to integrate payment processing into your website or app.
  • Security: Stripe handles the security of payments, ensuring that sensitive information is protected.
  • Global Reach: Stripe supports many currencies and payment methods, allowing businesses to operate internationally.

How stripe works ?

We need to understand how Stripe works before writing any code.

  1. First, The user selects a subscription plan.
  2. Then proceed to the payment step and enter their card information.
  3. When the user clicks the submit button, the following actions will take place in our backend:
    • A new subscription is created using the selected plan and the provided payment method.
    • The payment method is attached to the customer.
    • A new Stripe customer is created if the customer does not already exist in Stripe.
  4. A webhook is set up to enable communication between Stripe and our backend. This webhook verifies whether the payment was successful or not since Stripe sends various events (like payment success, payment failure, etc.) to our backend via webhooks and we need to process these events

Image description

This process ensures that the user’s subscription is properly created and their payment is securely processed.

Now moving to our favorite part, writing some code

Implementing Stripe in Nest.js

Let's walk through setting up Stripe in a Nest.js application:

If you haven't already, create a new Nest.js application and install the necessary packages then we need to create one using Nest’s CLI, install @nestjs/config to get environment variables and stripe’s npm package.

nest new nestjs-stripe && npm i @nestjs/config && npm install stripe
Enter fullscreen mode Exit fullscreen mode

Once the installation is complete, the next step is to create a stripe folder inside */src*. This structure is optional; you can organize it according to your preference.

Create a module, controller, and service for Stripe. Remember to place your Stripe API key in the .env file. You can name the key anything you like, but for consistency with the setup instructions, name it STRIPE_API_KEY.

Let's begin with setting up the Stripe module. It should look something like this:

import { DynamicModule, Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { StripeController } from './stripe.controller';
import { StripeService } from './stripe.service';

@Module({})
export class StripeModule {

  static forRootAsync(): DynamicModule {
    return {
      module: StripeModule,
      controllers: [StripeController],
      imports: [ConfigModule.forRoot()],
      providers: [
        StripeService,
        {
          provide: 'STRIPE_API_KEY',
          useFactory: async (configService: ConfigService) =>
            configService.get('STRIPE_API_KEY'),
          inject: [ConfigService],
        },
      ],
    };
  }
}
Enter fullscreen mode Exit fullscreen mode

let’s add the stripe service

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

@Injectable()
export class StripeService {
  private readonly stripe: Stripe;
  private readonly logger = new Logger(StripeService.name);

  constructor(@Inject('STRIPE_API_KEY') private readonly apiKey: string) {
    this.stripe = new Stripe(this.apiKey, {
      apiVersion: '2024-04-10',
    });
    this.logger.log('StripeService initialized with API version 2023-10-16');
  }

  async getProducts(): Promise<Stripe.Product[]> {
    try {
      const products = await this.stripe.products.list();
      this.logger.log('Products fetched successfully');
      return products.data;
    } catch (error) {
      this.logger.error('Failed to fetch products from Stripe', error.stack);
      throw new Error('Unable to fetch products from Stripe');
    }
  }

  async getCustomers(): Promise<Stripe.Customer[]> {
    try {
      const customers = await this.stripe.customers.list();
      this.logger.log('Customers fetched successfully');
      return customers.data;
    } catch (error) {
      this.logger.error('Failed to fetch customers from Stripe', error.stack);
      throw new Error('Unable to fetch customers from Stripe');
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

now let’s move to the controller

import { Controller, Get, HttpException, HttpStatus, Logger } from '@nestjs/common';
import { StripeService } from './stripe.service';
import { Stripe } from 'stripe';

@Controller('stripe')
export class StripeController {
  private readonly logger = new Logger(StripeController.name);

  constructor(private readonly stripeService: StripeService) {}

  @Get('products')
  async getProducts(): Promise<Stripe.Product[]> {
    try {
      const products = await this.stripeService.getProducts();
      this.logger.log('Products fetched successfully');
      return products;
    } catch (error) {
      this.logger.error('Failed to fetch products', error.stack);
      throw new HttpException('Failed to fetch products', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  @Get('customers')
  async getCustomers(): Promise<Stripe.Customer[]> {
    try {
      const customers = await this.stripeService.getCustomers();
      this.logger.log('Customers fetched successfully');
      return customers;
    } catch (error) {
      this.logger.error('Failed to fetch customers', error.stack);
      throw new HttpException('Failed to fetch customers', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

That's it for setting up Stripe in your Nest.js application. The next steps involve configuring the webhook, setting up the payment gateway, and implementing the subscription creation process. Let me know if you'd like me to continue writing the next steps.

I hope you learned something valuable from this article. If you have any feedback or notice anything that could be improved, please let me know. I'd love to hear your thoughts and make any necessary corrections.

Top comments (0)