Subscription Payments #4: Access premium content based on subscription plan

Subscription Payments #4: Access premium content based on subscription plan

Languages | Tools Used | Time Saved

Node.js, HTML Stripe 3 weeks → 40 mins

Goodies

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.

Subscription Payments #1: Adding Basic and Pro subscription plans using Stripe
Subscription Payments #2: Keeping track of Customer Billing information using Mongo and Stripe Webhooks
Subscription Payments #3: Update and Cancel plans via a Manage Billing Screen using Stripe

Every SaaS app needs subscription payments - a recurring payment. Users need to be able to change or cancel their plans, go through a trial phase to see if they even would like to pay for premium features.

On the free plan, customers have access to standard content. For access to premium content, they can subscribe to the Basic or Pro plan. We can show our customers different content depending on their level of access. In Part 4, we will:

  • Allow access to content at /basic only when the user is on the Basic plan, else show nothing.

Add Plan-Specific content

To be able to show content, we need to update our UI so it links to plan-specific content i.e. /basic for basic plan, /pro for pro plan and so on. Edit the views/account,ejs and the links.

<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> 

Set Current User Middleware

With express middleware, implementing this behavior is very easy.

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('/')
  }
}

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')
    }
  }
}

In app.js

app.get('/none', [setCurrentUser, hasPlan('none')], async function (
  req,
  res,
  next
) {
  res.status(200).render('none.ejs')
})

app.get('/basic', [setCurrentUser, hasPlan('none')], 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')
})