Skip to main content
A billing plan is a reusable rule set that turns a driver’s raw usage (currently toll tickets) into money on an invoice. A plan is defined once; the system uses it to generate invoices as agreements accumulate usage.
Three layers:
  1. Plan — the container plus global settings (grace periods, due dates).
  2. Charges — the line-item rules inside a plan.
  3. Invoices — the output (see Driver Billing Overview).

The plan

A plan belongs to a fleet. A fleet can have many plans. A plan applies to an agreement in one of two ways:
  • Directly assigned to an agreement, or
  • Fleet default — used by any agreement without its own plan.
Which plan bills a driver = the agreement’s own plan, else the fleet default. If neither exists, no invoice can be generated.

Plan settings

All *_hours values are durations in hours, not timestamps.

Charges

A charge is one billable line. A plan has an ordered list of them. Each charge selects some tickets, reduces them to a quantity, multiplies by a unit rate, and produces one invoice line:

Charge fields

Aggregation types

  • count — number of matching tickets. Ignores aggregation_field. Example: “2.00pertoll"count×2.00 per toll" → `count` × `2.00`.
  • sum — add up aggregation_field across matching tickets. Example: pass through the raw toll cost → sum of amount × $1.00.
  • count_unique — number of distinct values of aggregation_field. Example: charge per unique day driven → count_unique of transaction_date.

Aggregation fields

The field that sum / count_unique operates on:
  • amount — the toll’s face amount.
  • cash_cost — the fleet’s negotiated cost (respects an amount-override setting); falls back to amount when no cash cost exists.
  • transaction_date — mostly useful with count_unique (unique days).
When aggregation_type is sum or count_unique, aggregation_field is required. For count it is not used.

Filters

Filters narrow which tickets a charge applies to. A charge’s filters is a list; all filters must match (logical AND). Each filter is a triple:
Supported fields: agency, transaction_date, exit_plaza, amount. Supported operators (op): When op is in, value must be a list. Fields and operators outside the supported sets are rejected by the backend.

Examples

“Charge $1.25 for every MTA toll”:
“Pass through the cash cost of all tolls over $5”:

From plan to invoice

Each invoice records why it was generated. The trigger maps to a plan setting: The three grace-period settings exist because each maps to one automated trigger. See the invoice lifecycle for how a draft becomes finalized.

Plan snapshot

When an invoice is created, the plan and its charges are frozen into the invoice as a snapshot. Editing the plan afterward does not change existing invoices — only future ones. Plan details shown on an invoice come from its snapshot, not the live plan. To correct an already-created invoice, use a fee adjustment (draft) or a credit note (finalized).

Corrections

Two distinct concepts:
  • Fee adjustment — edits a line on a DRAFT invoice before it is finalized. Overrides the quantity and/or unit rate for one charge line, with a reason. Original values are preserved.
  • Credit note — issued against a FINALIZED invoice to refund/reduce it after the fact. Has its own number, reason, line items, and PDF. The credit total can’t exceed the invoice’s remaining balance.
Rule of thumb: draft → adjust the fee; finalized → issue a credit note.