FREELessons: 9Length: 50 minutes

Next lesson playing in 5 seconds

  • Overview
  • Transcript

3.4 Generating Invoices

Now that we can bill users, we need to be able to generate invoices. In this lesson, I'll show you some methods for displaying and downloading a user's invoices, directly from our application.

3.4 Generating Invoices

In the previous lesson we took a good look at managing subscriptions. In this lesson we're going to look at retrieving invoices for a user as well as allowing them to download their invoices as PDFs. It's actually quite a simple process. Let's create a new route to show invoices for a user. We'll just route it to the invoices URI, and in the route we'll set a variable called invoices to off user invoices. If you'd like to get the users upcoming invoice, then you can use the upcoming invoice method. This will return a single invoice instance, right so now let's just return a view called invoices and we'll pass along this invoices variable as the data. Now let's go ahead and create a new file in resources view called invoices.blade.php. So we're going to need a table to display the users' invoices. We'll have a table with a t head, a new row, and we'll have four headings. Alongside the t head we'll also have a t body. Pretty standard stuff. Inside the headings we'll have date, amount, view, and download. Inside the body, it will open up a new four h, and will loop over all of the invoices. Then we'll want to open up a new row with four columns. So each invoice will actually be an instance of Laravel Cashier Invoice. If we take a look at this class, there's a whole bunch of handy methods that we can use to display various pieces of information about our invoice. The first thing we want is the date. About half way down, we actually have two methods relating to the date. We have the regular date method which also lets us pass in a time zone to have it adjusted. This method will then return a carbon instance which we can use to manipulate however we want. Or we can use the date string method, which returns a string-based date, ready to display. Let's go with that. In our table, we'll simply display the date string. Next up is the amount. Back in the invoice class we actually have several methods available. At the very top, we have dollars, which is an alias for the total with the currency method. So this will display the total amount with the currency symbol prefixed. We can also configure the currency symbol, we just need to add an addCurrencySymbol method to our user model and return the symbol prefixed onto the amount. Our invoice class also has a total method which gets the total without the currency symbol prefixed. And we also have a subtotal method which we will be the total before discounts are applied. We're going to use the dollars method though. So back in our view let's display the dollars in our second column. Finally we have our view and download columns. These are both going to be hyperlinks. The first will be a link to invoice/invoice id, we set the anchor text to view. The second link would be similar, except it'll end with slash download. And the anchor text will be download. All right, it's time to admire our handiwork. In our browser, lets navigate to the slash invoices URL. And we'll be presented with a beautiful table showing our invoices. As expected we have our first invoice totaling $9.99 cents, and because we have swapped our plan, we have our second invoice totaling $0.00. Right, so far so good, now to view our invoices. First let's set up a route so that we can fetch the invoice and display it. We'll have a route get with a URL of invoice slash id wrapped in curly braces. Then our closure which will accept a single parameter of id. Now to fetch the invoice we'll go through off user again. Except this time we'll call the find invoice or fail method. And we'll give it our invoice's id. There is also a findInvoice method, which will return an invoice, or null if one cannot be found. I like to use the Or Fail variant because it throws a not found HTTP exception. Normally, you'd have a listener set up for that exception, so that you can handle it appropriately. We'll just leave it as it is for now. So once we have our invoice, we're simply going to return invoice view, and we'll pass it an array, where we need a vender key, which we'll set to My Cool Store, and we'll also need a product key, which we'll set to Subscription. And that's it. If we now try to view our first invoice, we'll then be presented with a fairly basic invoice, which shows us some data related to the invoice, as well as the line items for the invoice. Now this view is pretty basic, but it's completely customizable. Let me quickly show you how I can modify this view so it looks exactly how you want. First we'll switch to our terminal and we'll run PHP artisan, vendor publish. With the provider option and we want to publish the Laravell cashier, cashier service provider. Once the command has run, the view itself will have been published to our resources/views folder. If we navigate further inside the vendor/cashier folder, we'll now have a receipt.blade.php view. We can now make any changes we need to this view, and it will be used when returning the invoices view from our route. But enough on that. Let's take a look at downloading an invoice as a PDF. There's a bit of magic that goes on here to make this happen which I'll explain shortly. First, though, let's create the route to download the invoice. We'll just duplicate every route and simply adjust the URI so it has the download on the end. Then instead of calling the view method, we'll call the download method with the exact same parameter. Now, in our browser, let's go back to our invoices and we'll try to download our first invoice. So we're presented with our download window, and we'll just save it to the desktop. Once it's downloaded, let's open it up. And as we can see, the invoice looks much like it did when we viewed it in the browser. Awesome. There's a few things that happened here. First, Cashier takes the view from before and renders the invoice using that view, then saves it in temporary storage as a .pdf. At this stage, the file is still actually an HTML document. Then, this is where some magic happens. Cashier uses phantomjs to capture a screenshot of that HTML document and save it as an actual PDF file. It then grabs the contents of the PDF and creates an HTTP response, deletes the original PDF, and then returns the response that was created. And so that pretty much covers invoices. There's a lot more you can do, but I'll leave that up to you. Make sure you have a good look through the Laravell cashier invoice class to see what else you can do with your invoices.

Back to the top