Delayed and scheduled payments with Stripe
Tags: payment, stripe, nestjs, react
Published: 2021-09-03 14:24:56

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](https://github.com/arthurPrvst/credit-card-saving-stripe) or [on FMP](https://fast-modular-project.com/modules/reactjs-nestjs-stripe-card-saving)** 🙂

This payment module will be added top of the React/Node/MySQL starter. This starter has already been presented to you in [this article](https://dev.to/fastmodularproject/web-starter-react-nestjs-mysql-3o9i).

# 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 corresponding `one 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 a `Webhook`. It saves all payment status in database as logs records.
- 6. If the `SetupIntent` has a correct status (received from the webhook), the `stripeCustomer` is saved in database in the `User` 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 a `PaymentIntent` 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](https://fast-modular-project.com/modules).


# 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](https://fast-modular-project.com)
* Module "Delayed and scheduled payments" on [GitHub](https://github.com/arthurPrvst/credit-card-saving-stripe).