How invoice totals are computed

Every figure on a document made here — each line amount, the subtotal, the discount, the tax, the shipping, the total and the balance due — is produced by one small money engine, in a fixed order, from the quantities and prices you type. This guide walks through that engine one step at a time: what it computes, why it computes it that way, and where it deliberately stops. The methodology page states the rules; this page shows them at work.

Every number below was computed by that same engine when this page was built, from fictional documents whose inputs are named in the sentence. No result here is a typed-in figure — only the example inputs are — so the prose cannot disagree with the tool. Other guides in this series are listed on the guides page.

Whole cents, never decimals

The engine converts every amount you type into an integer number of cents before it does anything else. The reason is that binary floating point cannot represent most decimal fractions exactly: 0.1 + 0.2 evaluates to 0.30000000000000004. One line hides that; a column exposes it. A fictional supplier bills 100 identical lines of one unit at 19.99. Added in floating point, the machine reports 1999.0000000000007. Added by the engine in integer cents, the subtotal is 1,999.00, which is also what the person checking the document with a calculator gets. Integer cents make the arithmetic exact, so the engine never has to hide a stray fraction.

One line: quantity × unit price, rounded once

A line is quantity multiplied by unit price, rounded to a cent immediately. The rounding is half away from zero, which is how people round by hand: a half-cent goes up. Suppose a timber yard enters 1.5 units of hardwood offcuts at 0.33 each. The exact product is 0.495; the engine prints 0.50. Banker’s rounding is not used; the methodology page gives the reason: it is better behaved statistically and would surprise every user.

A unit price is held to two decimal places. Typed as 0.125, the price field refuses it: “Enter a valid unit price with at most 2 decimal places.” A lone three-digit group after a single separator is read as a thousands group instead, as the methodology page records for 1.250; the parser makes one exception, for a whole part that is a single 0, which is why 0.125 is refused rather than read as a whole number. Typed as 1.125, the same field reads 1,125.00. Behind the form, the engine also rounds any sub-cent price to a printable price before multiplying, so a translator’s rate of 0.125 per word for 2,000 words would be printed as 0.13 a word and a line of 260.00, not the 250.00 the raw arithmetic gives. That is deliberate: a line reading “0.13 × 2,000 = 250.00” looks like an error even when the exact arithmetic supports it. The same job entered as 2 units at 125.00 per thousand words prints a line of 250.00, so a rate in fractions of a cent wants a unit that gives a price the document can show.

Quantities are held to four decimal places. The quantity field accepts 3.3333 and refuses 3.33333: “Enter a valid quantity with at most 4 decimal places.” A consultant billing 3.3333 hours at 60.00 has an exact product of 199.998, which prints as 200.00; because the quantity is fixed at four places before anything is multiplied, a billed third of an hour cannot drift as it is repeated down the page.

Why the printed lines must add up

Rounding once at the line, rather than carrying exact products and rounding only the total, is marginally less accurate and visibly right. Harbor Lane Studio bills three sessions of an hour and twenty minutes, entered as 1.3333 hours each at 90.00. Each line is exactly 119.997 before rounding and prints as 120.00; the subtotal is the sum of the three printed lines, 360.00. Carrying the exact products and rounding at the end would instead print 359.99 beneath three lines that visibly add to 360.00. A reader with a calculator would stop there and query the document. The engine takes the version that reconciles in the hand of the person holding it.

The order of operations

After the lines are settled, the rest of the document is computed in one fixed sequence, and each step reads only the result of the step before it:

  1. Subtotal — the sum of the rounded lines.
  2. Discount — a percentage of the subtotal, then any flat amount, capped at the subtotal.
  3. Taxable base — subtotal minus discount.
  4. Tax — added to the base, or extracted from it, depending on the mode.
  5. Shipping — added after tax.
  6. Total — base plus tax (when tax is on top) plus shipping.
  7. Amount paid — whatever has already arrived; the document builder passes it to the totals only for an invoice.
  8. Balance due — total minus amount paid, floored at zero.

Discount comes off before tax

Fenwick Joinery invoices four oak shelves at 185.00, 6.5 hours of fitting at 48.00 and fixings at 23.70, with a 10% discount and tax added on top at an example rate of 20%. The subtotal is 1,075.70. The discount is 107.57, leaving a taxable base of 968.13. Tax on that base is 193.63, and the total is 1,161.76. The discount comes off first because tax is owed on what was actually charged: the same lines and rate with no discount produce 215.14 of tax, so computing the tax before the discount and then taking the discount would overstate the tax line by the difference.

A flat discount is applied after the percentage, not instead of it. Add a 25.00 goodwill reduction to the same invoice and the discount line becomes 132.57, the base 943.13, the tax 188.63 and the total 1,131.76. The percentage is worked out and rounded to a cent first, the flat amount is added to it, and the document shows one combined discount figure.

Tax on top, or tax already inside

The tax mode decides what the prices you typed already contain. With tax added on top, as in the Fenwick example, the tax is a percentage of the taxable base and increases the total. With tax already included, the prices are gross: the engine finds the tax inside them by dividing by one plus the rate, and the total does not change. Marigold Catering enters a buffet at 18.50 a head for 24 guests and five hours of service staff at 32.00, with 20% already included. The subtotal is 604.00; the tax extracted from it is 100.67; the total stays 604.00.

The common misreading is to subtract a percentage from the inclusive price instead. Twenty percent of 604.00 is 120.80, which overstates the tax by 20.13 — a fifth of the correct figure, because the rate applies to the net price, not the gross one. The engine never subtracts a percentage in inclusive mode. Shipping on an inclusive document is simply added to the base: with 15.00 of delivery, Marigold’s total is 619.00, and the tax inside the prices is not added a second time. The inclusive-versus-exclusive guide works the extraction at several rates, and sales tax vs. VAT explains which shape of tax each mode is for. Which mode applies to your prices is not something the engine decides.

Shipping is added after tax

Pennant Press invoices 250 letterpress cards at 1.20 and 250 envelopes at 0.18, with tax on top at an example rate of 7.5% and 12.50 in the shipping field. The subtotal is 345.00, the tax 25.88, and the total 383.38: the shipping sits outside the taxable base and is added once the tax is known. That is a stated simplification. Some jurisdictions tax freight, and this tool does not model that; the methodology page says to add shipping as a line item instead if yours does. Entered that way, as a line of one unit at 12.50, Pennant’s subtotal becomes 357.50, the tax 26.81 and the total 384.31. The engine does not choose between the two; the field you put the figure in does.

The amount-paid field records money that has already arrived. Cobble Street Tutoring invoices eight hours at 45.00, a total of 360.00 with no tax, and 150.00 was paid as a deposit. The document carries the total, the 150.00 paid, and a balance due of 210.00. If the client has paid 400.00 against the same invoice, the balance due is 0.00 — the field is floored at zero rather than printing a negative figure, and the 400.00 paid is still recorded. The payment terms guide covers deposits and part payment from the other side of the table.

The document builder passes the amount-paid field to the totals only when the document is an invoice. Built as an invoice, Cobble Street’s document ends with a line labelled “Balance due”. Built as a receipt from the same lines, it ends with “Amount paid” carrying the document total, 360.00: a receipt is the record that the whole amount arrived. The already-paid field is ignored on a receipt — the 400.00 entered against this one never reaches the totals, whose amount-paid figure is 0.00 — and the payment method, here “Bank transfer”, is kept instead. A quote ends with “Quote total”. The reason the label changes with the document rather than being typed is set out in the bottom-line label guide and in invoice vs. receipt vs. quote.

A discount can reach zero, not below it

Northgate Bikes charges 12.00 for a puncture repair, applies a 20.00 voucher as a flat discount and has tax on top at an example rate of 10%. The discount is capped at the subtotal, so the discount line reads 12.00, the taxable base is 0.00, the tax is 0.00 and the total is 0.00. A voucher larger than the bill does not produce a credit; the engine has no concept of one and prints no credit line.

Where the engine stops

The engine refuses inputs it cannot represent rather than guessing, and the messages it gives are its own, reproduced here as it issues them:

  • An empty document: “Add at least one line item.”
  • One line too many: “A document holds at most 200 lines.”
  • A tax rate above 100%: “The tax rate cannot exceed 100%.”
  • A discount above 100%: “The discount cannot exceed 100%.”
  • A negative quantity: “Quantity cannot be negative.”
  • A rate with too many decimal places, such as 8.12345%: “The tax rate can have at most four decimal places.”

What it does not do is decide anything. It applies the rate you type, in the mode you select, and prints the result. It does not know which rate applies to you, whether a sale is taxable, whether your prices should be shown inclusive, or how freight is treated where you trade. It is a document generator, not an accounting system and not tax advice, and the arithmetic described here is the whole of what it asserts.

Questions

Why does the tool work in whole cents instead of decimals?

Because binary floating point cannot hold most decimal fractions exactly, and the error grows down a long column. Every amount is converted to an integer number of cents as soon as it is entered and stays that way through the subtotal, discount, tax, shipping and balance. Integer addition is exact, so the lines on the document add to the subtotal printed beneath them.

Why does my own calculation differ from the document by a cent?

Usually because the engine rounds each line to a cent immediately and adds the rounded lines, while a calculator carries the full product forward and rounds only at the end. Each rounding moves a line by at most half a cent, so the gap depends on how many fractional lines there are: the Harbor Lane example on this page prints a subtotal of 360.00 from three rounded lines, where carrying the exact products and rounding once at the end gives 359.99. The engine chooses the first method so that the printed lines reconcile with the printed subtotal.

Is the discount applied before or after tax?

Before. The sequence is subtotal, then discount, then the taxable base, then tax. A percentage discount is taken from the subtotal, a flat discount is subtracted after it, and the tax rate is applied to what remains. Working the tax out on the undiscounted subtotal would overstate it.

Why is the shipping figure not taxed?

Shipping is added after tax as a documented simplification: this tool does not model the places that tax freight. If shipping needs to fall inside the taxable base on your document, enter it as a line item instead of in the shipping field, and the tax is then computed on it like any other line.

What happens if the amount already paid is more than the total?

The balance due shows zero rather than a negative figure. The amount-paid field is subtracted from the total and the result is floored at zero. The field is read only on an invoice; a receipt and a quote ignore it, because neither document carries a balance due.

Can a discount make the total negative?

No. The combined percentage and flat discount is capped at the subtotal, so the taxable base can reach zero and never go below it. Tax on a zero base is zero, and the total is then whatever shipping was entered, or zero.

Every figure on this page was computed when the page was built by the same engine the invoice, receipt and quote generators use; the rules themselves are set out on the methodology page. The generators run on your own device, and nothing you enter leaves your browser.