Skip to main content
Billing is what each tenant owes and what they have left: a balance, what the current period has come to, and where the money went. This page is the operator’s view; an organisation admin sees their own on the same screen, with the cost and margin columns withheld. What they see, and what they can read off it, is the tenant’s billing page.

Balances

Each tenant has a balance, a credit limit and a reserved amount. Reserved is credit held against calls in progress — money not yet spent but no longer available, which is what stops a prepaid tenant starting more calls than their balance can finish.

Adding credit

Billing → Balances → Add credit puts money on an organisation’s balance. Pick the organisation from the list, or use a row’s Add credit.
  • The amount is exact, in the organisation’s billing currency.
  • The description is shown on the organisation’s ledger.
  • A reference can be entered only once, so a transfer recorded twice is refused rather than credited twice.
A row’s Ledger lists every entry and who made it. Holds for calls in progress are hidden unless you ask for them. Adding credit needs the operator’s billing permission. Organisations can read their own ledger but cannot write to it.

Credit limits and postpaid

A row’s Limits sets three things:
  • Credit limit: how far below zero the balance may go before calls are refused.
  • Enforce the limit, for a postpaid organisation: off by default, and every postpaid organisation you already have is unchanged. Off, calls are rated and never stopped, as postpaid always was. On, calls are held against balance + credit limit and cut off exactly as a prepaid one’s, so a postpaid client cannot run up more than you have agreed.
  • Warn below: when available credit falls below this, the organisation’s admins and you are emailed once, and a Low balance alert opens. A top-up that lifts it above the level closes the alert, so the next fall warns again. Empty means no warning.

Card payments through Stripe

Organisations can top up their own balance by card, paid into your Stripe account.
  1. Settings → Payments: turn it on, enter your Stripe secret key (sk_...; a publishable pk_ key is refused) and the webhook signing secret, and set the smallest and largest top-up.
  2. In Stripe, add a webhook to the address the page shows, https://<your API host>/api/v1/public/payments/stripe/<operator>, for the events checkout.session.completed and checkout.session.async_payment_succeeded.
The keys are stored encrypted and never shown again. Only Stripe’s signed webhook adds money. A payment page that returns successfully credits nothing on its own. A webhook delivered twice, or both events for one payment, credits once. A payment is not credited, and is logged as an error for you to refund in Stripe, if it:
  • names an organisation that is not yours;
  • is in a currency other than the balance’s.
Currencies without cents are not offered.

Monthly statement

A row’s Statement shows one month for one organisation. Choose the month, and Download CSV for a spreadsheet. It contains:
  • the opening balance;
  • each payment and credit, with the total;
  • rated calls by destination country and by trunk, each client trunk named (the rest are Phones and applications);
  • the closing balance.
A call that crossed two of your nodes is counted once. Organisations read their own statement on the same screen.

Prepaid cut-off

A credit check runs before a call is placed. A tenant out of credit is refused at origination rather than discovered mid-call, and the refusal carries a reason. The caller hears the reason too: “Your balance is not enough to make this call” when credit or a team budget has run out, and “Calls to this destination are not allowed on your account” when the rate card has no price for the number. Each organisation can replace either with its own recording; see refusal announcements.

Settlement is idempotent

A call is settled exactly once. A replayed hangup — which happens — does not bill twice.

AI is separate

Minutes and tokens are rated on different cards and appear separately. The “charged” figure on a call record is telephony only; a call answered by a virtual agent has its AI cost alongside, not folded in.

Exchange rates

A carrier charges in its currency; you bill an organisation in yours. Billing → Exchange rates is what joins them, so that a call’s margin is a real number and not dollars subtracted from rupees. Enter one direction — 1 USD = 83.2 INR — and the other is worked out from it.
  • A rate is added, never edited. When it changes, add a new one. The rate in force when a call ends is written on that call, beside what the carrier charged in its own money, so entering this month’s rate cannot move last month’s margin. Old rates stay listed: they are the record of what past calls were converted at.
  • A rate dated in the future waits its turn. In force marks the one a call ending now would use.
  • The charge is converted, not the price. Minimums and increments are the carrier’s arithmetic and are done in the carrier’s currency first.
On a call record: currency is what the sale, the cost and the margin are all in; cost_currency, cost_amount_original and fx_rate are what the carrier charged, in what, and the rate that turned it into cost_amount.
With no rate for a pair, a call’s cost cannot be converted. The carrier’s figure is kept, the call is marked cost_unconverted, the log says so at error level, and the calls list shows that margin as ? — never as a number, because it would be one currency subtracted from another. Add the rate; calls from then on convert. Importing a price list tells you about a missing pair before anything is written.

Withheld is not zero

Where a reader may not see cost or margin, FireTone omits it and the panel draws it as withheld. It never substitutes zero. A zero here would read as “this call cost us nothing”, which would be a false statement about the business rather than a missing one.