Billing & Ledger stores pricing instructions (rates, discounts, allocations, subscriptions) and uses them to create charges that are mutable until invoiced/settled. When charges are invoiced or settled, they become immutable and are moved to
SettledCharges.
Billing & Ledger is the financial backbone of Nelnet Payment Services (NPS) billing platform. It defines pricing, models discounts and prorations, routes financial responsibility through allocation rules, and produces audit-safe records that downstream services (Invoices, Recurring Billing, Payment Widget, Remittance) can use to invoice, settle, and reconcile.
Billing & Ledger is responsible for:
- Rates (debits and discounts)
- Rate Cards (catalog grouping for UI discovery)
- Allocation configurations (how responsibility is distributed)
- Subscriptions (billing intent for a billable entity or account)
- Charges (invoice-ready billing instructions, mutable pre-invoice)
- Ledger posting primitives (journal entries and balances, as part of settlement flows)
Billing & Ledger is not responsible for:
- Rendering invoices (Invoices service)
- Orchestrating recurring execution (Recurring Billing service)
- Capturing payments (Payments API)
- Storing payment credentials (Tokenization + Profile)
- Acting as a merchant’s general ledger (it’s a sub-ledger and an instruction engine)
| Concept | What it is | Why it matters | Key IDs you’ll use |
|---|---|---|---|
| Billable Entity | Who the service was rendered to (e.g., a participant, student, dependent, member) | Most charges are tied to the billable entity for traceability and allocation validation | billableEntityId (from Profile Service) |
| Account | Who is financially responsible (e.g., household, agency, sponsor) | Allocations split or route responsibility across one or more accounts | accountId (from Profile Service) |
| Rate | A pricing instruction for a debit or discount | Defines “what it costs” (or “how much to discount”) | rateId |
| Rate Card | UI/catalog grouping of rates | Helps humans and UIs find rates quickly; not used directly by charge calculations | rateCardId |
| Allocation Configuration | A set of ordered rules describing responsibility distribution | Controls splits, caps, transfers, and write-offs at settlement | allocationConfigurationId |
| Subscription | Billing intent for a billable entity or account | Ties together rate + discounts + allocation + billing frequency & anchor | subscriptionId |
| Charge | An invoice-ready billing instruction | Stores inputs and version snapshots; mutable until invoiced | chargeId |
| Settled Charge | Immutable, resolved version of a charge | Stores resolved amounts and splits after invoicing/settlement | settledChargeId |
A Billable Entity represents who services were rendered to (e.g., a dependent receiving care, a student receiving instruction, a participant in a program).
An Account represents who is financially responsible.
A charge must target either:
- a
billableEntityId(most common), or - an
accountIdwhen you want to bill directly to an account (e.g., a registration fee that isn’t tied to a single service recipient).
These are mutually exclusive for a charge and for a subscription. (Subscriptions also support either billableEntityId or accountId.)
This diagram is intentionally “conceptual” (client-facing). The actual storage model includes audit history and settlement tables.
Debit or Discount
Ordered rules
Intent + schedule + references
Catalog grouping (UI)
Mutable pre-invoice
Stores instructions + version snapshots
Immutable post-invoice/settlement
Stores resolved amounts + splits
A Rate is a single pricing instruction. Rates can represent:
- Debits (what you charge), and
- Discounts (credits) using
type=DISCOUNT.
Rates do not store resolved outcomes—they store instructions. Charges reference rates and compute the derived fields from those instructions.
- Rates are versioned. Updating a rate creates a new version.
- Existing charges and subscriptions do not automatically change when a rate changes.
- You must explicitly update a charge or subscription if you want it to use a newer version later.
A Rate Card is a catalog grouping of rates for UI discovery and organization.
rateId (and optionally discountRateIds and an allocationConfigurationId). Rate cards exist to help humans/UIs choose those values.
Discounts are modeled as rates (type=DISCOUNT). A discount rate can be:
- percentage-based (e.g., 10% off), or
- fixed-amount (e.g., $25.00 off)
Discount rates are applied in order and can be combined with a debit rate, or exist as standalone credits.
Allocation configurations describe how financial responsibility is distributed for a charge. They contain an ordered list of rules that are evaluated deterministically and resolved at settlement time into ledger/journal lines.
Examples:
- Split 50/50 across two accounts.
- A sponsor pays the first $50, the responsible party pays the remainder.
- A cap is applied, and any remainder is written off.
Allocation configuration updates are versioned. Invoiced/settled charges keep their original allocation snapshot.
A Subscription represents billing intent, not execution.
Subscriptions define:
- who is being billed (
billableEntityIdoraccountId) - what to bill (rate + discounts)
- how responsibility is routed (allocation configuration)
- how often and when to bill (frequency + anchor day + timezone)
- optional validity window (
startDate/endDate)
A Charge is an invoice-ready billing instruction. It is mutable until it is invoiced/settled. Charges:
- store inputs and references (rate IDs, allocation IDs, discount IDs)
- snapshot versions of referenced configuration at creation time
- can be recalculated and updated while they are in mutable states
- become immutable when invoiced/settled and are moved to Settled Charges
A charge can represent:
- a single debit rate
- a debit rate + one or more discounts
- a standalone discount (credit)
- a prorated debit/discount (via proration factor)
Charges intentionally store the instruction set rather than a fully resolved “final amount” so that:
- charges can be edited during the billing window
- you can correct quantity/discount selections without rewriting ledger
- the system can deterministically resolve the final outcome at settlement time using the snapshotted versions
Billing cycles determine when charges are finalized.
Key behavior:
- Charges remain mutable during the billing window (for example:
PENDINGorBILLED) - Once a charge is invoiced/settled, it becomes immutable (
INVOICED)
The API enforces mutability rules (updates/deletes are allowed only for mutable statuses; invoiced charges return conflict errors).
Every charge snapshots the versions of the configuration used at charge creation time, including:
- rate version
- discount rate versions
- allocation configuration version
- subscription version (if applicable)
That means:
- Updating a rate, allocation, or subscription does not retroactively change existing charges.
- To apply new configuration, you must explicitly update the charge or create a new one.
Billing & Ledger supports tags on configuration and stores derived tags on downstream records. Tags originating from Profile entities are nested under profile (for example profile.billableEntity.*) while billing configuration tags are nested under billing.*.
See the Tagging section for details on nesting and consolidation rules.