VRATIX Logo

βœ…

Checkout Sessions

βœ…

Payment Links

βœ…

List Available Subscription Plans

βœ…

Upsells at Checkout

βœ…

Plan Upgrades/Downgrades with Prorating

βœ…

Subscription Cancellation at End of Billing

βœ…

Seat-Based Subscriptions

πŸ—οΈ

Usage-Based Subscriptions

πŸ—οΈ

Free Tiers

About

The Stripe Subscriptions API module provides a full-featured integration for subscription-based billing using Stripe, allowing developers to quickly monetize their apps without complex setup. It offloads the logic of managing products and prices to Stripe, keeping your database lightweight and minimizing data synchronization issues.

Installation

To add the Stripe Subscriptions Module to your project, run:

npx vratix add stripe-subscriptions

.env

Add the following environment variables to your .env file:

  • STRIPE_API_KEY: A server-side Stripe API secret key
    • Default: None (required)
    • Example: STRIPE_API_KEY=sk_test_...
  • STRIPE_WH_SECRET: Webhook endpoint secret from the Stripe Developer Dashboard
    • Default: None (required)
    • Example: STRIPE_WH_SECRET=whsec_...
  • CHECKOUT_SUCCESS_URL: Redirect URL after successful payment
    • Default: None (required)
    • Example: CHECKOUT_SUCCESS_URL=https://yourdomain.com/payment-success
  • CHECKOUT_CANCEL_URL: Redirect URL if payment is canceled
    • Default: None (required)
    • Example: CHECKOUT_CANCEL_URL=https://yourdomain.com

Dependencies

The auth-basic module is required for user management and authentication and will be installed automatically with this module.

Usage

To start using the module, import the router in your entry file, such as server.ts:

import { router as subscriptionRouter } from "@/routes/subscription.js";
 
app.use("/subscription", subscriptionRouter);

This module leverages Stripe as the source of truth, storing minimal subscription data on your end:

  • Customer ID, Subscription ID, and Plan Key (plan).

Subscription Key (plan)

The plan key is composed from the Stripe price lookup_key or the Stripe product name in lowercase, e.g., team_pro, so checking if a user is subscribed can be as simple as user.plan === 'team_pro'.

Subscription Object

The module simplifies Stripe’s API responses, returning only the relevant properties in a structured format:

{
  "plan": "team_pro",
  "name": "Team Pro Plan",
  "description": "Pro features for you and your whole team",
  "priceId": "price_...",
  "interval": "monthly",
  "priceType": "per_unit",
  "price": {
    "currency": "USD",
    "amount": 2000 // $20.00 represented as a whole intiger
  },
  "features": ["Unlimited API calls", "Team management", "Granular access"]
}

Seat-Based Subscriptions

Seats can be configured during Stripe Checkout by adjusting the quantity property for the subscription. To disable this behaviour remove the line_items.adjustable_quantity property.

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

You can also manually set the number of seats by adding the seats property before creating a Stripe Checkout URL.

Endpoints

The Stripe Subscriptions Module exposes the following endpoints:

MethodEndpointDescription
POST/Lists available subscriptions
GET/userLists current subscriptions of the authenticated user
POST/payment/checkoutGenerates a Stripe Checkout URL for user subscriptions
POST/payment/linkGenerates a reusable Stripe Payment Link for user subscriptions
PATCH/:subscriptionIdUpgrades/Downgrades subscription, prorates based on current billing period
POST/:subscriptionId/seatAdds a user to a seat in a seat-based subscription (Owner only)
DELETE/:subscriptionId/seatRemoves a user from a seat in a seat-based subscription (Owner only)
PATCH/:subscriptionId/seatAdjusts seat count (Owner only)
DELETE/:subscriptionId/cancelCancels subscription at end of billing period, no future charges (Owner only)
POST/:subscriptionId/cancelStops pending cancellation, renews subscription at end of billing (Owner only)

Errors

Below are common errors with solutions for this module:

Error CodeNameSolution
404SubscriptionNotFoundVerify subscription ID and ensure it's an active subscription for the user
409NoAvailableSeatsEither increase seat count or remove a user to free up a seat
403NoEmptySeatsToRemoveEnsure seat count matches or exceeds currently occupied seats
400CantRemoveSubOwnerSubscription owner cannot be removed from seats, cancel subscription to stop billing
400StripeWebhookEventNotSupportedConfirm correct Stripe webhook events are configured on the Stripe Developer Dashboard

Examples

To explore sample requests and responses, download our Postman collection: