API with NestJS #37. Using Stripe to save credit cards for future use

JavaScript NestJS TypeScript

This entry is part 37 of 158 in the API with NestJS

With Stripe, we can build advanced custom payment flows. In this article, we continue looking into it and save credit cards for future use. To do that, we need to have a more thorough understanding of how we can integrate Stripe with our system.

Saving cards with setup intents

Our goal in this article is to have payment credentials saved and ready for future payments. Imagine creating a website for an online shop. We could require the users to provide the credit card details every time they make an order, but that wouldn’t be the best user experience. Instead, we can save the credit card details in Stripe and use them later.

To get us through this process, Stripe uses setup intents. We can set up a payment method without creating a charge and assign it to a customer.

We need to add the above functionality to the that we’ve created in the previous part of this series.

To use the above method, let’s create the .



As you can see, we expect the users to send us the when adding the credit card. To achieve that on the frontend side with React, we need to do it the same way as in the previous article. This time, we call the endpoint, though.


There is one additional thing we should do above, though. In the previous part of this series, we’ve used the parameter. Using it when saving a card would attempt to confirm it immediately.

The above solution might work, but it is not guaranteed. The bank might require the user to perform some additional authentication on the frontend. To handle it, let’s use the Stripe provides us with when creating the payment intent.


When we call the on the frontend, Stripe has a chance to carry out any actions needed to confirm the card setup.

Listing saved credit cards

Another important part of the flow is listing the credit cards that the user saved. To implement it, let’s add a new method to the .


To use it, we also need to modify the :


A significant thing to notice here is that Stripe doesn’t allow us to view all of the card’s details. For example, we can see only the last four digits of the card number, and we can’t access the CVV code.

There is a great chance that our application doesn’t need to expose that much data about the credit cards. If that’s the case for you, feel free to modify the Stripe’s response in the endpoint.

By default, the returns up to 10 credit cards. If you need more, you need to use pagination with the and properties. For details, check the documentation.

If you want to know more about pagination in general, take a look at API with NestJS #17. Offset and keyset pagination with PostgreSQL and TypeORM

Charging using saved cards

The last part of the flow is charging the customer using the saved card. Let’s use the logic from the previous article, but with the   parameter.

By setting to , we indicate that it occurs without the direct involvement of the customer with the use of previously collected credit card information. Let’s use the above logic in the .


An important change above is that we return the response from the method. This is because setting to might work, but there is a chance that the bank will require additional authentication. We need to prepare for this scenario on the frontend.

The above controller returns all of the data returned by Stripe. Feel free to remove unused data and send only the and the to the frontend, for example.

By doing the above, we try to confirm the charge immediately. If it fails, we call the method. It might require the customer to perform additional steps to complete the payment, depending on the bank. Stripe walks the user through this process.

Testing our integration

Stripe provides a set of credit cards for testing that always work. With them, the confirmation on the backend will succeed without issues.

To confirm that our integration works well for other cases, we can use the 3D secure test card numbers, for example. They require us to properly handle confirmation when saving the credit cards and using them later.

We can also test for specific responses, and errors with credit card numbers Stripe prepared exactly for those cases.


In this article, we’ve continued integrating Stripe with our NestJS API. We’ve learned how to save credit cards for future use. We’ve also made payments with them and learned how to confirm them on the frontend side. By doing so, we’ve learned even more about how to implement Stripe into our application. There is still quite a bit to learn, so stay tuned!

Series Navigation<< API with NestJS #36. Introduction to Stripe with ReactAPI with NestJS #38. Setting up recurring payments via subscriptions with Stripe >>
Notify of
Newest Most Voted
Inline Feedbacks
View all comments
2 years ago

Hey, thanks for your lessons.
Can you provide the react repo link?

2 years ago

I followed the tutorial. It works fine to add a credit-card but. using Get creditcards the data object returns empty. Is the API changed? I tried adding same package ‘stripe’ as in original code.

“object”: “list”,
“data”: [],
“has_more”: false,
“url”: “/v1/payment_methods”