# How to create invoices in Bubble

- Tool: Bubble
- Difficulty: Beginner
- Time required: 25-30 min
- Compatibility: All Bubble plans
- Last updated: March 2026

## TL;DR

Creating invoices in Bubble involves building an invoice form with line items, automatic tax and total calculation, due date management, and status tracking for paid and overdue invoices. This tutorial covers the complete invoice creation workflow from data structure through PDF generation and email delivery.

## Overview: Creating Invoices in Bubble

This tutorial walks through building a manual invoice creation system in Bubble. You will create an invoice form with dynamic line items, automatic calculations for subtotals and tax, due date tracking, and status management for paid and overdue invoices. Perfect for freelancers, agencies, and small businesses who need to bill clients directly from their Bubble app.

## Before you start

- A Bubble account with an app
- A Client or Customer Data Type already set up
- Basic understanding of Bubble Data Types and workflows
- Familiarity with Repeating Groups for dynamic lists

## Step-by-step guide

### 1. Create the Invoice and Line Item Data Types

In the Data tab, create an Invoice Data Type with fields: invoice_number (text — auto-generated unique identifier), client (your Client/Customer Data Type), issue_date (date), due_date (date), status (text — draft/sent/paid/overdue), subtotal (number), tax_rate (number — percentage), tax_amount (number), total (number), notes (text), and created_by (User). Create a Line_Item Data Type with: invoice (Invoice), description (text), quantity (number), unit_price (number), and line_total (number). The line_total is calculated as quantity times unit_price.

**Expected result:** Invoice and Line_Item Data Types created with all fields for invoicing.

### 2. Build the invoice creation form with dynamic line items

Create a 'create-invoice' page. Add a form Group with: a Dropdown for client selection (data source: Search for Clients), a Date Picker for issue_date (default: today), a Date Picker for due_date (default: 30 days from today), and an Input for notes. Below the header, add a Repeating Group of type Line_Item for the line items section. Since we are creating items dynamically, use a custom state on the page called temp_items (list of texts — each text is a JSON-like string for description, qty, price). Add an 'Add Line Item' button that appends a new empty row. Each row has inputs for description, quantity, and unit_price.

> Pro tip: Use a simpler approach: create Line_Item records as 'draft' items linked to a temporary invoice, then finalize when the user saves.

**Expected result:** An invoice form with client selection, dates, and a dynamic list of line items that can be added and removed.

### 3. Implement automatic calculations for totals

For each line item row, calculate the line_total dynamically: set a Text element to display quantity input's value times unit_price input's value. For the invoice totals section, display: Subtotal = sum of all line totals (use the Repeating Group's list of line totals :sum), Tax = Subtotal times tax_rate / 100, and Total = Subtotal + Tax. Add a tax_rate Input (default 0 for no tax). These calculations update in real time as the user enters values. When the user clicks Save, create the Invoice record and all Line_Item records with the calculated values.

**Expected result:** Subtotal, tax, and total calculations update automatically as the user adds or modifies line items.

### 4. Create the Save and Send Invoice workflow

Add a 'Save as Draft' button and a 'Send Invoice' button. Save as Draft: create the Invoice record with status 'draft', then create Line_Item records for each row. Send Invoice: same creation logic but set status to 'sent', plus send an email to the client with the invoice details (invoice number, line items, total, due date, and a link to view the invoice online). Generate a unique invoice_number using a format like 'INV-' followed by a sequential number or timestamp. After saving, navigate to the invoice detail page.

**Expected result:** Invoices can be saved as drafts or sent directly to clients via email with all details included.

### 5. Build the invoice detail page with status management

Create an 'invoice' page (type: Invoice) displaying all invoice details: client name, invoice number, dates, line items in a Repeating Group, subtotal, tax, and total. Add status management buttons: 'Mark as Paid' (changes status to 'paid'), 'Mark as Overdue' (changes status to 'overdue'), and 'Send Reminder' (re-sends the invoice email). Use conditional formatting to color-code the status badge: green for paid, yellow for sent, red for overdue, grey for draft. Add a backend workflow scheduled for the due_date that automatically changes status from 'sent' to 'overdue' if not yet paid.

**Expected result:** A complete invoice view with status badges and action buttons for managing invoice lifecycle.

### 6. Create an invoice list dashboard

Create an 'invoices' page with filter tabs: All, Draft, Sent, Overdue, Paid. Add a Repeating Group showing Invoices where created_by = Current User, filtered by the selected tab's status (use Ignore empty constraints for the All tab). Each row displays invoice number, client name, issue date, due date, total, and a color-coded status badge. Add summary statistics at the top: total outstanding (sum of sent + overdue invoice totals), total paid this month, and total overdue. This gives a financial overview at a glance.

**Expected result:** An invoice dashboard with filter tabs, summary statistics, and a complete list of all invoices.

## Complete code example

File: `Workflow summary`

```text
INVOICE SYSTEM SUMMARY
=======================

DATA TYPES:
  Invoice: invoice_number, client (Client), issue_date, due_date,
    status (draft/sent/paid/overdue), subtotal, tax_rate,
    tax_amount, total, notes, created_by (User)
  Line_Item: invoice, description, quantity, unit_price, line_total

INVOICE NUMBER FORMAT:
  'INV-' + year + '-' + sequential_number
  Example: INV-2026-0042

CALCULATIONS:
  line_total = quantity × unit_price
  subtotal = sum of all line_totals
  tax_amount = subtotal × (tax_rate / 100)
  total = subtotal + tax_amount

WORKFLOWS:
  Save as Draft:
    1. Create Invoice (status = 'draft')
    2. Create Line_Items for each row
    3. Navigate to invoice detail page

  Send Invoice:
    1. Create Invoice (status = 'sent')
    2. Create Line_Items
    3. Send email to client with details
    4. Schedule overdue check for due_date

  Mark as Paid:
    Make changes to Invoice → status = 'paid'

  Auto-Overdue (Backend, scheduled for due_date):
    Only when: status is 'sent'
    Make changes to Invoice → status = 'overdue'
    Send reminder email to client

DASHBOARD METRICS:
  Outstanding = sum(total) where status = sent OR overdue
  Paid this month = sum(total) where status = paid
    AND paid_date is in current month
  Overdue count = count where status = overdue
```

## Common mistakes

- **Not auto-generating unique invoice numbers** — Manual numbering leads to duplicates and gaps that cause accounting confusion Fix: Auto-generate invoice numbers using a consistent format like INV-YYYY-NNNN with a sequential counter
- **Forgetting to implement automatic overdue detection** — Without automation, overdue invoices sit in 'sent' status indefinitely and never get flagged Fix: Schedule a backend workflow for the due_date that changes status to 'overdue' if the invoice is not yet paid
- **Calculating totals on display only without saving to the database** — If calculations only exist in dynamic expressions, you cannot easily search, sort, or report on invoice totals Fix: Save calculated values (subtotal, tax_amount, total) to the Invoice record when creating or updating

## Best practices

- Auto-generate unique invoice numbers with a consistent format
- Save calculated totals to the database for reporting and filtering
- Schedule automatic overdue detection via backend workflows
- Send invoice emails with all details included — do not rely on links only
- Use conditional formatting to color-code invoice status badges
- Add summary statistics to the dashboard for quick financial overview

## Frequently asked questions

### Can I generate PDF invoices in Bubble?

Yes. Use a PDF generation plugin or external API service (like PDFShift or DocRaptor) that converts your invoice page HTML to a downloadable PDF file.

### How do I handle recurring invoices?

Create a Recurring_Invoice Data Type with client, items, frequency, and next_date fields. Schedule a backend workflow that creates a new Invoice from the template on each recurrence date.

### Can I accept payments directly from the invoice?

Yes. Add a 'Pay Now' button on the invoice view page that creates a Stripe Checkout session for the invoice total. On successful payment, update the status to 'paid'.

### How do I calculate tax for different rates?

Add a tax_rate field to the Invoice. For line-item-level tax, add a tax_rate field to Line_Item and calculate tax per item instead of on the subtotal.

### Can I customize the invoice design?

Yes. The invoice detail page is a regular Bubble page — style it with your brand colors, logo, and layout. For PDF output, the PDF service will render whatever your page looks like.

### Can RapidDev help build an invoicing system?

Yes. RapidDev can build complete invoicing systems with custom templates, recurring billing, payment integration, PDF generation, and financial reporting dashboards.

---

Source: https://www.rapidevelopers.com/bubble-tutorial/create-invoices-in-bubble
© RapidDev — https://www.rapidevelopers.com/bubble-tutorial/create-invoices-in-bubble
