Sapior LogoSapior

No, It’s Not Just You: Billing and Account State Are a PITA to Remember

Billing, account management, and pricing feel impossible to keep in your head because they’re usually six systems wearing one trench coat.

It’s not just you

Billing and account management are the parts of a developer tool that almost nobody wants to think about. Authentication lives in one provider. Plans and entitlements live in your database. Invoices live in Stripe. Usage lives in ClickHouse or your event pipeline. Pricing copy lives on the marketing site. Customer support asks you to manually check a portal. You end up holding six different mental models, and none of them agree.

The memory tax is the real cost

Every time someone asks “why can’t this user see feature X?”, you trace account_id → customer_id → subscription_id → price_id → entitlement flag. That path is rarely one hop. Teams usually remember the happy path for monthly plans and forget edge cases: annual prepay, proration, seat additions, plan downgrades, paused subscriptions, overdue invoices, usage caps, trial expiry, and canceled-but-active states.

This isn’t a discipline problem. It’s a system design problem. Billing state is a state machine, but most teams implement it as scattered flags and webhook handlers. [Stripe’s subscription objects](https://stripe.com/docs/billing/subscriptions/overview) encode a good portion of this, but entitlements and account identity still live outside Stripe. [Clerk](https://clerk.com/docs) solves login, not plan state.

Pricing is code, but rarely treated that way

Pricing changes often start on a landing page, then get duplicated into checkout, a billing API, a database migration, and a support macro. Each copy is a chance for drift. A new plan is rarely just a price—it changes what existing customers can access, what usage counts, what invoices show, and what happens when they downgrade.

A saner mental model

Treat account, billing, and pricing as one domain object: a customer account has a plan state, an entitlement set, a usage window, and an invoice status. If any of those can be changed independently, you’ll eventually forget which one changed.

The fix is to make the API model match the business model:

One account graph, not separate auth and billing IDs.

Plan and price changes apply to entitlements immediately, not after a webhook turnaround.

Usage metering writes to the same state that invoices read.

Customer-facing billing history and plan controls live in the same system as internal tooling.

What Sapior does

At Sapior, we build the account and billing layer for developer tools. Instead of wiring Stripe, auth, metering, entitlements, and a customer portal by hand, you get a single API for accounts, plans, pricing, metering, and invoices. The point is not to hide Stripe—it’s to stop reconstructing the customer’s billing state from five different systems.

When billing feels like a PITA to remember, it usually means you’re memorizing glue code instead of working with a model.

Why Billing, Account Management, and Pricing Are So Hard to Remember | Sapior