Tutorial: Calculating your Stripe monthly recurring revenue (MRR)
I love Stripe (the customer payment solution I advocate using in Hello Web App: Intermediate Concepts), but I wish the Stripe's dashboard came with a bit more information about the state of your project and revenue.
In particular, I wish it had MRR (monthly recurring revenue), which is a good indicator of health for your app's revenue. For WeddingLovely, my wedding planning and vendor marketplace app, I have people on monthly and (mostly) yearly subscriptions, not to mention a lot of folks with discounts. Calculating MRR just based on the number of customers I have would be fairly inaccurate. So I need to query Stripe and calculate MRR based on the subscriptions and discounts applied to my actual customers, and I wrote a script to do this.
Note: This does not comply with generally accepted accounting principles, so don't use this for your accounting. It's just a quick estimation of your Stripe subscriptions.
Prerequisites: Django app with an active Stripe account (with the Stripe Python library installed), with at least a few active customers (can be test data).
I recommend reading Hello Web App: Intermediate Concepts's Stripe chapter if you're looking to learn how to tie in Stripe to your Django app.
The necessary bits of code to calculate and return MRR:
# Import me at the top. import stripe from django.conf import settings stripe.api_key = settings.STRIPE_SECRET # Grab all your customers from Stripe. # I have about 200 customers so I set the limit to 50 - the # default is 10. stripe_customers = stripe.Customer.list( limit=50, expand=['data.subscription'], ) # The results are auto-paginated, so you need to loop over # the pages. for customer in stripe_customers.auto_paging_iter(): # Grab the subscriptions for the specific customer. subscriptions = customer.subscriptions # Start tracking revenue for that customer. rev = 0 for sub in subscriptions: # Year subscriptions need to be divided by 12. Update # this to match your specific subscription intervals. if sub.plan.interval == "year": rev += sub.plan.amount / 12.0 elif sub.plan.interval == "month": rev += sub.plan.amount # If your customer has a coupon attached, make sure to take # that into account for your revenue. if customer.discount: percent_off = customer.discount.coupon.percent_off discount = rev * (percent_off / 100.0) rev = rev - discount # Add this customer's revenue to your total. monthly_rev += rev # Total monthly revenue, divided by 100 because Stripe gives # revenue in cents monthly_rev = monthly_rev / 100
This looks deceptively simple, but it took me a couple of hours to figure out that I need to loop over the results returned from Stripe, and that I can't
len(stripe_customers) because it actually isn't a simple list (It'll always return
4 because that's the number of keys in the underlying dict structure.)
The Django management command:
Here's my full script if you'd like to copy my Django management command that has nice printouts and whatnot. There is also a chapter on scripts in Hello Web App: Intermediate Concepts if you're interested in learning more!
import stripe from django.conf import settings from django.core.management.base import BaseCommand stripe.api_key = settings.STRIPE_SECRET class Command(BaseCommand): def handle(self, *args, **options): monthly_rev = 0 stripe_customers = stripe.Customer.list( limit=50, expand=['data.subscription'], ) print "------" for customer in stripe_customers.auto_paging_iter(): print "Profile: %s" % customer.description subscriptions = customer.subscriptions rev = 0 for sub in subscriptions: print "Interval: %s" % sub.plan.interval if sub.plan.interval == "year": rev += sub.plan.amount / 12.0 elif sub.plan.interval == "month": rev += sub.plan.amount else: print "ISSUE" if customer.discount: percent_off = customer.discount.coupon.percent_off discount = rev * (percent_off / 100.0) rev = rev - discount print "Rev with discount: %f (%f off)" % (rev, percent_off) else: print "Revenue: %f" % rev monthly_rev += rev print "Total revenue now: %f" % monthly_rev print ">" print "------" # because Stripe gives us revenue in cents... monthly_rev = monthly_rev / 100 print "MRR: $%f" % monthly_rev
After all this work, I figured out that WeddingLovely's MRR is $1568.25. Not bad, not bad at all.
Go forth and conquer with your new datapoint for your app's health!
Update: Discovered Stripe's "expanding objects" feature on API calls, so we can grab subscriptions as well when we're making the API call for customers, so we don't have to do additional API calls.