Invoices
Invoice Creation Process
OpenMeter creates invoices by transforming gathering invoices into draft invoices based on billing profile configurations. During this process, several key pieces of data are cloned to ensure invoice immutability:
- The effective billing profile at the time of creation
- Customer information and metadata
- Usage-based pricing quantities
This cloning mechanism ensures that invoices remain immutable once created, preserving the integrity of billing records even if the underlying data changes. The immutability is critical for maintaining accurate financial records and audit trails.
While this cloning behavior ensures invoice immutability, any subsequent changes to workflow configurations or customer information must be made directly on the invoice if it is expected to affect the invoice. This includes modifications to customer names, billing workflows, and other invoice-specific details. This approach maintains data consistency.
Invoice contents
In addition to the cloned information, an invoice contains essential financial data including the Currency and comprehensive totals information.
The invoice totals comprise the following monetary values, with all totals automatically rounded according to the currency's precision:
Name | Contents |
---|---|
amount | The total amount of lines before discounts and taxes |
chargesTotal | The total amount of charges (minimum spend) before discounts and taxes |
discountsTotal | The total amount of discounts applied |
taxesInclusiveTotal | The total amount of taxes included in amount , chargesTotal |
taxesExclusiveTotal | The total amount of taxes on top of amount , chargesTotal |
taxesTotal | Sum of taxesInclusiveTotal and taxesExclusiveTotal |
total | The total amount after taxes and discounts charged to the customer |
Note: the lines use the same totals format using the same calculation methods.
For a detailed view on the invoice's data structure please consult the Invoice API reference.
Validation errors
Invoices include validation errors that indicate any issues encountered during state transitions in the invoice processing workflow.
Validation errors are classified into two severity levels:
warning
: Non-blocking issues that allow invoice processing to continuecritical
: Blocking issues that prevent the invoice from proceeding to the next state
When encountering critical validation errors, resolution requires either:
- Updating the invoice while in draft state
- Addressing issues in connected external systems
- Retrying the failed state transition after fixes are applied
Example validation issue:
Invoice line
Besides this data, the invoice also contains 0 or more lines. We allow empty invoices to signify that there's no outstanding liabilities against the customer.
On the invoice there can be two kinds of lines:
- Flat Fee: It represents a single line item
- Usage Based Line: Represents a collection of Flat fees based on the usage quantity (these flat fee lines are called detailed lines)
The .rateCard
property represents the intended billing configuration for each
line item, while properties outside of .rateCard
reflect the actual invoiced
values after all calculations and adjustments have been applied.
To illustrate:
- The
rateCard.discounts
field defines the discount policy (e.g. a 50% reduction from the base price) - The
discounts.amount
field contains the calculated monetary value of the applied discount
Flat fee line
Flat fee lines represent the most basic line item structure in the invoice. Each flat fee line consists of two primary components:
- A quantity, specified in
.rateCard.quantity
- A price amount, defined in
.rateCard.price.amount
The billing timing preference (In Advance or In Arrears) is determined by the
.rateCard.price.paymentTerm
field.
The following example demonstrates a typical flat fee line structure:
Key Fields:
- The
category
field indicates whether the line item represents a charge when set to "charge" - The
managedBy
field determines line item management:- When set to "subscription", the system automatically manages the line item and reflects subscription changes
- Manual edits change this to "manual", preventing future subscription changes from affecting the line item to preserve manual modifications
The status
field can have the following values:
valid
: The line item is ready to be invoiced in its current statedetailed
: The line item is a component of a Usage Based charge and should be included in billingsplit
: The line item serves as the parent entry for a Progressive Billing charge
Usage Based Lines
Usage Based Lines represent charges that are calculated based on actual usage measured by meters. These lines are fundamental to usage-based billing scenarios where customers are charged according to their consumption of specific services or resources.
Each Usage Based Line is associated with a meter defined by the feature reference, which tracks the actual usage data. The pricing structure for these charges is defined in the Rate Card, which specifies the unit price, any tiered pricing rules, volume discounts, and minimum or maximum charge constraints that should be applied to the measured usage.
A key feature of Usage Based Lines is their ability to contain multiple child
line items marked with status="detailed"
. These detailed lines provide a
comprehensive breakdown of the usage and associated charges. For instance, when
dealing with API usage billing, the detailed lines might represent usage across
different pricing tiers This granular breakdown is essential for transparency
and enables accurate reporting.
Detailed lines are immutable and cannot be modified through the invoice edit API. Any modifications to detailed lines must be performed by updating their parent usage-based line item. This immutability ensures data consistency and maintains the integrity of usage-based billing calculations.
The relationship between a parent Usage Based Line and its detailed lines follows strict rules for consistency. The parent line's totals (both the amount and total fields) must exactly match the sum of all its detailed child lines. This requirement serves multiple purposes: it ensures data consistency within the system, enables accurate synchronization with external billing systems that may not support hierarchical grouping, and guarantees proper calculation of invoice-level adjustments such as taxes.
When accessing these lines through the API or viewing them in the UI, users can see both the consolidated view in the parent line and expand to view the complete usage breakdown in the detailed lines.
The following example demonstrates a typical usage-based line structure: