How to Set Up Stripe Payments in Feathers.js
Table of content
- Stripe API
- Integrating with Feathers.js
- Agenda Processors
Automated payments are fundamental to scale any tech startup. That is why at Teacode.io, we established a flow for delivering Stripe payments to your product faster than ever. In this post, I will explain this flow to you, so that you can incorporate it to your app as well. First, we will explore the Stripe API and then we will discuss how it fits in with the Feathers.js framework.
Stripe Installation with NPM or Yarn
You can install stripe using your favourite package manager (npm or yarn). It is as simple as running the following commands in your console.
Stripe is the industry standard for automating payments. It provides you with an API, which removes the burden of managing your clients’ sensitive data. We have to first get familiar with some key concepts before we can start integrating Stripe, as a Feathers service, with our app.
The name of this object is rather self-explanatory. A customer is equivalent to your user; this will be the object you refer to when communicating with the Stripe API.
These are created by Stripe for the customer as statements of the amount that is owed to you. They can be generated one-off or in a periodic fashion. These are important to you as they are the actual means through which the customer executes a payment.
Stripe uses this object manages recurrent payments that include paying an invoice via generating periodic ones. It takes away the problem of remembering to invoice your customer regularly. It is assigned to a customer.
This is an object which resides at a higher level than subscriptions supported by Stripe. It tells Stripe how the app should generate a subscription. Such cases include paying both a yearly or a monthly subscription for your product. This would be carried out by creating two plans: monthly and annual. When a customer selects a plan, a subscription will be generated using the plan object’s information.
Stripe uses these to inform you about anything important that has happened. For example, it will notify you when a payment fails, allowing your app to act accordingly. This is carried out using webhooks.
Integrating with Feathers.js
Having the Stripe API’s basic concepts spelt out, we can now dive into the integration with Feathers.js. We will begin by looking at how we can turn our clients into customers, but before we dive in, we first need to set up the stripeClient.
To set up the Stripe Client, we create a new file called stripe.js in the src. The content is as follows.
This will set up your stripe client using the stripe config you have defined, which is then called from your app.js as a configuration.
Now with this setup, we can start building the payments system!
Turning clients into customers
From the client model view, this is relatively simple. We need to add two new fields to our already existing user schema: the customerId and subscriptionPlanId.
Note that the subscriptionPlanId is set to be required. Whether the customer is supposed to pay or not, you want to have a subscription associated. This allows for easier transitions between subscriptions later on.
Now with the model setup, we want to add some logic to it. Let’s create a createStripeCustomer hook function.
For this function, we extract the email that the user-provided on signup and the assigned _id. We create a customer using the stripeCustomers service that we will define a bit later on. Then we patch the client that we just created with the customerId. In the case that something fails we remove the entire user and return the error. This function is then attached to the clients create.after hook.
The following services are supported by Stripe as well:
Now let’s look at the stripe customer service. We have a dedicated model for storing information about the customer. The schema is defined as follows.
Here we store a copy of the customer object from Stripe. For this service, we also define a createStripeCustomer hook function. This function is purely responsible for sending over the required information to Stripe to create a Stripe customer.
You then want to save the result of this request in your stripeCustomers service. In case this fails, remove the stripeCustomer. You are patching the stripeCustomer results in running the after.patch hook, where two methods are present: createTaxId and updateStripeCustomer. First, we will have a look at the createTaxId method.
To create the taxId, we pass the data from the request and send it to stripe using the stripeClient. If the taxId is not present, but it was there earlier, we want to make sure that we remove it from the stripe by calling deleteTaxId. The updateStripeCustomer hook passes all the data that has changed to the stripeClient and requests an update.
Finally, for the customer service, we need to handle deleting the customer. This is done on an after.remove hook. This method is relatively straightforward since for removal just the id is required.
Thus the hooks for the stripeCustomer can be summarised as follows.
This concludes the customers part. Now we can move on to some more exciting details, which are the stripeEvents!
Handling Stripe Events
As mentioned at the beginning Stripe Events are how Stripe send information to your app. The model for this service is pretty simple.
We only store a generated id for this event, making sure that we don’t process the event more than once. This service has only one hook on after.create. There we create an Agenda job, which is a lightweight job scheduling library. Using a job scheduler allows you to quickly respond to the webhook and leave the event’s processing to some later time when the app has some free resources.
We define the agenda jobs as follows.
Here for each event, you define a processor. Here we will look at the most basic three processors that you will need to get yourself going. Let’s define an events/index.js which contains a mapping from stripe events to the processor methods.
These processors manage three types of events. The success of a payment, updating a customers subscription and deleting a customers subscription. When such an event is sent to you from Stripe, Agenda will create a job with the corresponding processor, and it will be queued for later. Let’s now look at the payment succeeded processor.
The function above first verifies that all the necessary data is provided if everything is ok. The user’s accessExpiryDate is extended to a later period. If the user fails to pay, the accessExpiryDate is not updated and thus the access is revoked. The app can similarly handle the remaining events.
This concludes the process of setting up payments using Stripe.js in Feathers.js. We have explored the Stripe API’s key concepts and looked into how they can integrate into the Feathers.js framework. Using this approach, it is straightforward to allow automated payments in your app, allowing you to scale faster! Be witty and for the payment service use the best Feathers service for Stripe!