DEV Community

Cover image for Ultimate Stripe Subscriptions: Recurring Payments With Examples
Md. Maruf Rahman
Md. Maruf Rahman

Posted on • Edited on • Originally published at practicaldev.online

Ultimate Stripe Subscriptions: Recurring Payments With Examples

Implementing subscription payments is essential for SaaS applications. In this guide, we'll learn how to integrate Stripe subscriptions with Node.js and React, including checkout sessions, webhooks, customer portal, and subscription management.

Building a SaaS application means you need to handle recurring payments, and Stripe makes this process straightforward. After implementing Stripe subscriptions in multiple production applications, I've learned the patterns that work reliably and scale well.

In this guide, I'll show you how to implement a complete Stripe subscription system with minimal code. We'll cover creating checkout sessions, handling webhooks, managing subscriptions, and integrating the customer portal. The examples are production-ready and follow Stripe's best practices.

What is Stripe Subscriptions?

Stripe Subscriptions is a payment solution that handles:

  • Recurring billing - Automatic monthly/yearly charges
  • Subscription management - Upgrade, downgrade, cancel subscriptions
  • Customer portal - Self-service billing management
  • Webhooks - Real-time subscription lifecycle events
  • Proration - Automatic billing adjustments for plan changes
  • Multiple payment methods - Credit cards, ACH, and more

Installation and Setup

First, let's install Stripe:

npm install stripe
Enter fullscreen mode Exit fullscreen mode

Configure Stripe with your API keys:

import Stripe from 'stripe';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  apiVersion: '2025-02-24.acacia',
});
Enter fullscreen mode Exit fullscreen mode

Stripe Service: Core Functions

Create a service class to handle Stripe operations:

import Stripe from 'stripe';

export class StripeService {
  // Get or create Stripe customer
  static async getOrCreateCustomer(userId: string, email: string) {
    // Check if user already has a customer ID
    const user = await getUser(userId);
    if (user?.stripeCustomerId) {
      return user.stripeCustomerId;
    }

    // Create new customer
    const customer = await stripe.customers.create({
      email,
      metadata: { userId },
    });

    // Save customer ID to database
    await updateUser(userId, { stripeCustomerId: customer.id });
    return customer.id;
  }

  // Create checkout session for new subscription
  static async createCheckoutSession(
    userId: string,
    userEmail: string,
    planId: string,
    billingInterval: 'monthly' | 'yearly'
  ) {
    const plan = await getPlan(planId);
    const priceId = billingInterval === 'monthly' 
      ? plan.stripePriceIdMonthly 
      : plan.stripePriceIdYearly;

    const customerId = await this.getOrCreateCustomer(userId, userEmail);

    const session = await stripe.checkout.sessions.create({
      customer: customerId,
      line_items: [{ price: priceId, quantity: 1 }],
      mode: 'subscription',
      success_url: `${FRONTEND_URL}/dashboard?session_id={CHECKOUT_SESSION_ID}`,
      cancel_url: `${FRONTEND_URL}/pricing`,
      metadata: { userId, planId, billingInterval },
    });

    return session.url!;
  }
}
Enter fullscreen mode Exit fullscreen mode

Best Practices

  1. Use Stripe webhooks for subscription events
  2. Store customer IDs in your database
  3. Handle subscription lifecycle events
  4. Implement customer portal for self-service
  5. Handle errors gracefully
  6. Test with Stripe test mode

πŸ“– Read the Complete Guide

This is just a brief overview! The complete guide on my blog includes:

  • βœ… Webhook Handling - Processing subscription events
  • βœ… Customer Portal - Self-service billing management
  • βœ… Subscription Management - Upgrade, downgrade, cancel
  • βœ… Payment Methods - Handling multiple payment methods
  • βœ… Error Handling - Comprehensive error management
  • βœ… Real-world examples from production applications

πŸ‘‰ Read the full article with all code examples here


What's your experience with Stripe subscriptions? Share your tips in the comments! πŸš€

For more backend guides, check out my blog covering Express.js, Prisma ORM, JWT Authentication, and more.

Top comments (0)