3 ms·
We just did this for our own SaaS. Our backend is Django and we use djstripe[0] to connect to Stripe. The model is as follows: A user pays per site (he can add
by bartkappenburg 8y ago
We just did this for our own SaaS. Our backend is Django and we use djstripe[0] to connect to Stripe.
The model is as follows:
A user pays per site (he can add multiple) and we decided to have all features available to all plans except for pageviews (we supply a search service like Algolia, but better ;-), and a notification service (small persuasive popups) for e-commerce).
We tie a so called 'module' to a site. A module has a product, start date, end date and subscription (FK). When a user signs up he can start a trial for a specific product which in effect creates a module with a start date, end date (now() + trial_length) and an empty subscription (ie. no subscription means trial).
In our middleware we check if a user wants to view a specific page from a product and we allow/deny access based on having a valid trial (now < end_date). We have jobs running that check which trials have ended and we suspend serving the javascript (which you need to have the service on your site).
After the trial we redirect to a plan picker (but you can still see reports for instance) and let them choose a plan. All plan meta data comes from Stripe as single source of truth (it sits actually in our db because dj-stripe has cached that using sync and webhooks).
Choosing a plan does the whole CC flow and when we get an OK from Stripe we attach a subscription (payment tied to a plan) to the module and delete the end_date. We set the limit in pageviews and check on the usage every minute using a job. The current usage is also communicated to the customer.
The same check we did with the trial is in place to see if a customer has an active subscription (now < end_date) and if the current_usage < usage_limit.
Upgrading and downgrading is easy: tie a new plan to the subscription and Stripe handles the rest (prorate, new invoice).
Canceling is easy as well: cancel call to Stripe, get the returned end_date and set this on the module.
You also have to think about reactivating the subscription (before the cancelled subscription has ended).
A fews things to consider:
- VAT: we're based in the Netherlands, so we have 4 (2x2) cases: Individual/Company and EU/Non-EU. Based on that we have to charge or charge no VAT, you have to add that yourself in your call to Stripe.
- Expired CC, declined payments: Stripe calls a webhook and you have to handle that in a way that it will (a) change the subscription/module (b) tell the customer
Our model also allows for:
- old/defunct pricing plans by setting the subscription to an old plan
- different/special usage limits for clients using special plans
- payment without CC (e.g. bank transfer) by using out_of_band option on Stripe
[0] https://github.com/dj-stripe/dj-stripe https://github.com/dj-stripe/dj-stripe
- tnolet 8y agoCool stuff! Checkly is also a dutch company, although I live in Berlin. I will do a write up soon too on how we deal with Stripe and EU taxes. I found it not THAT hard as people make it out to be.