We've recently pushed some changes to the Report URI billing processes that will result in a better experience for our users, give us less lines of code to maintain and simplify our tax handling!
What are the changes?
Before I get started, this will have no impact on existing customers in terms of their subscription or pricing, these are purely cosmetic and convenience changes. In short, we've now implemented Stripe Checkout, Stripe Customer Portal and Stripe Tax!
Stripe Checkout
We previously used Stripe Elements to build the form on our Billing page and users could also retrieve their invoice and manage their payment card directly within our site:
This was a great way to get started, definitely the preferred method back when we were getting started in 2014/2015, and it served us well for many years. More recently though, we found ourselves constantly having to tweak our implementation and then along came Strong Customer Authentication, which really required some work. We could either continue to tweak and update our implementation over time, along with the big whack of work to support SCA, or, we could hand it over to someone else and focus on what we're good at and what we want to be doing. This is where Stripe Checkout came in and our Billing page is now much simpler!
When subscribing to a plan, rather than being directed to our payment page where your Payment Card Data was captured, you're now redirected to Stripe Checkout to input your PCD instead.
You can see that Stripe manages the checkout
subdomain of our site and once you've punched in your payment details, you hit Subscribe and Stripe takes care of the rest! We handle the webhooks on our side as usual, and you're subscribed to your desired plan.
As the billing expert for our code, Michal took care of this and it resulted in quite a nice reduction in the lines of code related to billing.
We could also remove a heap of packages that were made redundant due to our migration to Stripe Checkout and that came with its own benefits too.
Stripe Customer Portal
The next consideration on our list was how to manage customer subscriptions and for this, we opted to use the Stripe Customer Portal. On our side, we were previously responsible for sending invoice emails, initiating plan upgrade/downgrade/cancellation, change of PCD, address and a few other details like Tax IDs. All of that was handled on our site, but is now handled in what we refer to as our Billing Portal.
You can click a link on our Billing page that takes you directly into the Billing Portal to do any account management that you need. Another bonus feature that we got is that Stripe provides access to all previous invoices for your account, something that we didn't previously provide in our UI. Again, as with Checkout, all we need to do is handle the appropriate webhook events and everything works as it did before but with less responsibility on our side.
Stripe Tax
Tax is definitely the least fun thing I have had to deal with as a result of running my own company. Nobody likes paying tax, but dealing with tax is even worse. Brexit made things unnecessarily harder for us (yay freedom, I guess?) as we do a lot of selling to customers within the EU and indeed around the World. I've written about our struggles with Overcoming the hurdles of VAT and VAT MOSS in the EU and even about How the EU made our website slow, but no more!
I decided to switch to using Stripe Tax purely for the simplification of everything tax related. We already had it covered, and we were doing pretty well, but again, it was a huge responsibility that fell to us to manage and nobody wants to find out what happens if you get this stuff wrong. As a brief overview, for a company selling goods into the EU, even digital services like ours, you are required to collect tax on sales to organisations or individuals located in member states at the appropriate rate and then pay those taxes to the appropriate authority. The VAT OSS scheme (previously VAT MOSS) was setup to help reduce the burden here and previously we were part of the Union Scheme as an EU member state, but now we're a member of the non-Union Scheme (yay Brexit...). Stripe has a pretty good explainer on EU VAT and the VAT OSS requirements here.
Every company selling goods and services to European customers needs to collect value-added tax (VAT), even if their business is not established in Europe.
This meant keeping track of the VAT rates of each country, and some countries have multiple VAT rates depending on where you live, updating those VAT rates when they change, validating VAT IDs against the VIES service (see the post above about why our website was running slow), collecting evidence of the location of the customer to justify the VAT rate and so, much, more. Just look at our issues related purely to VAT!
That was an insane amount of our time to be spent doing something that not only do we not enjoy, but isn't beneficial to our core product either. Stripe Tax now takes care of every single one of those issues for us and even simplifies the process of generating our VAT returns by providing an export of our tax calculations for any given quarter. The associated reduction in code on our side was also pretty great, with our VAT Rate Changer Tool weighing in itself at 1,200+ lines of code!
The Good and The Bad
There are a heap of great things we've gotten from switching from our previous method to the combination of Stripe Checkout, Stripe Customer Portal and Stripe Tax, but there are a small number of drawbacks that I think it's only fair to mention. Each of these should also be viewed as feature requests for Stripe, but none were critical enough to prevent us from migrating.
Stripe Checkout doesn't allow you to anchor a subscription to a particular date. Previously, we'd anchor all subscriptions to the 1st of the month and everybody would have their report quota reset on that day. When using Checkout, you can't set an anchor date for a subscription and instead, the subscription renews on the date the user subscribed. Stripe really need to add this functionality to Checkout.See udpate below.Stripe Checkout doesn't allow you to add a discount coupon once you're on the checkout page, the coupon needs to be added on our site before we initiate the checkout session and redirect the user to Stripe Checkout. This is a really awkward experience and defeats some of the objective of moving this stuff over to Stripe in the first place.See update below.- Stripe doesn't support the creation of coupon codes that can only be used for the purposes of a plan upgrade. Previously, we could enforce this rule ourselves but now we're using Stripe Customer Portal, coupon codes intended to reduce the price of a plan upgrade can also be used to reduce the price of a plan downgrade.
- Stripe Customer Portal needs the ability to input a 'billing email' where copies of invoices can be sent to. This is a really frequent feature request that we get, but something that isn't supported in Stripe Customer Portal and customers that used to depend on our implementation will lose access to this feature. We have reached out to them individually with information on possible alternatives.
All in all though, this has been a hugely positive move for us and was less work than us trying to implement SCA and other incoming requirements, along with any new requirements or changes that would be required in the future. To any existing customers, if you have any issues or questions, please reach out via your usual channels.
Update 17 Nov 2022: It's been awesome to see various Stripe staff reach out both publicly and privately to ask for feedback! I've crossed out one of our 'feature requests' above (#2) as it is possible to enable discount coupons in Stripe Checkout.
Very cool, Scott! Thanks a ton for the write up. I noticed one of the growth opportunities was to add discounts on the Checkout page. Not sure if you came across this param during implementation, but wanted to share: https://t.co/tgOfPwHf8R
— CJ Avilla (@cjav_dev) November 16, 2022
Update 17th April 2023: Another feature request (#1) to knock off the list, you can now set the billing_cycle_anchor
in Checkout! Docs: https://stripe.com/docs/payments/checkout/billing-cycle