How it works
Decimal literals use the m suffix and preserve decimal arithmetic for this calculation. The pipeline keeps only paid invoices and sums their amounts, so the unpaid row contributes nothing. Formatting with an invariant culture produces the same decimal separator regardless of the device’s display language. Decimal reduces the binary representation surprises common with base-ten money values, but it does not choose a currency, a tax rule, or a rounding policy.
Those decisions still belong in the domain. Sum on an empty decimal sequence returns zero, which is appropriate for some totals but should not hide missing or incomplete source data.
Mark every invoice unpaid and predict the result. Then add a tax calculation and choose deliberately whether rounding happens per invoice or only after the final total.
A working example
using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
var invoices = new[] { new Invoice(12.50m, true), new Invoice(8m, false), new Invoice(4.25m, true) };
var total = invoices.Where(x => x.Paid).Sum(x => x.Amount);
Console.WriteLine(total.ToString("0.00", CultureInfo.InvariantCulture));
record Invoice(decimal Amount, bool Paid);
Expected output
16.75
Keep decimal values numeric until the final formatted output.