Hi Sparta!
In this article I will share with you how to execute delayed or scheduled payments in your React and NestJS app 💳
The full source code and the documentation is available on GitHub or on FMP 🙂
This payment module will be added top of the React/Node/MySQL starter. This starter has already been presented to you in this article.
How does it work ?
We'll use Stripe API in order to:
- 1. Save customer's payment credentials
- 2. Execute an offline payment when we want (by triggering the backend from a UI in the front, by adding a cron in the backend...).
For the first step, we'll use Stripe's SetupIntent
that are meant to save credit card info that can be later used as we wish.
For the second step, we'll use Stripe's PaymentIntent
that are meant to execute a payment instantly.
High picture of the workflow
- 1. User loads the page where he can save it's card.
- 2. Frontend asks backend to create a Stripe
SetupIntent
in order to let the user save it's payment credentials. - 3. Backend creates the
SetupIntent
and returns the correspondingone time secret
to the frontend. - 4. User fills all info about it's card (number, CVV...) and does the 3DS authentication if needed. He press the "save my card" buttton.
- 5. Backend is receiving several notifications about the
SetupIntent
status thanks to aWebhook
. It saves all payment status in database as logs records. - 6. If the
SetupIntent
has a correct status (received from the webhook), thestripeCustomer
is saved in database in theUser
table (so we can retrieve all it's card info later). - 7. When you then want to trigger an offline payment for this user, backend only needs to ask stripe all card infos for this particular
stripeCustomer
. It then triggers aPaymentIntent
with all infos previously retrieved, and... TADA ! The delayed payment is done 🎉
Step by step guide
Step 1 - Backend
Add folder backend/stripe
in your backend/src/api
.
Don't forget to add StripeModule
in the imports of the app.module
.
Add folder backend/payment
in your backend/src/api
.
Don't forget to add PaymentModule
in the imports of the app.module
.
In the backend folder, install following dependency:
npm install stripe@8.132.0
Step 2 - Frontend
Add folder frontend/screenExample
in your frontend/src/pages
.
Add following code in pages.navigation.tsx :
<Route exact path="/example" component={PaymentSiScreen}/>
Add folder frontend/services/stripe.service.ts
in your frontend/services
.
In the frontend folder, install following dependency:
npm install @stripe/stripe-js@1.11.0
Step 3 - Stripe credentials
Backend:
Update stripeSecretKey
in StripeController
and StripeService
with the secretKey from your stripe account.
Frontend:
Add stripe public key in PaymentSiScreen
:
stripeSecretKey: "pk_test_XxxXXXXxXXXXXXXxXXxxxxxXxxXXXXxXXXXXXXxXXxxxxxXxxXXXXxXXXXXXXxXXxxxxxXxxXXXXxXXXXXXXxXXxxxxx"
Step 4 - Stripe webhook
In your Stripe account, create a webhook and publish it to production. Your webhook setup will need following events:
- setup_intent.created
- setup_intent.requires_action
- setup_intent.canceled
- setup_intent.setup_failed
- setup_intent.succeeded
- payment_intent.created
- payment_intent.requires_action
- payment_intent.requires_capture
- payment_intent.canceled
- payment_intent.payment_failed
- payment_intent.succeeded
Once published, you'll have a webhookSecret
available.
You can now update stripeWebhookSecretKey
in StripeService
with this webhookSecret.
Bonus
If you want to contact your users when they correctly saved their card or when a delayed payment failed, you can use a mailer module and send mail in the webhook function in stripe/stripe.service.ts
. This other module is available here.
Conclusion
I hope this module will help you ! Do not hesitate to pin and star on GitHub if you appreciated the article ❤️
Links:
- The platform sharing the starter and it's modules: Fast Modular Project
- Module "Delayed and scheduled payments" on GitHub.
Top comments (0)