For example, people building foreign keys to prices and receipt items. In what cases do you expect to retroactively change what you charged all customers? Copy that data to the receipt item, don’t give your accountant a headache and heart attack when you change pricing. I’ve also seen people using those same kinds of rows to determine what features a user gets access to. Don’t do that, use capabilities/roles. When a payment succeeds, update the user’s capabilities. When a payment fails, remove capabilities. This also allows support to just give a customer capabilities without a line item or changing their plan, because some customers are just annoying and it is less expensive to give them a feature. It also allows more easily selling custom-tailored solutions to bigger clients since the features aren’t linked to line items.
This article is more about usage-based billing, which is probably harder to get right, but feature-based billing is something I’m more familiar with and it’s so annoying to see all the ways people will fuck it up.