Skip to main content

Overview

Invoices are billing documents that detail charges for a customer over a specific period. FlexPrice generates invoices automatically for subscriptions, or manually for one-time charges. Invoices progress through states from draft to finalized to paid.

Invoice Structure

A complete invoice contains comprehensive billing information:
{
  "id": "inv_abc123",
  "invoice_number": "INV-2024-001",
  "customer_id": "cus_xyz789",
  "subscription_id": "sub_premium",
  "invoice_type": "subscription",
  "invoice_status": "open",
  "payment_status": "pending",
  "currency": "usd",
  "subtotal": "1000.00",
  "total_tax": "80.00",
  "total_discount": "100.00",
  "total_prepaid_credits_applied": "50.00",
  "total": "930.00",
  "amount_due": "930.00",
  "amount_paid": "0.00",
  "amount_remaining": "930.00",
  "adjustment_amount": "0.00",
  "refunded_amount": "0.00",
  "period_start": "2024-03-01T00:00:00Z",
  "period_end": "2024-04-01T00:00:00Z",
  "billing_period": "month",
  "billing_sequence": 3,
  "billing_reason": "subscription_cycle",
  "due_date": "2024-04-15T00:00:00Z",
  "finalized_at": "2024-03-01T00:00:00Z",
  "invoice_pdf_url": "https://api.flexprice.io/invoices/inv_abc123/pdf",
  "version": 1,
  "metadata": {
    "po_number": "PO-2024-Q1-001"
  }
}

Invoice Types

FlexPrice supports multiple invoice types:
Recurring invoices generated automatically based on subscription billing cycles.
{
  "invoice_type": "subscription",
  "subscription_id": "sub_premium",
  "billing_sequence": 3,
  "billing_reason": "subscription_cycle"
}

Invoice Status

Invoices progress through several states:
1

Draft

Invoice is being prepared but not yet finalized. Line items can still be added or modified.
{ "invoice_status": "draft" }
2

Open

Invoice has been finalized and is awaiting payment. No further modifications allowed.
{
  "invoice_status": "open",
  "finalized_at": "2024-03-01T00:00:00Z"
}
3

Paid

Invoice has been fully paid.
{
  "invoice_status": "paid",
  "payment_status": "paid",
  "paid_at": "2024-03-05T14:30:00Z"
}
4

Void

Invoice has been voided and is no longer valid.
{
  "invoice_status": "voided",
  "voided_at": "2024-03-02T09:15:00Z"
}

Payment Status

Separate from invoice status, payment status tracks the payment state:
  • pending: Payment has not been attempted or is in progress
  • paid: Invoice is fully paid
  • partial: Invoice is partially paid
  • failed: Payment attempt failed
  • overpaid: Payment exceeds amount due (creates customer credit)
When payment_status is overpaid, the amount_remaining must be zero, and excess funds are typically applied as customer credits for future invoices.

Line Items

Invoice line items detail individual charges:
{
  "line_items": [
    {
      "id": "ili_seat_charge",
      "invoice_id": "inv_abc123",
      "customer_id": "cus_xyz789",
      "subscription_id": "sub_premium",
      "entity_type": "price",
      "entity_id": "price_seat_monthly",
      "price_id": "price_seat_monthly",
      "price_type": "per_unit",
      "display_name": "Premium Seats",
      "plan_display_name": "Premium Plan",
      "quantity": "10",
      "price_unit": "seat",
      "price_unit_amount": "50.00",
      "amount": "500.00",
      "currency": "usd",
      "period_start": "2024-03-01T00:00:00Z",
      "period_end": "2024-04-01T00:00:00Z",
      "prepaid_credits_applied": "0.00",
      "line_item_discount": "50.00",
      "invoice_level_discount": "0.00",
      "metadata": {
        "department": "engineering"
      }
    },
    {
      "id": "ili_usage",
      "invoice_id": "inv_abc123",
      "price_type": "usage",
      "meter_id": "meter_api_calls",
      "meter_display_name": "API Calls",
      "display_name": "API Usage",
      "quantity": "150000",
      "price_unit": "call",
      "price_unit_amount": "0.002",
      "amount": "300.00",
      "currency": "usd",
      "commitment_info": {
        "commitment_amount": "10000.00",
        "consumed_amount": "8500.00",
        "overage_amount": "0.00",
        "is_overage": false
      }
    }
  ]
}

Line Item Discounts

Line items can have multiple types of discounts:
Discount applied directly to this specific line item (e.g., from a price-specific coupon).
{
  "amount": "500.00",
  "line_item_discount": "50.00"
}

Billing Periods

Subscription invoices cover specific billing periods:
{
  "period_start": "2024-03-01T00:00:00Z",
  "period_end": "2024-04-01T00:00:00Z",
  "billing_period": "month",
  "billing_sequence": 3
}
  • period_start / period_end: Exact date range covered by this invoice
  • billing_period: The subscription’s billing period type
  • billing_sequence: Sequential number (3rd invoice for this subscription)

Billing Reasons

The billing_reason field explains why the invoice was generated:
  • subscription_cycle: Regular subscription billing cycle
  • subscription_create: Initial subscription invoice
  • subscription_update: Mid-cycle subscription change
  • subscription_threshold: Usage threshold reached
  • manual: Manually created invoice
  • proration: Proration charges from subscription changes

Invoice Amount Calculations

Invoice amounts follow a specific calculation flow:
1

Subtotal

Sum of all line item amounts before discounts, taxes, or credits.
subtotal = sum(line_items.amount)
2

Apply Discounts

Subtract coupon discounts (line-level and invoice-level).
after_discount = subtotal - total_discount
3

Apply Taxes

Add calculated taxes based on customer location and tax rules.
after_tax = after_discount + total_tax
4

Apply Prepaid Credits

Subtract prepaid credits from customer wallet.
amount_due = after_tax - total_prepaid_credits_applied
5

Final Total

The total represents the complete invoice amount.
total = subtotal + total_tax - total_discount
amount_due = total - total_prepaid_credits_applied

Invoice Numbers

Each invoice gets a unique, human-readable number:
{
  "invoice_number": "INV-2024-001",
  "billing_sequence": 1
}
  • invoice_number: Unique identifier per tenant, formatted for customer display
  • billing_sequence: Sequential counter for subscription invoices
Invoice numbers are guaranteed unique per tenant and environment using database constraints.

Idempotency

Invoice creation supports idempotency to prevent duplicates:
{
  "idempotency_key": "sub_abc123_period_2024-03"
}
Using the same idempotency key for multiple invoice creation requests returns the existing invoice instead of creating duplicates.

Commitment Tracking

For subscriptions with commitments, line items include commitment information:
{
  "commitment_info": {
    "commitment_amount": "10000.00",
    "consumed_amount": "8500.00",
    "remaining_amount": "1500.00",
    "overage_amount": "0.00",
    "is_overage": false,
    "overage_factor": "1.5"
  }
}
This tracks:
  • Progress toward commitment
  • Overage charges when commitment is exceeded
  • Applied overage pricing factors

Adjustments and Refunds

Invoices track adjustments and refunds through credit notes:
{
  "amount_due": "1000.00",
  "amount_paid": "1000.00",
  "adjustment_amount": "50.00",
  "refunded_amount": "100.00",
  "amount_remaining": "0.00"
}
  • adjustment_amount: Non-cash reductions (goodwill credits, billing corrections)
  • refunded_amount: Actual cash refunds issued to customer
Adjustments and refunds are applied through credit notes, not by directly modifying invoices. This maintains audit trails and accounting integrity.

Due Dates

Invoices have configurable due dates based on payment terms:
{
  "finalized_at": "2024-03-01T00:00:00Z",
  "due_date": "2024-03-31T00:00:00Z",
  "payment_terms": "30_NET"
}
Due date is calculated from the invoice finalization date plus the payment terms period.

PDF Generation

Finalized invoices can be exported as PDFs:
{
  "invoice_pdf_url": "https://api.flexprice.io/invoices/inv_abc123/pdf"
}
PDF URLs are typically signed and time-limited for security.

Invoice Validation

Invoices undergo validation before finalization:
1

Amount Consistency

  • amount_due must be non-negative
  • amount_paid must be non-negative
  • amount_paid + amount_remaining = amount_due (unless overpaid)
2

Period Validation

  • period_end must be after period_start
  • Subscription invoices must have billing_period set
3

Line Item Currency

All line items must use the same currency as the invoice.
4

Overpayment Rules

When payment_status is overpaid, amount_remaining must be zero.

Metadata

Invoices support custom metadata for integration and tracking:
{
  "metadata": {
    "po_number": "PO-2024-Q1-001",
    "department": "engineering",
    "cost_center": "CC-ENG-001",
    "contract_id": "CONTRACT-2024-001"
  }
}
Metadata is indexed and searchable, making it useful for:
  • Purchase order tracking
  • Department allocation
  • Contract references
  • Custom reporting dimensions

Version Control

Invoices use versioning for safe concurrent operations:
{
  "version": 2
}
The version increments with each modification, preventing race conditions in distributed systems.