BlogRuby on RailsSoftware Development

Integrating recurring payments with Stripe

By March 14, 2018 No Comments

When you’re working with online payments there’s little room for error, especially when your application has a large number of active users, which is certainly the case with our current project. We decided to use Stripe as a payment gateway, as it has proved it’s reputation many times and is thus, very developer friendly.  Recurring payments, such as subscriptions for example, can be a very useful feature and in this blog, I’m going to explain how to integrate  subscriptions with Stripe into your Rails application, as well as one way you can test them locally using ngork.

Stripe concepts

Before I demonstrate how to integrate the subscription system, let’s introduce the important Stripe concepts that we’ll be using. Namely, these are customers, products and subscriptions.  All of these are very well documented and you may learn more about them in Stripe’s API reference, but in a nutshell: The Plan object determines the currency, price and the billing cycle.

The Customer object allows you to bind payments to a certain user and track them and we can bind a Customer to a Plan via the Subscription object. In plain terms, the Customers subscribe to a plan. It is important to understand that Stripe Subscriptions and Charges are two different things. Charges are used to process single payments and may or may not be tied to a Product whereas Subscriptions, are used for charging fees on a scheduled basis (weekly, monthly etc.) and MUST be connected to a Plan. Also, it is noteworthy that subscriptions don’t have any information about how much the customer is going to pay, it simply represents the relationship between a Customer and a Plan.

To give this blog some context, let’s say we’re building an online learning platform, where users can register an access online courses. In addition, let’s say that basic course components, such as video lectures, are free for all users, but users that subscribe, gain access to more cool features.

First and foremost, we need to create the premium plans. This can be done in two ways, one being using the Stripe API, and the other, which I’m going to do in this example, is going to your Stripe account’s dashboard, select “Subscriptions” from the left hand menu, then “Products”, click the “New+” button and fill in the forms that will determine the pricing plan you want to use.

Basic examples

You’ll almost always want to store information regarding subscriptions in your database, so by  generating Subscription and Transaction models, we can keep track of all of the important things. Therefore, the Subscription belongs to the User and each time a Subscription payment is made, a corresponding Transaction record is created.

We’ll also generate a Subscriptions controller with, for now, two actions: new and create.

In the new action, we retrieve the plan object via Stripe API. The parameter that we used in the retrieve function, SubscriptionsToolkit::PREMIUM_PLAN_ID, is a string constant located inside the SubsciptionsToolkit module, and its value is the plan id, in our case ‘eschool-premium’.

Additionally, notice the SubcribeUserToPremium class, here we used the service object pattern and moved all the subscription logic into this class and therefore, made our controller slim and more readable, which we will discuss, later on.

The subscription form (the view for SubscriptionsController’s ‘new’ action)  looks like this. As ugly and basic as it gets, it will serve its purpose for this demonstration.

Let’s get back to our service object, the inside of our SubscribeUserToPremium looks like this:

Moving this logic to a ServiceObject, also enables us to reuse in places other than our SubscriptionsController, such as an API endpoint that can be used by mobile apps.

ServiceResponse is a very basic class, that helps with the neat implementation of the SO pattern.

And there you have it, it’s as simple as that. The code I’ve shown so far, will enable subscriptions to be created on Stripe, but earlier, I said that you’d almost always want to keep important information in your database. How can we do that?

That’s where we come to Stripe webhooks. Whenever an event (such as new subscription created, new subscription payment made, subscription canceled etc.) occurs, Stripe can notify a specific endpoint  that we can configure. Let’s create a new controller and an endpoint for this purpose.

Rails g controller StripeWebhook

Add this to our routes.rb

And the controller itself looks like this:

As you can see, we first parse the response that we get from Stripe, and after that, we handle it according to its type. You can see that we use several new service objects here. The CreateSubscriptionRecord and CreateTransactionRecords services to create a corresponding records in our database, the SendPaymetSucceeded and SendPaymentFailedMail services that invoke the Application mailer and notify our user of his transactions and the ActivateSubscription service that updates a particular SubscriptionRecord to active status. (We did this because in our implementation, when we first create the subscription record, we set it’s active status to false).

The endpoint has been configured, but we need to register it on Stripe now. Go to Stripe Dashboard -> Webhooks -> +Add Endpoint. Url to be called should be in the form of yourapplication_base_url/stripe . Also check ‘Select events to send’ and then check “customer.subscription.created”, “invoice.payment_succeeded” and “”invoice.payment_failed” because we need only those 3 in this example.

How to test subscriptions on localhost using ngrok

It is always important to do a local check before you commit something, but how can we test our localhost app if it’s supposed to communicate with Stripe? It’s simple. All we need is to expose the port on which our app is running locally so that Stripe can access it, and that’s where Ngrok comes in hand. Go to their website and dowload the .zip file. Extract the file and copy the ngrok executable to the root of your rails project and add it to the .gitignore file. Now, go to the terminal and navigate to the root of your application (where we’ve moved the ngrok executable to) and type this : ./ngrok http 3000

The output should look like this

Now that we’ve exposed our app, we will repeat the endpoint configuration step explained earlier and set the forwarding address (in this case > http://304b8be1.ngrok.io) as yourapplication_base_url.

So our endpoint in this case will be http://304b8be1.ngrok.io/stripe

Important: Each time you run .ngrok http 3000, a different forwarding address will be generated!

There you have it, now feel free to play around with this because that is the best way to learn how something works.

Now you are all set to go 🙂