Running a successful online business involves a myriad of processes and one such critical process is handling invoices. Whether you're selling products, services, or subscriptions, timely and accurate invoicing is essential to maintain a healthy cash flow. However, manual invoicing can be tedious, time-consuming, and prone to errors.
In this blog post, we will guide you through automating the process of generating and emailing invoices with Laravel, specifically using the Laravel Cashier package. By the end of this post, you'll be able to automatically generate professional-looking invoices, customized to your needs, and have them automatically emailed to your customers.
Prerequisites
Before we dive into the main content, it's important to ensure you have the following prerequisites in place.
- Laravel Setup: You should have a Laravel application up and running. Laravel is a powerful PHP framework that simplifies the process of building complex web applications. Learn how to get started with Laravel.
- Laravel Cashier: Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services. It handles almost all of the boilerplate subscription billing code you are dreading writing. You should have it installed and configured with your Stripe account. Learn how to set up Cashier.
- Subscriptions: You should have your subscription models set up in Laravel. If you haven't done that, you can refer to our previous guide on How to set up recurring payments in Laravel which will guide you step-by-step on setting up subscriptions using Laravel and Cashier.
- Email Providers: Lastly, you should have access to an email provider for sending emails. In this guide, we will discuss some common email providers such as Mailgun and Sendgrid, which offer free tiers for small businesses or startups.
Once you have these prerequisites in place, you are ready to automate the process of invoice generation and emailing in your Laravel application. Let's begin.
Previewing the invoice
This will only be used for us to test and to see what the final invoice looks like as a PDF. It is a great way to quickly iterate and make changes to the invoice before we start automating the process.
Create a new subscription
This article assumes you have already have a subscription for your user. If not, here's a quick reminder of how you would do that. After setting up Laravel Cashier, creating a new subscription for a user is quite straightforward. Here is an example:
$user = User::find(1);
$user->newSubscription('default', 'plan_premium')->create($creditCardToken);
In the above example, we find the user and create a new subscription for them. The 'default'
in the newSubscription
function is the name of the subscription, and 'plan_premium'
is the specific Stripe plan's ID to which the user is subscribing. The $creditCardToken
variable is obtained from your payment processor, such as Stripe, and represents the customer's payment details. Read more about setting up subscriptions for users here.
Preview the invoice
Now that we've created a subscription, we can generate an invoice for it. We'll create an HTTP route that fetches the first invoice and downloads it as a PDF.
In order to generate invoice PDFs, we first need to install a dompdf
dependency:
composer require dompdf/dompdf
Then, open your web.php
file located at routes/web.php
and add the following route:
In the above route, we're getting the authenticated user, fetching their first invoice, and using the download
method to generate and download the invoice as a PDF.
You can now preview the invoice by navigating to http://localhost/invoice/preview
in your browser. It will download the file to your computer.
You should now see a generated PDF of a subscription invoice. In the next section, we'll delve into how you can automate the process of emailing them to your users.
Automating emailing of invoices
Having set up and customized our invoices, the next step is to automate the process of sending these invoices via email to our users. We can tap into webhooks to automatically react to new invoices and send them to your customers via email whenever they are created.
Setting up email provider
To get started, you will need to set up your email provider. Laravel supports a range of mail drivers, including SMTP, Mailgun, Postmark, Amazon SES, and Sendgrid. These providers all offer free tiers, with Mailgun offering 5,000 free emails per month for three months, and Sendgrid offering a 30-day trial with up to 40,000 free emails.
First, sign up with your preferred email provider. They might have a "sandbox" mode as well where you can safely test sending real emails to your own address.
Once you get the email provider details, you can set up your chosen mail driver for Laravel in your .env
file:
Creating the invoice mailable
Let's first create the InvoiceFinalized
mailable which we could send to the user:
Notice this mailable takes a Laravel\Cashier\Invoice
instance, which we'll get to later. The mailable sets the subject, content in Markdown (we'll describe it in the next section), and also attaches the invoice as a PDF for convenience.
Customizing the invoice email contents
For this example, we'll write the content of the email in Markdown, because of how simple it is and allows us to avoid writing a lot of the HTML boilerplate.
Let's create the file resources/views/emails/invoices/finalized.blade.php
If you'd like to learn more about using Markdown for your emails, or ways to customise the final generated emails, you can read more about it in the Laravel Documentation on Markdown mailables.
Reacting to the invoice webhook
When a new invoice is created in Stripe, either automatically or manually using Laravel Cashier, Stripe will send a webhook with the details of the invoice.
To automatically email customers when a new invoice has been created, you need to set up a webhook listener for the invoice.finalized
Stripe event. Let's first create the StripeEventListener
class:
Register Stripe event listener
Let's now register the above listener to make sure handle the invoice finalized event:
Now whenever a new invoice is created in Stripe due to a subscription renewal or other reason, your app gets notified about it and the InvoiceFinalized
mail gets sent. Good job!
Test the implementation
In order to make sure we got everything right, let's test it. Listening for Stripe webhooks on your localhost is fairly easy, so let's set it up.
- Download the Stripe CLI tool
- Login to Stripe using the CLI tool -
stripe login
- Listen to Stripe webhooks using the CLI tool -
stripe listen --forward-to your-app.test/stripe/webhook
- You will see a "webhook signing secret", which starts with
whsec_
. Copy it, and add it to your.env
variables like so -STRIPE_WEBHOOK_SECRET=whsec_....
- Trigger a new subscription or a renewal. Go to your app and subscribe a new user, which will trigger the invoice creation. If you followed previous articles, that will be your
/subscribe
route.
After subscribing, you should see a few Stripe events in your terminal which is forwarding events to your local app. One of them will be the invoice.finalized
, and after it runs - you can check your logs or email to make sure the email has been sent and received.
Tip: when developing locally, set your MAIL_MAILER=log
and use a tool like Log Viewer for Laravel to preview these emails without having to set up any third-party mail service. Otherwise, use a tool like Mailtrap to send fake emails - great for testing.
Conclusion and next steps
Congratulations! You have now automated invoice generation and emailing with Laravel using the Laravel Cashier package. You've learned how to create subscriptions, preview invoices, customize them to your needs, and set up automatic emailing whenever a new invoice is created.
Remember to test the entire invoicing and email process thoroughly before rolling out to your users. You can utilize Stripe's and your email provider's sandbox environments for this purpose.
Also, remember to monitor the process regularly once it's live, ensuring that all invoices are generated correctly and emails are being delivered as expected.
Finally, keep exploring what Laravel Cashier can offer. You can customize it further to suit your needs and make the payment process smoother for your customers. It has functionalities for handling coupons, swapping subscriptions, subscription quantities, and even handling failed payments.
By fully utilizing Laravel Cashier, you can focus on growing your business, confident that your billing system is robust, professional, and customer-friendly. Happy coding!