Correctness guarantees

Metering & Billing keeps credit balances correct by booking every credit movement on an internal double-entry ledger. The public credit balance is not a mutable counter. It’s derived from ledger movements that are balanced, ordered, and preserved over time.

This matters for customers and operators because the same rules explain every balance change:

  • Grants add credits.
  • Charges consume credits.
  • Expiration removes unused credits.
  • Corrections add follow-up movements instead of changing the past.
  • Transaction history shows the customer-facing result of those movements.

Double-entry ledger

Every credit movement is backed by balanced ledger entries. When credits move into or out of a customer balance, Metering & Billing records the matching side of the movement in another account.

At a high level, the credit ledger contains customer accounts and business accounts:

flowchart LR
  subgraph Customer["Customer accounts"]
    FBO["Customer credit balance"]
    REC["Customer receivable"]
    ACC["Customer accrued"]
  end

  subgraph Business["Business accounts"]
    WASH["Settlement boundary"]
    EARN["Earnings"]
    BRK["Expiration / breakage"]
  end

  REC --> FBO
  FBO --> ACC
  ACC --> EARN
  FBO --> BRK
  WASH --> REC

The customer credit balance is the customer-facing account. Receivable and accrued accounts exist so Metering & Billing can represent payment state, consumed usage, and recognition separately. Business accounts represent the other side of settlement, earnings, and expiration.

Movements

A settled balance is calculated from committed credit movements. If a customer receives 100 credits and uses 30, the settled balance is 70.

+100 funded
 -30 consumed
----
  70 settled balance

Because the balance comes from movements, Metering & Billing can also answer point-in-time balance questions. A balance read before an expiration doesn’t include that expiration, while a balance read at or after the expiration does.

Movement immutability

Credit history is immutable. When usage changes, a charge is canceled, or a billing workflow reverses previously consumed credits, Metering & Billing books a correction movement. Metering & Billing doesn’t rewrite the original movement.

This gives the ledger a stable audit shape:

T1: +100 funded
T2:  -40 consumed
T3:  +10 returned by a correction

The ledger keeps the original consumption at T2 and records the 10 returned credits as a separate movement at T3, so the final balance is 70.

Safe grant retries

To make grant creation safe to retry, set a key on the grant. The key is unique per customer. Sending the same key again for the same customer returns a 409 Conflict instead of creating a duplicate grant. You can reuse the same key for different customers.

Deterministic consumption

When a customer has multiple grants in the same currency, Metering & Billing consumes credits in a deterministic order:

priority asc
restricted before unrestricted
expires_at asc
stable movement order asc

Lower priority values are consumed first. For equal priority, credits restricted to specific features or plans are consumed before unrestricted credits, then earlier-expiring credits are consumed first, and credits that never expire come last. If all of these are equal, Metering & Billing uses stable movement order. Only credits whose restrictions match the charge are eligible.

This rule keeps consumption predictable and also protects expiration correctness. When credits are consumed, Metering & Billing knows which future expiration should be reduced.

Credit expiration

Expiration removes only unused credits. If a customer uses part of an expiring grant, the used portion doesn’t expire later.

T1:  +100 funded, expires at T10
T5:   -30 consumed
T10:  -70 expired

The original grant was 100 credits, but only 70 credits remained unused at expiration. The consumed 30 credits were already spent, so they are not expired.

Transaction history is a projection

The double-entry ledger contains the accounting detail needed for correctness. Customer credit transaction history shows the customer-facing movement:

Type

Meaning

funded credits were added
consumed credits were used by charges
expired unused credits expired
voided unused credits were forfeited because the grant was voided

This projection keeps the public history understandable while preserving accounting correctness underneath. Internal accounting movements, such as the temporary movements used to convert a custom-currency overage into the invoice currency, aren’t shown.

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!