Skip to content
Last updated

Billing & Ledger Service

Key idea:
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.


What Billing & Ledger is (and is not)

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)

Core domain concepts

Quick reference table

ConceptWhat it isWhy it mattersKey IDs you’ll use
Billable EntityWho the service was rendered to (e.g., a participant, student, dependent, member)Most charges are tied to the billable entity for traceability and allocation validationbillableEntityId (from Profile Service)
AccountWho is financially responsible (e.g., household, agency, sponsor)Allocations split or route responsibility across one or more accountsaccountId (from Profile Service)
RateA pricing instruction for a debit or discountDefines “what it costs” (or “how much to discount”)rateId
Rate CardUI/catalog grouping of ratesHelps humans and UIs find rates quickly; not used directly by charge calculationsrateCardId
Allocation ConfigurationA set of ordered rules describing responsibility distributionControls splits, caps, transfers, and write-offs at settlementallocationConfigurationId
SubscriptionBilling intent for a billable entity or accountTies together rate + discounts + allocation + billing frequency & anchorsubscriptionId
ChargeAn invoice-ready billing instructionStores inputs and version snapshots; mutable until invoicedchargeId
Settled ChargeImmutable, resolved version of a chargeStores resolved amounts and splits after invoicing/settlementsettledChargeId

Billable entity vs account (required mental model)

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 accountId when 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.)


How the pieces fit together

This diagram is intentionally “conceptual” (client-facing). The actual storage model includes audit history and settlement tables.

Configuration (versioned)
Rate
Debit or Discount
Allocation Configuration
Ordered rules
Subscription
Intent + schedule + references
Rate Card
Catalog grouping (UI)
Charge lifecycle
Charge
Mutable pre-invoice
Stores instructions + version snapshots
Settled Charge
Immutable post-invoice/settlement
Stores resolved amounts + splits
Profile references
Billable Entity (Profile)
Account (Profile)
Allocation validation may require that the billable entity is associated to the accounts in the allocation.

Rates

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.

Rate behaviors

  • 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.

Rate cards

A Rate Card is a catalog grouping of rates for UI discovery and organization.

Important: You cannot “charge a rate card.” Charges require explicit rateId (and optionally discountRateIds and an allocationConfigurationId). Rate cards exist to help humans/UIs choose those values.

Discounts

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 and rules

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.


Subscriptions

A Subscription represents billing intent, not execution.

Subscriptions define:

  • who is being billed (billableEntityId or accountId)
  • 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)
Common misconception: Creating a subscription does not automatically enroll someone into recurring billing. A subscription expresses intent. Recurring billing is executed by an orchestrator (often the Recurring Billing service) that creates charges on a schedule.

Charges (mutable instructions)

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

Single vs combined vs standalone discount

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)

Why charges store instructions (not resolved amounts)

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 and mutability

Billing cycles determine when charges are finalized.

Key behavior:

  • Charges remain mutable during the billing window (for example: PENDING or BILLED)
  • 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).


Versioning (how pricing stays audit-safe)

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.

Tagging

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.