Case Study — Subscription Site

Alpine 100 (a community interest company) wanted to set up a "100 club" social lottery to help support winter athletes at all levels.

The lottery needed to be web-based, and provide:

  • member sign-up and subscription control
  • donations collection
  • grant application for athletes
  • posting of news articles (for non-developer users)
  • tracking payments
  • running the monthly lottery draw

Technical Stack

Stack design for subscription service

The final system design was:

  • website written in React, styled with Bulma.io and statically generated using Gatsby.js
  • simple Google sheets-based CMS for news articles
  • back-end elements of the booking system written as Gatsby (serverless) functions
  • whole website hosted on Netlify (linked to a GitHub repo for automated builds)
  • database hosted at Supabase
  • integrated with Stripe for subscriptions and donations, using Stripe APIs to project user's data
Alpine 100 subscription system - home screen
Alpine 100 subscription system - Stripe payment screen

Subscriptions

By integrating with Stripe using their subscription APIs and a webhook, we are able to maintain a record of how many tickets a user is buying, and what payments have been successfully completed, without holding any payment information. Stripe also provides all the tools and UI for managing (or cancelling) subscriptions, and can even send reminder emails when a payment method is close to expiring — so we don't have to spend time building them.

Content Management

There are several CMS integrations available with Gatsby. For Alpine 100, the brief was that the CMS should be simple to use, and (importantly) free.

Whilst we've previously implemented Decap CMS, we eventually decided to go with a Google sheets integration instead. Alongside a Netlify hook on the admin page, that allows the user to simply write their text into the Google sheet and generate an updated news article.

Alpine 100 subscription system - CMS
Alpine 100 subscription system - news item

Authentication & Access Control

Normally user authentication would happen on the server, but we don't have one. Instead, the Alpine 100 system uses JSON web tokens (JWTs), a type of browser cookie.

When a user signs in, a serverless function checks username and password, and after validation a JWT is stored in the browser. The JWT is encoded, and includes an identifier that can be checked against the database. It's also given an expiry date — a week in this case.

Whenever the booking page is revisited, or a request is made, the system checks  that a valid JWT is present. If not, any JWT will be deleted and the user will be shown the log-in screen. Logging out also deletes the JWT — meaning the log-in screen will be shown again.

Benefits

The benefits of this solution are:

  • Most of the website is statically generated, served by Netlify's Content Delivery Network (CDN). This means very quick load times and low hosting costs.
  • No server required. The booking system uses serverless functions to provide an API. We can still provide interaction, database access and full user-authentication.
  • Database is provided by Supabase (a Database-as-a-Service).
  • Stripe provide the full service for subscription payments, management and reminders — we don't need to hold any of that data.
  • Low running costs ...

Running Costs

We selected service providers and engineered the system to be efficient to keep running costs down.

Service Provider Cost
Code Repository GitHub Free
Hosting Netlify Free Tier
Database Supabase Free Tier available

While Supabase has a generous free tier, we recommend using the first paid tier which has the benefit of automated backups and doesn't pause the database if there are period of inactivity. Costs for a service like the Alpine 100 booking system are very low.

For more information or to discuss a project, please email [email protected].