API with NestJS #38. Setting up recurring payments via subscriptions with Stripe

JavaScript NestJS TypeScript

This entry is part 38 of 125 in the API with NestJS

In this series, we’ve implemented a few different ways of charging our users using Stripe. So far, all of those cases have included single payments. With Stripe, we can also set up recurring payments using subscriptions.

Recurring payments are a popular approach nowadays in many businesses. The users save a credit card and get billed once a month, for example. In return, they get access to the platform, such as a streaming service, for example. Since it is a common use case, it is definitely worth looking into.

Creating a product

To create a subscription, we first need to define a product. While we can do it through the API, we only need a single product for our whole application for now. Since that’s the case, we can do that through the Products dashboard.

When we click on the “Add product” button, we need to provide some basic product information. In our case, the product name is the “Monthly plan”.

The second important thing is the price information.

Since we want to implement subscriptions, we choose a recurring price billed monthly. There are more options to choose out from, though.

When we finish creating a product, Stripe redirects us to the details page. Here, we can see the information about the product we’ve just created.

The crucial part, for now, is the pricing section.

Above, we can see the id of the price we’ve set up. We need it to create subscriptions. The most straightforward way of referring to it would be to save it in the environment variables.



Managing subscriptions

To create a subscription for customers, they need to have a default payment method chosen.

Choosing a default payment method

In the previous part of this series, we’ve implemented the feature of saving credit cards. Now, we need to add the option to choose one of them as the default payment method. For that, we need to update the customer’s information.



Above, we handle a case in which a non-existent payment method is chosen or the one that belongs to another customer.

We also need to add a new route to our .



When the customers have the default payment method chosen, we can create a subscription for them.

Creating subscriptions

To manage subscriptions, we first need to create a few methods in our :



The two methods above are quite low-level. To manage our monthly subscriptions, let’s create the :


With the above logic, we allow the customers to subscribe only once and prevent Stripe from charged them too many times. The last part is to create the :


Confirming subscription payments

When we go to the testing page in Stripe documentation, we can see many different testing cards to cover different cases. Some of them require additional authentication when performing payments. Let’s use the route that we’ve created to check the details of the created subscription.

If we see that our subscription is it means that it might require payment. Aside from the , the Subscription also contains the property, which is an id.

We can pass additional properties to the method to change the id to the object.

Now, our endpoint responds with the details about the latest invoice, including the payment intent.

We could create separate endpoints to get the details of the invoices payment intents instead. Now, our endpoint responds with a lot of data that might not be needed. It would be a good idea to map the response from Stripe and remove unnecessary properties.

One of the properties of the payment intent is the . If the subscription status is , we need to use it on the frontend so that the user can authorize the payment.


When we try to confirm the payment, there is a chance that Stripe prompts the user for payment confirmation.

Creating subscriptions with trial periods

We can create a subscription with a customer with a free trial period. To do that, we can use the property.

When we do that, an invoice is still created, but for zero dollars. Once the trial is up, Stripe generates a new invoice. Three days before this happens, Stripe sends an event to our webhook endpoint. Using webhooks is a broad topic, and we will cover it separately.


In this article, we’ve implemented subscriptions into our application. To do that, we’ve had to create a product that requires a periodical charge. We’ve also implemented a way for the users to set up their default payment method and subscribe. We’ve also covered cases such as confirming payments for subscriptions and trial periods. There is still more to cover when it comes to Stripe, so stay tuned!

Series Navigation<< API with NestJS #37. Using Stripe to save credit cards for future useAPI with NestJS #39. Reacting to Stripe events with webhooks >>
Notify of
Inline Feedbacks
View all comments