Sorry about the title, I'm not sure it could have been worst. Yet this post is just that, a continuation of a post name "Stripe integration unanswered questions".
The first version of this post is linked below and provides some amazing insights (that you can hardly find anywhere else on the internet) for everyone that is looking to integrate stripe.
https://www.indiehackers.com/post/stripe-integration-unanswered-questions-5c19e25f4d
The original post was focused more on the general architecture of Stripe in a SaaS product. This post is meant to focus on one particular problem that 45 minutes on Google led to nowhere.
That is, "How to have a free member plan in your paid service?".
Q1. Should you keep the stripe customer plan state on your database or request it directly from stripe? Requesting it with every call introduces an unwanted latency while having a duplicate plan record in the database frees out all headaches of updating it when a payment fails or when the user changes plan etc. For this I'm thinking of an intermediate cache on the frontend (maybe on Redux) that gets invalidated when the user plan is updated.
Q2. Should you have a restrictions sub-module in your backend or implement the restriction logic accordingly to every API call. Every sub-module has a different logic and there seems to be no code sharing among them. Having them all in a central place sounds very reasonable from a business and management perspective.
That is just an introduction, if you have any other suggestions or methodologies, tools/libraries that you used or a whole different approach to handling free members restrictions feel free to share them on this post as well.
I want to take the chance and thank again @jordin_codes @Corstian @nphaskins @manishgroverDA for their insightful comments on the first post!
A slightly related question I have been asking myself is "what information should I save in my own data store?". Ideally I want to store everything, because that makes querying all this information easier, this will however increase maintenance complexity. Currently I am only storing some basic information about the current subscription (such as start/end date and plan id), and a customer id.
Using this information I query all other information during runtime. At this moment the additional information I am querying is mostly about invoices, registered payment methods and other subscriptions.
Now back to the free plan. Initially I did not register anything with Stripe. Now however I have changed the method to directly sign the user up to a trial of a premium plan, instead of signing users up to a free plan, with the possibility to upgrade to premium with trial included. This has the benefit that users get to see the premium features without further action, instead of having the mental barrier to 'potentially' spend some money by signing up to a trial.
From a technical point of view I have implemented this by creating a subscription as soon as the user is being registered. Within the trial period I try to get the user to enter their payment information in order to convert the trial into a paid subscription. If I do not have their payment information by the end of the subscription I cancel it, and the users can continue using the product using the free plan. When an user signs up again after the trial has ended, I check whether the user has a cancelled subscription for the plan, in order to prevent the user from having another trial period. Information on the back-end is primarily updated by relying on web hooks, and based on this the API almost instantly reflect changes made within Stripe.
Within the front-end I load an object with user information which contains info about the current subscription, but also some information about the user's access rights.
If interested I can do a write up about the combination of GraphQL, user authorization, subscription status and role base access control (RBAC). Simply put, the API only returns the data the user has access to in order to prevent roundtrips for questions like 'do I have access to this resource?'.
I would love another one of these! I might collate all this information and put it somewhere useful for us indiehackers.
Thanks for the shout Andreas!
Hope this helps! Happy to answer questions.
"How to have a free member plan in your paid service?".
I agree - your application does not need to do anything with stripe regarding free users. Just let them access the app.
I think you are asking how your application will know if a user is paid or not so you can give them access to a specific service or specific page. Generally I put a enumerated column called "account_type" in the users table with the options: "free", "standard", "pro", or something like that. Then the application can just check the session data to determining which user is currently logged in, and if they are a paid user or not. This way you minimize the number of api/db calls.