number_format() returns text, not a number
Problem. number_format() is made for display. With its defaults it puts a comma between the thousands, so number_format(12499.9, 2) returns the string "12,499.90".
Cast that string back with (float) and PHP reads it from the left until it meets a character that cannot be part of a number. The comma stops it, and 12,499.90 becomes 12.0. There is no error and no warning, just a wrong total in the invoice, the CSV export or the payment request.
Fix. When a machine will read the output, pass the decimal point and an empty thousands separator yourself: number_format($total, 2, '.', '') returns "12499.90", which casts back to the value you started with.
Better still, do all the maths on the original number and call number_format() once, at the very end, for whoever reads the result.
// Before: formatted for people, then used as a number$total = number_format(12499.9, 2); // "12,499.90"$withVat = (float) $total * 1.16; // 13.92, because (float) read 12.0// After: do the maths on numbers, format only for output$withVat = 12499.9 * 1.16; // 14499.884$forPeople = number_format($withVat, 2); // "14,499.88"$forTheApi = number_format($withVat, 2, '.', ''); // "14499.88"Result. Totals stay correct, and each output has the format its reader expects: separators for people, none for CSV files, APIs and form values. For money, store whole cents as integers so floating-point rounding cannot creep into totals, and keep number_format() for display.