| title | Stripe Subscriptions | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| description | Making Stripe subscriptions a piece of cake. Add subscription billing to your app within minutes | |||||||||||||
| features |
|
|||||||||||||
| postmanCollection | https://app.getpostman.com/run-collection/39515350-cd2bdb24-9802-4392-811b-ff743b769305?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D39515350-cd2bdb24-9802-4392-811b-ff743b769305%26entityType%3Dcollection%26workspaceId%3D36bf5973-695a-44e0-889e-bba83a364391 | |||||||||||||
| testCoverage | 98 |
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.
To add the Stripe Subscriptions Module to your project, run:
npx vratix add stripe-subscriptionsAdd 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
The auth-basic module is required for user management and authentication and will be installed automatically with this module.
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).
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'.
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"]
}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.
The Stripe Subscriptions Module exposes the following endpoints:
| Method | Endpoint | Description |
|---|---|---|
| POST | / |
Lists available subscriptions |
| GET | /user |
Lists current subscriptions of the authenticated user |
| POST | /payment/checkout |
Generates a Stripe Checkout URL for user subscriptions |
| POST | /payment/link |
Generates a reusable Stripe Payment Link for user subscriptions |
| PATCH | /:subscriptionId |
Upgrades/Downgrades subscription, prorates based on current billing period |
| POST | /:subscriptionId/seat |
Adds a user to a seat in a seat-based subscription (Owner only) |
| DELETE | /:subscriptionId/seat |
Removes a user from a seat in a seat-based subscription (Owner only) |
| PATCH | /:subscriptionId/seat |
Adjusts seat count (Owner only) |
| DELETE | /:subscriptionId/cancel |
Cancels subscription at end of billing period, no future charges (Owner only) |
| POST | /:subscriptionId/cancel |
Stops pending cancellation, renews subscription at end of billing (Owner only) |
Below are common errors with solutions for this module:
| Error Code | Name | Solution |
|---|---|---|
| 404 | SubscriptionNotFound | Verify subscription ID and ensure it's an active subscription for the user |
| 409 | NoAvailableSeats | Either increase seat count or remove a user to free up a seat |
| 403 | NoEmptySeatsToRemove | Ensure seat count matches or exceeds currently occupied seats |
| 400 | CantRemoveSubOwner | Subscription owner cannot be removed from seats, cancel subscription to stop billing |
| 400 | StripeWebhookEventNotSupported | Confirm correct Stripe webhook events are configured on the Stripe Developer Dashboard |
To explore sample requests and responses, download our Postman collection: