[HN Gopher] How we made billing backendless
___________________________________________________________________
How we made billing backendless
Author : ayushrodrigues
Score : 33 points
Date : 2025-05-15 13:54 UTC (9 hours ago)
(HTM) web link (useautumn.com)
(TXT) w3m dump (useautumn.com)
| robertlagrant wrote:
| Why not just authenticate the user against that customer_id, and
| then you can pass the customer_id around as much as you like (or
| have a surrogate key to it for a little more security)?
|
| A JWT with the customer_id (or surrogate) in would let you do
| that in serverless function.
| ayushrodrigues wrote:
| yep, this is the plan
| robertlagrant wrote:
| Oh, I must have misread? I thought the thing was a custom
| encryption/decryption dance instead of a signed JWT.
| taurath wrote:
| I'm rather confused by this article - I've made products and
| pricing services, and just on the first line its said that
| billing requires webhooks and state syncing.. but why? Is it a
| way to utilize payments in an otherwise static site? Whats the
| benefit? You can absolutely accept payments without webhooks.
| Please help, I really don't understand the niche!
|
| I'm left with the sense that this is a sort of solution that's
| trying to do auth permissions via the billing process, without
| calling it auth. Any access token you'd set up for auth with
| roles or permissions can give you access to both a customerId and
| whatever access grants you'd want to give.
| ayushrodrigues wrote:
| Yes you're right -- payments can definitely be done without
| webhooks, but it is typically all controlled server-side.
| Especially things like upgrade and downgrade flows, as they
| involve automatically charging a user's card.
|
| What we were exploring is whether there's a way to do this
| securely from the frontend (eg on a pricing page) without
| needing to open up backend routes.
|
| You're also correct that our niche is trying to control feature
| permissions, so that we can decouple pricing logic from an
| application (which makes it easier to handle pricing changes,
| custom plans etc). We are moving more towards a solution that
| just uses the JWTs to handle this instead of a customer_id.
| taurath wrote:
| I've made solutions before that a product can have many
| permissions, a product can have many prices, and a product
| can also be a bundle of products. The products service does
| the heavy lifting by having systems to determine things like
| addons (If have Product1 that gives Permission1, you can
| purchase Product43 as an Addon to give Permission2).
|
| This will not give you clean easy to understand reporting if
| you make bundles willy-nilly (N product line makes $ dollars,
| if bundled products exist), but to me, it gives accurate data
| that matches up with the pricing complexity that the business
| is designing.
| supportengineer wrote:
| The browser allows JavaScript to be modified. Therefore, you
| can never trust the client side. You can't put "trust" there.
| FinnLobsien wrote:
| I work in the billing space at Lago, so I think I can add a bit
| of color (though I'm also somewhat confused).
|
| Technically speaking, billing and payments are two separate
| things.
|
| For example: OpenAI needs to calculate how much you need to pay
| for the tokens you consumed across all of its models. That
| usage aggregation, calculation and then issuing of an invoice
| is billing--payments is only the transfer of money.
| baobun wrote:
| You should look deeper into JWTs and what you can do with them.
| Sounds like you are on the way to reinventing them.
| ayushrodrigues wrote:
| Yes! This is exactly what we're doing now which also helps us
| be a little more framework agnostic. Nextjs kind of just lets
| us have them built-in
| MobiusHorizons wrote:
| JWT is a standard that is supported by a lot of frameworks
| and auth libraries. It's also reasonably straightforward to
| implement yourself. It's very easy to make big security
| mistakes when you roll your own security, though, so it's
| best to at least stick with proven paradigms even if you
| implement it yourself for a new framework. Also read up on
| the mistakes people have made in implementing it and avoid
| repeating those mistakes.
| beej71 wrote:
| I don't get it. If someone gets a hold of the encrypted customer
| ID, can't they impersonate the customer? Is it just that the
| customer ID is guessable?
| johnyeocx wrote:
| That's true for now -- we definitely don't recommend using the
| encrypted customer ID as a fully secure method for auth, but
| implemented it more as a way for users to quick start without
| friction
|
| 1. This is also why we've built plugins for popular auth
| providers like Clerk, Better Auth and Supabase, which are
| called on the backend to fetch the user / org ID.
|
| 2. The encrypted customer ID is more of an experiment atm, and
| down the line if we continue working on it we might even build
| an auth system involving JWTs -- though that'd be reinventing
| the wheel and not something we're keen on
|
| 3. We are actually now working more on a framework agnostic
| pattern where users register a middleware on their backend
| which will spin up routes for Autumn, and the frontend provider
| contains a client which simply calls these routes
| ayushrodrigues wrote:
| Also we can make these rotate with each request
| serbuvlad wrote:
| I find everything about web technology nowadays to be extremely
| obtuse.
|
| I am mostly an embedded/Linux driver engineer, but I think I know
| the basics of HTTP, REST APIs, Docker containers, how the web
| works overall etc.
|
| But, like. What are we doing?
|
| What do you mean make the billing backendless? Obviously there
| has to be a backend to process the payment. What are you even
| saying? You are presumably not building a distributed blockchain
| - and even that requires permanent nodes.
|
| Same with serverless (which are just Edge Functions and could
| just be called that, or serviceless, if you really wanted to
| define it negatively).
|
| If these people named NoSQL, it would be called databaseless.
| elteto wrote:
| They encoded the billing rules into the fabric of spacetime,
| making them a fundamental property of the universe. Now there
| is no backend anymore, only reality.
|
| That will be $6.62607015e-34 please.
| taurath wrote:
| Give yourself some credit here, I'm a web developer who works
| on billing systems and I also have no idea what it is that they
| mean. My best guess is that they're making a marketing message
| that they do not have a very particularly annoying workflow of
| a very particular billing integration (Stripe webhooks maybe?).
|
| My problem is when you know that workflow, and that
| integration... you actually don't need it, its just nice to
| have. Its just a way for Stripe to send you updates to an
| endpoint with the status, like if say a card has declined as
| the charge is closing. But you _can_ just poll.
| MobiusHorizons wrote:
| I believe the marketing material around serverles functions is
| at fault. Clearly there is a server, because there is a
| computer answering requests on a specific ip address mapped to
| dns. So the wording is maddening. It's a bit like cgi-bin
| except it spins up a vm or other sandbox to run the serving
| code instead of just starting a process.
| jollyllama wrote:
| Functions-as-a-service was a better descriptor.
|
| This is just billing as a service.
| serbuvlad wrote:
| Oh, so there is a billing backend. It's just managed by
| someone else.
|
| Then yeah, just call it billing as a service.
|
| I just dislike the wording of it all. "You don't have to do
| the billing in the backend, you can do it on the frontend".
| As if the frontend and the backend were mythical realms
| fighting for control.
|
| We went from PHP generated websites, to PHP backend
| generation bad, use "client-side rendering" and "single-
| page applications", as the shiny new thing.
|
| Then we went to Server Side Rendering (SSR), as a new
| thing. What do you mean a new thing? You're just doing in
| Node what everyone was doing in PHP 15 years ago.
|
| And that's fine!
|
| Not every idea has to be revolutionary, not everything has
| to be "the future", or "the only way".
|
| You've found a service that does billing for you without
| having to integrate it into _your_ backend. Great! Amazing!
| Good for you! I 'm sure it's of interest to a lot of
| people!
|
| But why can't you just, you know, say it like that?
| skeptrune wrote:
| >If these people named NoSQL, it would be called databaseless.
|
| Lmao, this is way too good. I'm going to steal this.
| ljm wrote:
| One day there will be a type of web developer who completely
| dismisses the concept of running a backend and instead whips
| out their wallet and subscribes to a dozen SaaS providers
| instead. Literally everything else will be client side inside
| NextJS.
| UK-AL wrote:
| It's not really backendless more like outsourcing backend.
| singron wrote:
| > Server actions are public, unauthenticated routes
|
| Why can't they be authenticated? That seems like the obvious fix.
| Otherwise how you are handing out the correct customer_id unless
| you authenticate somehow?
|
| This scheme also complicates API key rotation, although you can
| work around it by trying to decrypt with both the old and new key
| if you use e.g. authenticated encryption.
|
| This also has no mechanism for expiration (besides API key
| rotation). If you add an expiration time and sign it, then you
| essentially created an authentication token that you use as the
| customer_id.
| johnyeocx wrote:
| Maybe we didn't phrase it as well as we should've. We meant to
| say API routes in general are public, and so the server actions
| could be called by anyone.
|
| Authentication is definitely possible, but we were trying to
| brainstorm a way where users could have protected routes with
| as little set up as possible, the ideal being they just pass in
| customerId into a Provider component
|
| We also did think about things like registering an auth
| function but felt that being able to just pass in customerId
| would be a magical experience!
|
| Definitely acknowledge that the current mechanism has flaws
| though -- it's really more of an experiment at the moment, and
| if it does indeed become very popular with users we would
| implement auth mechanisms like JWT and what not -- though that
| would kinda be reinventing the wheel
| captn3m0 wrote:
| The current mechanism has security flaws that are hiding
| because of SSR. Try to implement the same flow in pure-
| vanilla-js and you'll realize that you're hitting replay
| attacks instantly. This is the same vulnerability that
| companies which try to "hash the password on the client side
| to protect it" face - they've merely transformed the password
| to a different one (the hashed one) which has the exact same
| semantics as the original password for an attacker.
|
| Your encrypted customer ID has the exact same semantics as
| the original customer ID for an attacker, and is insecure.
| biker142541 wrote:
| Like others, quite confused here. If it requires server actions,
| then it's not backendless? Just say you are simplifying the
| backend and how you interact with it, if that's what you are
| doing.
| ayushrodrigues wrote:
| I intended to use backendless more as a figure of speech here.
| We wanted to make billing "feel" backendless.
| owebmaster wrote:
| The title is lying then, hope the mods change it because I
| only clicked thinking it would be about something backendless
| and then it talks about one of the crappiest server
| frameworks available.
| oatmeal_croc wrote:
| You could also say "I made the billing a winged cow sailing a
| boat" and it would be a figure of speech.
| Daviey wrote:
| I find this "backendless billing" approach fascinating because it
| highlights the tension between DX and security. As someone who's
| built payment systems, I understand the appeal of reducing
| backend boilerplate, but there's always a security tax to pay.
|
| The real issue seems to be that they're trying to make billing
| "feel frontendish" when it's inherently a backend concern. The
| encryption approach in Part 3 is essentially recreating auth
| tokens but with extra steps, as others have noted - they're
| basically reinventing JWTs.
|
| What struck me most was the security vulnerability they
| discovered with server actions. If you can make calls with any
| customer_id without verification, that's a textbook IDOR
| vulnerability. A simple curl request with a different customer_id
| would let you upgrade/downgrade other accounts! No amount of
| client-side magic can fix fundamentally flawed authorization.
|
| Their conclusion is telling, sometimes the "boring" approach
| (proper backend routes with auth) exists for good reasons. I
| appreciate their transparency about the journey though, we learn
| more from these explorations than from pretending everything
| works perfectly from day one.
| ayushrodrigues wrote:
| Appreciate the comment! Has definitely been an interesting
| journey for us exploring the space
| codegeek wrote:
| Interesting how YC funds similar companies. useautumn looks a
| close competitor to another YC company getlago.
| ayushrodrigues wrote:
| From a high level yes, but we are taking a very different
| route. They're very deep into usage-based billing and high
| throughput events, whereas we're more for early stage founders
| and "pricing in a box"
| oulipo wrote:
| Reading the blog it seems the engineers there lack basic
| knowledge about safety (see their multiple different approaches
| where they learned "after the fact" that their approach wasn't
| secure)... this doesn't inspire a lot of safety
| delusional wrote:
| If you don't have a backend, how do you make sure I'm billed?
|
| What's stopping me from opening the console and calling the
| "addMoreCredits" function? Why can't I just edit the code to
| remove any mention of consuming credits?
|
| I think you're about to discover why most multiplayer games have
| moved authoritative simulation to the server.
| johnyeocx wrote:
| it was more of a figure of speech where the entire
| implementation for the user would be on the frontend (React).
| Sensitive operations are being called securely on the backend,
| just through Next.js server functions!
| throwaway63467 wrote:
| Aren't server actions a backend?
| mathgeek wrote:
| As they say, the cloud is just someone else's server.
___________________________________________________________________
(page generated 2025-05-15 23:01 UTC)