Generating PDF invoices using Lago

Generating PDF invoices using Lago

At Lago, we believe all companies should have access to a purpose-built billing solution, whether they have a subscription-based, usage-based or hybrid pricing model.

However, a billing API is worthless without a strong invoice generation engine. Building such an engine is time-consuming as it requires you to address several topics:

  • What template do we use?
  • What information do we need to retrieve to update the different fields?
  • How can we generate PDFs at an affordable price?
  • How do we ensure scalability?
  • Where should we store the files?
  • Do we generate the PDFs when we generate the invoice objects or should we do it asynchronously?

Our design and front-end teams created the HTML template which was then implemented by our back-end engineers (#teamwork 💪). For the implementation, we chose to use the Gotenberg library, which allows us to manage resources efficiently and therefore reduce the risk of failure and our costs. PDF invoices are generated asynchronously and stored with Amazon S3.

Now that you have a good understanding of the setup, let’s see what Lago’s invoice generation engine is capable of!

Basic invoice information

First, our solution allows you to update your organization’s basic information. This information can be modified either via the user interface or API. Imagine that we want to add:

  • A global tax rate;
  • Our address;
  • Our contact email; and
  • Information in the footer.

Here’s the full payload of the request we need to send in this case:

The invoice footer can be used to display legal information at the end of each invoice. You can also modify the footer and organization information via the ‘Settings’ section of the app.

Subscription and usage

At the end of each billing period, Lago automatically calculates how much your customers owe you, depending on the events pushed by your back-end system and the charges defined in the plan model. By aggregating all the events and applying charges, you will be able to have a full breakdown of all the prices related to an invoice.

Lago then generates an invoice payload that includes all fees and can be sent to any third-party system (e.g. accounting tool, payment processor, tax processor, CRM). Therefore, companies that use tools like QuickBooks or NetSuite to generate PDF invoices can retrieve Lago’s invoice object and transmit this information to their external provider. Here’s an example of an invoice payload.

Subscription fee

The subscription defines the boundaries of the invoice (i.e. start date, associated plan and termination data, if any) and includes a recurring fixed fee (fee.type: subscription), which can be paid in advance or in arrears.

Usage-based fees

In addition to the recurring fixed fee related to the subscription, Lago calculates usage-based charges: fee.type: charge. If there are several usage-based components, they are listed one after the other. The total number of units consumed during the period and total amount, which depends on the charge model of each component (e.g. standard pricing, graduated pricing, package pricing), are included in the payload.

fee.amount_cents does not include taxes but this information is available in fee.vat_amount_cents.


The general tax rate set at organization level (see ‘Basic invoice information’ above) can be overwritten for each customer. If there’s a tax rate defined at customer level, it will be the only tax rate used when generating invoices.

Download an invoice

Receiving a payload every time a new invoice is generated is useful, especially when you can connect the webhook to any third-party service. But it’s even better if you can directly download a PDF invoice!

With Lago, you can download invoices via the user interface or API.

The PDF includes information about your organization, your customer and the amount of the invoice. The invoice summary is on the first page and the usage breakdown on the second page.

Uniqueness of an invoice

Lago ensures the uniqueness of an invoice at two levels:

  • The sequencial_id; and
  • The number.

The invoice.sequencial_id is an incremental value of the number of invoices generated by your company. This identifier covers all your customers, ensuring that your organization issues unique invoices.

The invoice.number is a unique invoice reference, including:

  • The first three letters of the organization name;
  • A random identifier; and
  • An identifier based on an incremental value.

Here’s an example based on the above payload: MY -95D5-001-002.

Updating an invoice status

There are three possible invoice statuses:

  • Pending (i.e. awaiting payment);
  • Failed (i.e. when the payment failed); and
  • Succeeded (i.e. when the payment was successful).

When an invoice is generated, its initial status is pending (i.e. awaiting payment).until you update the status. You can update the status of an invoice via the API, as illustrated below.

When using one of our native integrations, the cash collection process is triggered by Lago, which automatically retrieves the payment status from your payment service provider in real time.

We hope you'll find this feature useful. To learn more about Lago's new functionalities, check out our product updates or get in touch with our team.

Two hosting options, same benefits

Whether you choose the cloud version or decide to host the solution yourself, you will benefit from our powerful API and user-friendly interface.

Open source

The optimal solution for small projects.


The optimal solution for teams who want control and flexibility on cloud or self-hosted version.