Most billing bugs aren't about the invoice math. They're about having two code paths that both think they're responsible for charging the customer.
We just shipped a fix for exactly that in DymCore, our invoicing and billing platform for small businesses. The commit message says it plainly: "lo que se ve es lo que se cobra" — what you see on screen should be what gets charged, no more, no less.
DymCore lets businesses add paid modules on top of their base plan. Module purchases touch two places in the codebase: a module-billing service that handles the module's own lifecycle, and the store/billing service that aggregates everything into what the customer actually pays. When both paths compute a charge for the same module instead of agreeing on a single total, the business ends up billed twice for one thing.
The fix consolidates that logic into one place: a new consolidated-billing.ts module that becomes the single source of truth for what a combination of modules should cost. billing.service.ts, module-billing.service.ts and store.service.ts were all updated to go through it instead of calculating their own partial totals.
We also added a dedicated spec file, cobro-consolidado.spec.ts, with 111 lines of tests just for the consolidated path, covering module combinations that previously had no coverage at all. The billing dashboard on the frontend was updated too, so what the business owner sees on the page matches what the consolidated service actually charges.
None of this is glamorous work. It never shows up in a changelog a user reads, but it's the difference between a business trusting its invoice or opening a support ticket. If you're building anything with modular pricing, it's worth asking early: is there exactly one place in your code that decides what a customer pays, or did that logic quietly grow in two places at once?
DymCore is an invoicing and billing platform built for small businesses in Ecuador and Latin America, including SRI-compliant electronic invoicing. More at dymcore.com.