- Languages: Node, HTML
- Tools Used: Stripe
- Time Saved: 3 weeks -> 40 mins
- Source Code
- Live Demo
This is the Part 4 in the series of guides on adding, managing, and keeping track of subscription payments using Stripe and Mongo for your SaaS app.
Introduction
Subscription Payments are the bread and butter of a SaaS application; it's how you start generating revenue. In a well-implemented system, users need to first be able to change or cancel their plans, and second, undergo a trial phase to see if they would even like to pay for premium features. Typically, it's a hassle to set these up. In this set of guides, we will go through all the steps required to build a complete Subscription Payments system for your SaaS app.
In Part 4, we will:
- Set up an express middleware to extract user information from every request
- Allow customers to access content based on their plan - None, Basic, Pro
Step 1: Add Plan-Specific content
Let's create links to three different pages that will house their own content.
<p>You can access your content by clicking one of the buttons below.</p>
<ul>
<li><a href="/none">None</a></li>
<li><a href="/basic">Basic</a></li>
<li><a href="/pro">Pro</a></li>
</ul>
Step 2: Set Current User Middleware
Currently, for any request made to our server from the client, we have to extract the customer information and get the full profile from the database. Following DRY (Don't Repeat Yourself), we can offload this work to a middleware function in Node.
src/middleware/setCurrentUser.js
:
const UserService = require("../user");
module.exports = async function setCurrentUser(req, res, next) {
const { email } = req.session;
if (email) {
user = await UserService.getUserByEmail(email);
req.user = user;
next();
} else {
res.redirect("/");
}
};
We can set up another middleware to figure out what plan the customer is currently on.
src/middleware/hasPlan.js
module.exports = function hasPlan(plan) {
return async (req, res, next) => {
if (req.user && req.user.plan == plan) {
next();
} else {
res.status(401).send("Unauthorized");
}
};
};
We are now ready to use our middlewares and make our code easier to read.
app.js
const setCurrentUser = require("./src/middleware/setCurrentUser");
const hasPlan = require("./src/middleware/hasPlan");
//...
app.get(
"/none",
[setCurrentUser, hasPlan("none")],
async function (req, res, next) {
res.status(200).render("none.ejs");
}
);
app.get(
"/basic",
[setCurrentUser, hasPlan("basic")],
async function (req, res, next) {
res.status(200).render("basic.ejs");
}
);
app.get(
"/pro",
[setCurrentUser, hasPlan("pro")],
async function (req, res, next) {
res.status(200).render("pro.ejs");
}
);
Step 3: Test it out
- Subscribe to the Basic plan
- Try to access the
/pro
endpoint - Unauthorized - Now try to access the
/basic
endpoint - Success!
!https://launchman-space.nyc3.cdn.digitaloceanspaces.com/saasbase/images/2021/05/1-3.png
Next Steps
In this guide, we learned how to:
- Set up an express middleware to extract user information from every request
- Allow customers to access content based on their plan - None, Basic, Pro
Our subscription payments system is mostly complete. But before we can deploy it to Production, we have to make some changes - use a cloud DB, set up the production webhook, and more. This is what we will tackle in the next part.