Logo

dev-resources.site

for different kinds of informations.

Stripe Subscription Integration in Node.js [2024 Ultimate Guide]

Published at
11/21/2024
Categories
javascript
stripe
webdev
node
Author
ivanivanovv
Categories
4 categories in total
javascript
open
stripe
open
webdev
open
node
open
Author
11 person written this
ivanivanovv
open
Stripe Subscription Integration in Node.js [2024 Ultimate Guide]

Getting Stripe subscriptions working with backend services can be tricky and often leads to what developers call the dreaded “brain split” - managing both Stripe's logic and your own backend data in sync.

At Vratix, we’ve tackled this problem head-on while building our Open Source Stripe Subscriptions API Module. Here's how we approach Stripe subscription billing in Node.js to keep things simple, scalable, and developer-friendly.

Core Principle: Let Stripe Be the Source of Truth

The key is to shift as much of the logic to Stripe while keeping your database minimal. We only store:

  • Customer ID
  • Subscription ID
  • Plan

This way, we avoid:

  • Overcomplicated backend logic
  • Error-prone webhook implementations for syncing dashboard changes
  • Data redundancy

With this approach, you still have a fully functional subscription billing system while relying on Stripe as the single source of truth.

Features of Our Implementation

By the end of this guide, you’ll have a subscription-based app supporting:

  • User subscription plans
  • Checkout sessions
  • Subscription upsells
  • Available plan listing

Tech Stack

  • PostgreSQL
  • Node.js + Express.js
  • TypeScript

Step 1: Database Design

We start by designing a clean, minimal database table:

CREATE TABLE user_subscriptions (  
    "id" SERIAL PRIMARY KEY,  
    "plan" VARCHAR NOT NULL,  
    "user_id" INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,  
    "customer_id" VARCHAR,  
    "subscription_id" VARCHAR NOT NULL,  
    "is_owner" BOOLEAN NOT NULL DEFAULT TRUE,  
    "created_at" TIMESTAMP NOT NULL DEFAULT NOW(),  
    UNIQUE (user_id, subscription_id)  
);
Enter fullscreen mode Exit fullscreen mode

Key points:

  • user_id: References your internal user table
  • plan: Tracks the subscription plan
  • subscription_id: The Stripe subscription ID
  • is_owner: Flags the primary subscription holder

Step 2: Controllers

We use a factory function to keep the business logic modular and testable. Here's a snippet from our Stripe Subscription Controller:

async getSubscriptions() {  
  const stripePrices = await stripe.prices.list({  
    active: true,  
    type: "recurring",  
    expand: ["data.product"],  
  });  

  return stripePrices.data.map((price) => {  
    const product = price.product as Stripe.Product;  
    return {  
      plan: price.lookup_key || product.name.toLowerCase().replaceAll(" ", "_"),  
      name: product.name,  
      priceId: price.id,  
      interval: price.recurring!.interval,  
      price: { currency: price.currency, amount: price.unit_amount },  
    };  
  });  
}  
Enter fullscreen mode Exit fullscreen mode

Key highlights:

  • Custom subscription keys: Derived from the product name or lookup_key for clean plan checks (user.plan === 'pro_plan').
  • Stripe-first approach: We fetch subscription data directly from Stripe, avoiding the “brain split.”

Step 3: Streamlined Stripe Checkout

Our createCheckout function sets up a subscription checkout session:

const checkout = await stripe.checkout.sessions.create({  
  line_items: [  
    {  
      price: priceId,  
      adjustable_quantity: { enabled: true },  
      quantity: seats || 1,  
    },  
  ],  
  mode: "subscription",  
  subscription_data: { metadata: { userId } },  
  success_url: CHECKOUT_SUCCESS_URL,  
  cancel_url: CHECKOUT_CANCEL_URL,  
});  

return { url: checkout.url! };  
Enter fullscreen mode Exit fullscreen mode

Want to Skip All This?

We’ve packaged everything into a ready-to-go Open Source module. In less than 30 seconds, you can set up:

  • Stripe integration
  • Authentication
  • Database configuration
  • Prebuilt routes and SQL queries

Run this:

npx vratix init  
Enter fullscreen mode Exit fullscreen mode

Check out our Stripe Subscriptions Module Docs for more details.

The full code is available on our GitHub repo.

See a demo video how to do all of this with a working UI here.

I’d love to hear your thoughts - does this make building subscription APIs easier? Let us know what features you’d like to see next!

stripe Article's
30 articles in total
Favicon
Boost Your Shopify Sales in Australia, the US, and Beyond: Accept Various Payment Methods and Currencies with Stripe
Favicon
Boost Your Shopify Sales in Poland, Europe, and Beyond: Accept Various Payment Methods and Currencies with Stripe
Favicon
Is Stripe your only choice for payment gateway in Sharetribe?
Favicon
Stripe Invoice.Upcoming changes: model switching from monthly to yearly
Favicon
Replay failed stripe events via webhook
Favicon
Building a Payment System for Your Flutter App: A Journey with Stripe Connect and Firebase
Favicon
Understanding Laravel Cashier's Core Traits: A Deep Dive
Favicon
Creating Stripe Test Data in Python
Favicon
Simplifying Payments with Pay gem: A Guide to Using Stripe in Rails
Favicon
Comparison of the middleware implementation between Supabase Auth documentation and the nextjs-stripe-supabase.
Favicon
Building a Custom Shipping Calculator with Stripe and Netlify Functions for Multi-Currency (€/$), Quantity, and Location Support
Favicon
🌟Open-source SaaS Starter: React + Firebase + Stripe + i18n
Favicon
Creating a marketplace with Stripe Connect: The onboarding process
Favicon
Stripe Subscription Integration in Node.js [2024 Ultimate Guide]
Favicon
Clerk Update – November 12, 2024
Favicon
Integrating Stripe Payment Intent in NestJS with Webhook Handling
Favicon
How Mocking Against a Public API Endpoints within Blackbird Gets your API in Production Faster
Favicon
How to add Stripe to Astro
Favicon
Designing Idempotent APIs
Favicon
Building E-Commerce Platforms with Next.js and Stripe: A Step-by-Step Guide
Favicon
How to retrieve the Transactions from Stripe
Favicon
Integration with Stripe for Payment Processing on AWS
Favicon
Providing receipts for in-person transactions with Terminal
Favicon
Providing receipts for in-person transactions with Terminal
Favicon
Top 10 Payment Processors for Next.js Applications [2024]
Favicon
Fixing the Stripe API Key Error When Migrating Next.js from Vercel to Azure Static Web Apps
Favicon
Announcing the Release of my Stripe to SevDesk Integration
Favicon
Receive payments easily using Stripe and PHP
Favicon
Integrating Payment Gateways in Next.js 14
Favicon
Experimenting with pricing: Finding the right strategy for growth!

Featured ones: