4 ms·
Honestly, billing is really not that hard. I've built some billing systems myself, and although it's easy to make mistakes if you read up on the known pitfalls
by gizmo 4y ago
Honestly, billing is really not that hard. I've built some billing systems myself, and although it's easy to make mistakes if you read up on the known pitfalls rolling your own billing system is not a big deal.
One key thing to remember is that if you want your billing to make sense to your customer you can't get too clever about it. A few rules of thumb: when you have to round anything, round in favor of the customer. Split the logic that calculates what should happen and the billing part of the billing system. For example, if you store a next_billing_date for each customer you can trivially adjust the date as needed, but if you have a crobjob that calculates which customers should get billed and then immediately bills them manual overrides are harder.
Giving a user what amounts to a few free days of service when they upgrade/downgrade is no big deal. Especially because you should see more upgrades than downgrades in any given month. In some cases the easiest way to credit people is to move their next_billing_date forward. For usage based pricing (e.g. number of active users in a month) do the easy and fair thing where you take the minimum of active users during the month (store num_active_users each night for each customer, and use that for billing and for user facing billing dashboard). Otherwise you get edge cases where you overcharge customers when they add and remove many users because then the max of unique user ids is >> the number of active users at any given time. The example query in the blogpost gets this wrong.
The SQL query that aggregates the number of API calls for a user is wrong for the same reason because it confuses API calls with billable API calls. You should have a cron that counts the API calls for each user and stores them separately in a billing table. Then when a good customer has a junior programmer make a ton of API calls by mistake you can easily go into the billing table for that customer and manually adjust the usage, with total confidence that future invoices will be correct. If you compute the usage at the time of billing then everything gets needlessly complicated.