Adding Stripe Checkout and Customer Portal to your Laravel application

Published under Laravel.

📺  Click here to skip to the video attached to this post  👇

Here's a quick overview of how you can add Stripe Checkout and Stripe Customer Portal to your Laravel application via Laravel Cashier.

This guide assumes you have a Stripe dev account setup and access to your Stripe Key and Secret. You should also have your products and pricing configure in Stripe. You will need at least one Price ID.

Resources

Considerations

First, you need to figure out which entity in your application will be considered the billable entity. For example, if you have an application with teams where each team signs up and pays for a number of seats, then your Team model will be your billable entity. However, if your application has users which sign up and pay for themselves, then your User model will be your billable entity.

Environment variables

We need to setup some environment variables for Laravel Cashier to pass along to stripe. You only need to set CASHIER_MODEL if your billable model is not App\Models\User.

Package installation

As of Feb 9, 2020, the released version of Laravel Cashier supports Stripe checkout. You can install Laravel Cashier with:

On the frontend, we will be using the Stripe JS SDK, so make sure to include that on your page somewhere:

Migrations

I recommend publishing Cashier's migrations into your local migrations directory, so that you have full control over them:

If your billable model is not User, make sure to change the table in the CreateCustomerColumns migration we just published to the table that corresponds to your billable model.

I also had to change the CreateSubscriptionsTable migration to reference my billable entity's table:

Since we published Cashier's migrations, we should also tell Cashier not to run its default migrations. Add this to your AppServiceProvider.register method:

Model setup

Next, we need to configure our billable model. In my case, the billable model is Team. Add the Billable trait to your model:

Redirect to subscription page

If your user is logged in but doesn't have an active subscription, we need to redirect them to a page asking them to subscribe. The following examples will be specific to Inertia, but the concepts can be used on any Laravel stack.

Middleware

We're going to add a middleware which we will use to confirm the user has an active subscription. You can pass the name of the subscription into subscribed().

We then need to add the new middleware to our HTTP Kernel:

Controller

Create the controller which will start a new Stripe Checkout session, and then return the Checkout Session ID to the UI.

You'll notice in the above example that I am referencing config('stripe.price_id'). This comes from the Stripe Dashboard where you configure your products and pricing. I'll leave it up to you to figure out how you want to determine this value. Most people store their plans/pricing in a Laravel config file and then pull them from there based on what the user selected from your UI.

Don't forget to add the route for the above controller:

Note that the name of the route above matches the name of the route we are redirecting to in the BillingMiddleware.

Inertia View

Here's my full Inertia (Vue) component to render the subscription page. This probably won't be copy/pastable, but hopefully it can guide you in the right direction.

The key to the above component is the checkout method which we call via a button (user input). The checkout method is called with our public Stripe Key (passed from the backend), and the sessionId which is the Stripe Checkout Session ID (also passed from the backend).

From here, Laravel Cashier will take care of updating your database tables with the accurate subscription info, all via webhooks. You will need to make sure you've configured webhooks on the Stripe Dashboard though. The endpoint that Laravel Cashier automatically registers is: /stripe/webhook.

Billing portal endpoint

The Billing Portal is the easiest part of this whole process. All you need to do is register a new endpoint which redirects to the billing portal.

And then define the route:

And then link to that new route from wherever you want in your application. In my Jetstream application, I've added it to the dropdown menu:

Summary

There are a bunch of steps involved, but mostly its following the Laravel Cashier documentation. You can check out the Laravel docs repo on GitHub to see the documentation changes made for the Billing Portal: https://github.com/laravel/docs/compare/stripe-checkout...master


Thanks for reading!

Did you find this post useful? Let me know on Twitter! If you found an issue with the content, submit a pull request!

Subscribe to my newsletter to know when I publish more content in the future.

❤️ Likes: 0
📣 Retweets: 0
💬 Replies: 0
🙊 Mentions: 2