Developers January 19, 2020

[SaaS payment] How do you handle the account's status?


I have a question on SaaS' payment handling. Say, you have a SaaS product and you want to restrict access or amount of something depending on the selected plan.
For example, if a user is on a free plan he can create only one item, if "pro" - up to 10 etc. The same about the restrictions on some functionality (features).
When you use this approach you restrict your interface's elements, as well as back-end endpoints.
So, the question is now: how do you check the account's state? I see 2 approaches here:

  1. Use hooks from the payment's system. For example, if a user paid on time your hook will grab the user's id and set his account to "valid" or so. When the next time the user will try to create one more item, you will check his account, see "valid" there and allow (or "invalid" and disallow).
  2. Check the user's account's state (in a payment system) every time when a user tries to do something that can be restricted. You don't rely on your database (as it may be outdated) and just make call for payment's system endpoints which returns you some information about the user's account and you make a decision based on this information.

Which approach do you use and why?

  1. 4

    Don't use external services in real-time situations if you don't have to.

    1. It will always be slower
    2. Sh*t happens. Someday the service will be down or change the way it works, how do you react to that?
    3. There is a big chance that this will require more work, and be more prone to bugs. Less code is always better
    1. 1

      That's interesting, I didn't think in this direction, thanks!

  2. 3

    Basically, the first option. When the user sign upgrade to the paid subscription, you record customer id in user data plus some role corresponding to the plan they subscribed to. You check the permissions associated with the role in the API endpoint with the associated limits. The payment system provides a webhook, which allows you to get informed about whether the next charge was successful or not. If not, you can Mark the user and act accordingly, for example, remove the role or put the user to another role with limited permissions.

    1. 1

      Thanks, that makes sense.

  3. 2

    I use the first option. It has worked well so far but there were a couple of them that slipped past my wall. I'm yet to assess how it happened though...

    1. 1

      Haha, that why I'm thinking to have a hybrid system :)

  4. 1

    Hey man, I actually just finished building this functionality into my SaaS app on Friday. I think everyone here gave good answers, so I’ll be brief:

    For context sake, I used the Django (Python) platform for my app which makes it really easy to create “models” - think users, profiles, subscriptions- basically global objects that connect to the database. I, like most people here used stripe for handling payments which requires only a few lines of code to process. So, when a customer buys my pro plan the my app runs the “payment” function which also includes a short script that updates adds a current user to my subscribers model- that model is then referenced by the rest of the app for permissions sake.

    Hope this helps! 🤙🤙

    1. 2

      Thanks for sharing your experience. How do you check if a user has access to some restricted functionality - checking your own database information or checking the stripe subscription status?

      1. 1

        Sorry, forgot to mention that-> I use my own database. When a user buys my pro I make them a customer via the stripe api and then store their data in the subscription model... which references my database.

  5. 1

    I use the first one. Kinda safely decoupled with the external payment system 😁

  6. 1

    Nice question, I also want to develop something similar, what do you think is the best service to use for payments?

    1. 2

      The first option is as always, Stripe.

      1. 1

        I’m Italian, here is not very used, another one?

  7. 1

    Number 2. You should have business logic in place for whenever an action can be a "chargable" event. For example, if the user can create two instances on the "beginner" plan, but 10 on the "pro" plan, then your backend should be keeping track of the number of instances in use for this customer.

  8. 1
    1. anything else will be horrible performance for the end user waiting on unnecessary remote calls.
    1. 1

      Right, I thought about this too. Thanks!

Recommended Posts