Comment by agreeahmed

1 day ago

The "storing my source of truth externally" is super fair, and something we plan to address soon by giving you the ability to store this data on your side. So you'll still get all the benefits of our data model and full stack SDK, but aren't locked in to our hosting.

> I don't understand how your service can even help with this. "Features" are necessarily part of my app, I have to define what the user is purchasing.

We let you define features that you reference using slugs that you decide, and then group those features with products. So when someone subscribes to the product, they get the features you defined and associated with that product. So to see whether they can access a feature (boolean):

useBilling().checkFeatureAccess('fast_generations')

Or to see if they have enough credits to take a usage metered action:

useBilling().checkUsageBalance('fast_generations')

The problem we're trying to address is a bit broader than just storing price ids. You use your customers' payments state to derive billing state, and you use billing state to derive app behavior (what features they can access, what usage meters what balances and whether those are sufficient to continue consumption). You need this data on your backend and your frontend. So a substantial amount of most CRUD app code is just managing, transposing, and shuttling this kinda of data around between backend and frontend.

For fun I once mapped out a vanilla SaaS checkout flow and realized that it required a developer to coordinate 15 server-client boundary hops [0]. Each one is a liability that you have to maintain. And the flow as a whole is one of the most frustrating to test. If a developer came up with this flow on their own, we'd immediately say it smells. But it's the flow required by the current best-in-class vendors.

And it's not entirely the result of complexity intrinsic to the domain. Much of it is the result of decisions made over a decade ago that haven't really been revisited. At least in React-land, we've learned a lot in that time about how gracefully different patterns for state management age in a codebase. The last time the webhook-only pattern was the frontier of DX, Redux was the considered the best state management framework for React.

I haven't seen Redux in React code in a very long time, maybe 6 years. Not because Redux is terrible - in fact it represented the community's best understanding of state management at the time. But over time we realized the limitations of Redux as a framework, and engineered our way out of them with new frameworks. This process is natural and beautiful and part of what makes technology magical. In payments, this improvement loop is significantly rate limited. Because to build a truly better solution you have to commit to all of the uphill compliance and financial services work that people have very astutely pointed out in other comments.

[0] https://x.com/agreeahmed/status/1965258666892034257/photo/1