Developing On Stripe: Easy to Start; Hard To Get Right
Jul 22 2015
NOTE:This post is a bit different than our normal content, and comes from the ProfitWell product team to give you a look inside how we’re building the most accurate SaaS metric tool on the market.
When we started building ProfitWell, the team agreed on one very clear goal above all else: perfection when it came to the accuracy of your SaaS metrics.
After all, unlike a marketing analytics app where there’s some flexibility in accuracy when reporting clicks or visits, if we tell you your MRR is $136,712, it better be $136,712 and not a dollar more or less.
Stripe’s beauty in being the most flexible and easiest to use payment processor out there means that developing on the platform has moments of infuriating agony in handling hundreds of edge cases. That’s ok though, because we’re here to make this feel like absolute analytics magic and be that guardian of accuracy.
To help everyone understand why that commitment to accuracy takes the dedication of a monk though, let’s walk through some of the agony it took to get to “one click SaaS metrics” magic.
Stripe is a Payments Processor not a SaaSPayments Processor
Stripe didn’t set out to corner the SaaS/subscription payment processing market like Recurly or Zuora. Instead, their ultimate goal was to be the easiest and most flexible tool to handle payments out there for anyone. This lead to folks utilizing Stripe to handle their payments for anything from ecommerce transactions and charity donations to our darling SaaS recurring revenue.
The flexibility causes problems though, because everyone uses Stripe a little differently. Take applying a discount to a customer, for instance — something you’d think would be exceptionally easy. The best practice is to utilize Stripe’s discounting functionality to apply a discount to that particular customer and their transaction.
Yet, in looking at around 20% of Stripe’s SaaS market (our ProfitWell users), some people instead add a negative invoice item to a customer’s invoice. Others will manually add cash to a customer’s account to account for the discount. Others still use another five different ways all to do the same thing.
Obviously if you’re using an analytics platform, you don’t (and shouldn’t) care how the calculation gets done. Yet, from a development standpoint this means with every new user we’re running through different QA scripts and internal checks to ensure we’re handling all of these edge cases appropriately.
Stripe’s API has changed steadily over time
As most innovative companies do (and should do), Stripe’s product has changed over time with the addition of more and more features and functionality. This has caused similar problems to development, as companies who implemented Stripe 3 years ago differ in their makeup than those who implemented Stripe 6 months ago.
For example, Stripe didn’t support a customer being on two different subscriptions until February 2014. This was a great piece of functionality, but made it tricky to identify subscriptions that began before February 2014 and continued after because the entire unique identifier of each subscription changed and shifted.
This means anyone building on Stripe needs to not only account for flexibility in implementation, but also shifts in Stripe’s functionality, which creates another set of risks to our ultimate goal of accuracy.
Stripe has multiple places to pull from for similar data
The main reason there’s been a plethora of “SaaS analytics for Stripe” companies popping up so quickly is because Stripe does make it exceptionally easy to calculate your most basic metrics with a few lines of code. The problem comes when you start to get a bit more complicated with your calculations and want to ensure supreme accuracy.
This is because the easiest way to calculate your metrics is to look at the invoice and charge data that Stripe generates. Yet, that charge data is extremely error prone and doesn’t tell you SaaS data in real time. For instance, if a user downgrades on the 15th of the month, but aren't billed until the 30th, most Stripe tools won't show that downgrade until the 30th of the month. In other words, they have no way of knowing what happens between invoices.
Because we chose the more complicated (but more accurate) route, we’re able to tell you that user is going to downgrade immediately on the 15th. In order to do this (and calculate many other metrics), we ingest 5x the data of anyone else on the market, which brings it's own set of complexities when it comes to parsing the data and serving you your metrics in real time.
There’s no Defined SaaS Metric Playbook
Beyond the technical challenges of building on Stripe, a business challenge exists in the fact that Stripe gives you the fire hose of billing data, which you then need to parse through and make some hefty decisions on calculations. There isn’t (yet) a SaaS GAAP standard for things like churn, MRR, refunds, etc., which means this can be tricky.
A good example of this is determining when a user officially churns. Some folks believe that a user should “churn” when they officially say “I’m cancelling.” This is wrong though, because technically they’ve paid for that full month or term of subscription and therefore should still count in your MRR numbers. There’s value in knowing that person’s about to churn though, so visually you need to set up a good mental framework to make sure all of this information is funneled to users when it makes the most sense.
Overall, Stripe’s a beautiful platform on which we love building (we have the Stripe laptop stickers to prove it :)). Yet, like building on any platform there’s definitely plenty of challenges to work through to make sure we’re fulfilling that goal of being the most accurate out there. If you’re ever looking for any advice on building on Stripe, feel free to reach out. We’re always up for helping.
Also, we’re hiring if you want to come join the crew. :)
By Eric Yu
Software Engineer at ProfitWell, building tools to grow subscription companies. When he's not building tools for ProfitWell, you can find him drinking too much iced coffee at his local coffeeshop.