Integrating Stripe with NestJS: A Step-by-Step Tutorial

Integrating Stripe with NestJS: A Step-by-Step Tutorial
Integrating Stripe with NestJS: A Step-by-Step Tutorial


When building modern web applications, especially e-commerce platforms, integrating payment systems is a crucial component. Stripe stands out as one of the best payment gateways, offering simplicity, flexibility, and robust security features. Pairing it with NestJS, a progressive Node.js framework, allows developers to create scalable and efficient payment solutions.

In this detailed tutorial, you’ll learn how to integrate Stripe into a NestJS application step-by-step, with a focus on creating a backend API to handle payments.

Why Stripe and NestJS?

Before diving in, here’s why Stripe and NestJS make a great combination:

  1. Scalable and Secure: Stripe ensures PCI-compliant transactions, while NestJS offers a modular structure for building scalable backends.
  2. Developer-Friendly: Stripe’s APIs and SDKs are intuitive, while NestJS provides tools like decorators and dependency injection to simplify development.
  3. Advanced Features: Stripe supports payments, subscriptions, invoicing, and more, which can easily be incorporated into your NestJS app.


Prerequisites

Before starting, ensure you have the following:

  • Node.js installed (v16+ recommended).
  • A basic understanding of NestJS and TypeScript.
  • A Stripe account (sign up at stripe.com).
  • A code editor (e.g., VS Code).

Step 1: Setting Up a NestJS Project

First, create and configure a new NestJS project.

Install the NestJS CLI

npm install -g @nestjs/cli

Create a New Project

nest new nestjs-stripe-tutorial


Choose a package manager (npm or yarn) when prompted.

Navigate to the Project Directory

cd nestjs-stripe-tutorial

Install Stripe Library and Config Module

The Stripe library will allow you to interact with the Stripe API, and the @nestjs/config module will help you manage environment variables.

npm install stripe @nestjs/config

Step 2: Setting Up Environment Variables

To keep your sensitive API keys secure, store them in a .env file.

Create a .env File

In the root of your project, create a .env file and add your Stripe keys:

STRIPE_SECRET_KEY=sk_test_your_secret_key
STRIPE_PUBLISHABLE_KEY=pk_test_your_publishable_key

Load Environment Variables

Modify the AppModule to include the ConfigModule:

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config'; @Module({ imports: [ConfigModule.forRoot()], }) export class AppModule {}

Step 3: Create a Stripe Service

A service will encapsulate all the logic for interacting with Stripe’s API.

Generate a Service

Run the following command to create a Stripe service:

nest generate service stripe

Configure the Service

Edit the stripe.service.ts file to initialize the Stripe client:

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config'; import Stripe from 'stripe'; @Injectable() export class StripeService { private stripe: Stripe; constructor(private readonly configService: ConfigService) { this.stripe = new Stripe(this.configService.get<string>('STRIPE_SECRET_KEY'), { apiVersion: '2022-11-15', }); } async createPaymentIntent(amount: number, currency: string) { return this.stripe.paymentIntents.create({ amount, currency, }); } }
  • The Stripe client is initialized using the secret key from environment variables.
  • The createPaymentIntent method sets up a payment request.

Step 4: Create a Payments Controller

To expose the Stripe functionality, you need a controller.

Generate a Controller

nest generate controller payments

Define the Endpoints

Update the payments.controller.ts file:

import { Controller, Post, Body } from '@nestjs/common';
import { StripeService } from './stripe.service'; @Controller('payments') export class PaymentsController { constructor(private readonly stripeService: StripeService) {} @Post('create-payment-intent') async createPaymentIntent(@Body() body: { amount: number; currency: string }) { const { amount, currency } = body; return this.stripeService.createPaymentIntent(amount, currency); } }
  • The POST /payments/create-payment-intent endpoint allows clients to request a payment intent by sending the amount and currency.

Register the Controller and Service

Update the AppModule:

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config'; import { PaymentsController } from './payments/payments.controller'; import { StripeService } from './payments/stripe.service'; @Module({ imports: [ConfigModule.forRoot()], controllers: [PaymentsController], providers: [StripeService], }) export class AppModule {}


Step 5: Testing the Payment API

Start the Server

npm run start

Test the Endpoint

Use Postman or cURL to test the /payments/create-payment-intent endpoint:

POST http://localhost:3000/payments/create-payment-intent
Content-Type: application/json { "amount": 5000, "currency": "usd" }


If successful, you’ll receive a Stripe payment intent object containing a client_secret key.

Step 6: Integrating with the Frontend

To collect payment details, integrate Stripe’s frontend SDK.

Install Stripe.js

npm install @stripe/stripe-js

Frontend Implementation

Use Stripe’s library to create a payment form. Here’s a basic example using React:

import { loadStripe } from '@stripe/stripe-js';
import { Elements, CardElement, useStripe, useElements } from '@stripe/react-stripe-js'; const stripePromise = loadStripe('pk_test_your_publishable_key'); const PaymentForm = () => { const stripe = useStripe(); const elements = useElements(); const handlePayment = async () => { const response = await fetch('http://localhost:3000/payments/create-payment-intent', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ amount: 5000, currency: 'usd' }), }); const { client_secret } = await response.json(); await stripe.confirmCardPayment(client_secret, { payment_method: { card: elements.getElement(CardElement), }, }); }; return ( <form onSubmit={handlePayment}> <CardElement /> <button type="submit">Pay</button> </form> ); }; const App = () => ( <Elements stripe={stripePromise}> <PaymentForm /> </Elements> );


Advanced Features to Explore

  1. Webhooks: Handle events like successful payments or refunds.
  2. Subscriptions: Use Stripe to manage recurring payments for SaaS platforms.
  3. Customer Portal: Allow users to manage their payment methods via Stripe-hosted pages.

This guide covered the step-by-step process of integrating Stripe with a NestJS application, from setting up your backend to handling payments. By following these steps, you’ve built a modular and scalable payment solution that can be extended with advanced features.

For further exploration, consult the official Stripe documentation and NestJS documentation.

Post a Comment

Previous Post Next Post