[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)