Subscription System with Stripe and Express.js

Build a subscription system with Stripe and Express js.

Denisse Avatar

By:

Denisse Abreu
May 08, 2022 12pm ET

Eng/Spa 5-min

Hello 🖐🏼, this is the second part of our project: How to Build A Subscription System With Stripe and Vue js?. In this blog, we'll teach you how to integrate the backend section of this project. As you already know, Stripe needs a backend server to generate the client secret, the key that will give you access to the Stripe Card Element. I will use Express js as a server, making this project a whole javascript application. If you don't have a project, you can copy my Vue Stripe Subscriptions.

1. Set Up Stripe And Express.

  • First, Install the corresponding libraries.
Install through npm
npm install express npm install stripe --save
  • Create a .env file in the project root; please, don't expose your keys directly in the code!
.env

Next, create Index.js; this file will be the data entry point. Create a middleware that will check if the HTTP request is directed to the webhook; if it is, let the request pass without parsing it as a JSON object; otherwise, parse the data and redirect it to the Express router. If you parse the webhook data, Stripe will reject it. We will implement the webhook in a separate blog due to its complexity.

server/index.js
require('dotenv').config() const express = require('express') const cors = require('cors') const app = express() // Middleware app.use((req, res, next) => { if (req.originalUrl === '/api/posts/webhook') { next() } else { express.json()(req, res, next) } }) app.use(cors()) // Router const posts = require('./routes/api/posts') app.use('/api/posts', posts) const port = process.env.PORT || 3000 app.listen(port, () => console.log(`Server is running on port ${port}.`))

Create the Express router file, and start by importing Stripe and the secret key; the first HTTP method is a router post. This method will create the customer using the email and full name. If the customer creation is successful, send back to the frontend the customer id. In production, collect more parameters from the customer, the address and phone number; here, you can check the list of parameters that you can send to Stripe.

server/routes/api/posts.js
require('dotenv').config() const express = require('express') const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); const router = express.Router() // Create Customer router.post('/', async (req, res) => { const { email, fullname } = req.body; if (!email && !fullname) { return res.sendStatus(400); } try { // pass customer fullname and additional parameters const customer = await stripe.customers.create({ email: email, name: fullname }) if (customer) { // save the customer.id as stripeCustomerId // in your database. return res.json({ customer: customer.id }); } } catch (error) { console.log(error); return res.sendStatus(400); } });

The second router post method is subscription creation. Destruct the request body and extract the customer id and the price id, send them to Stripe using the subscription create function. If the create subscription function is successful; retrieve the subscription id and the client secret; Send them back to the front end as a JSON object.

server/routes/api/posts.js
// Create subscription router.post('/subs', async (req, res) => { const { customerId, priceId } = req.body; if (!customerId && !priceId) { return res.sendStatus(403); } try { const subscription = await stripe.subscriptions.create({ customer: customerId, items: [{ price: priceId }], payment_behavior: 'default_incomplete', expand: ['latest_invoice.payment_intent'], }); res.json({ subscriptionId: subscription.id, clientSecret: subscription.latest_invoice.payment_intent.client_secret, }); } catch (error) { return res.sendStatus(400) } });

The last router method is the subscription delete route. In order to delete the subscription, we need the subscription id, create a login system in your application to let the users delete their subscriptions, and retrieve the subscription id from your local database.

server/routes/api/posts.js
// Delete the subscription router.post('/delete', async (req, res) => { try { const deletedSubscription = await stripe.subscriptions.del( req.body.subscriptionId ); res.send(deletedSubscription); } catch (error) { console.log(error); } });