Not the OP, but anybody who has built a deep integration with any billing provider (inclusive of Stripe) knows there are some bodies buried, although you typically don't discover them until you're late in the game.
90% of your use cases are covered, and with excellent UX and docs to boot. But that sweet 10%!
---
For a concrete example, Stripe has a very nice "subscription" abstraction that makes it easier to operate a SaaS business. They also offer a nice "tax" product, that doesn't do filing for you, but does offer tax computation if you code your products appropriately. Sounds great!
But if you want to sell 2 subscriptions to the same customer, and those 2 subscriptions are fulfilled in 2 distinct taxable regimes (say, you're shipping widgets to NYC once per month and to a vacation home in NH once per quarter), you're screwed because Stripe only allows 1 shipping address for customer for tax purposes, and each subscription references this address when computing tax.
We went through support, which filtered through to engineering, and the eventual answer was "no plan to change this anytime soon", which is difficult to interpret any other way than "good luck". :)
There is no clean or even acceptably-dirty solution to this problem, tragically. So as a business we can't allow customers to transact with us this way. Oh well.
There's another, similar, story around creating draft invoices to give people quotes before checking out. The dashboard API has a function to modify the line items of a draft invoice, but it's not a public-facing API and there's no short-term intention to make it public-facing, so one has to build an ugly workaround.
This effectively means one needs to maintain internal models for subscriptions, products, taxes, invoices, invoice items, products, shipping addresses, on and on. And Stripe becomes a somewhat-dumb processor for these models (although the state machine for subscriptions is admittedly very valuable).
I'd love to "offshore" everything to Stripe, status as the source of truth for data included, but it's not feasible in a surprising frequency of scenarios.
Caveat that every payment provider is like this, Stripe is much better and actually improves over time.
A lot of the time there’s trade-offs that can be made that engineers don’t even consider because they’re not pure. For example, why do you need a one-to-one relationship between your customers and Stripe customers? I am guilty of it myself, where an 80% solution is unacceptable from an engineering perspective but, actually, when balanced against the cost of building out a perfect solution, the business may well find it very acceptable.
One of the most important things I’ve learned about working with third-party systems is that there has to be some amount of surrender to their way of doing things. Essentially, the price of using Stripe is not being able to use invoices as a quote, and that has to be articulated to the business. If that’s not acceptable, then the business should be considering the requirements in aggregate when evaluating a solution, rather than deciding on Stripe and then gradually re-implementing parts of Stripe internally because they aren’t right for the business.
(Obviously that’s easier said than done, and for engineers it’s a fun challenge to make something impossible possible, but it’s almost always a mistake and as engineers it’s our responsibility to articulate the burden of owning workarounds.)
The example you give is a smart one that we did explore!
Effectively, relationship is no longer user -> stripe customer, but user -> shipping_address -> stripe customer.
We decided the cost of implementing and maintaining this solution wasn't worth the benefit to the business. A credit to your later points.
We came up with a solution that allows us to ship one-off things to arbitrary addresses with correct tax calculation, and if a customer really wanted to setup a subscription to a distinct address, we could implement it in the future, hackily, with this primitive.
>One of the most important things I’ve learned about working with third-party systems is that there has to be some amount of surrender to their way of doing things. Essentially, the price of using Stripe is not being able to use invoices as a quote, and that has to be articulated to the business.
We have this same limitation on another payment platform. We just change the concept on our end to "payers" and allow an account to have multiple payers. When the user adds a payment method, they can either select that existing payer or, if they need to change the name or address, they create a new one.
The provider we use had an invoicing product, but it has several misfeatures that just make the product unworkable. We absolutely have to be able to enforce first-in-first-out invoice payments. Users will pay the May invoice before the April invoice and pretend like they are all paid up. I'm not sure why they didn't consider this with a subscription-invoice product... users paying the invoices out of order was a big problem because users saw it as an exploitable vulnerability they could use to get a free month here and there.
> There's another, similar, story around creating draft invoices to give people quotes before checking out. The dashboard API has a function to modify the line items of a draft invoice, but it's not a public-facing API and there's no short-term intention to make it public-facing, so one has to build an ugly workaround.
There is a similar "not a public-facing API" limitation with configuring multiple invoice email addresses for Stripe customers (works in the dashboard, but blocked in the public API, where you can only set a single email per customer).
I'm actually quite surprised Stripe does this, since their initial reason for being was developer-friendly payments. But oh well, maybe I should take a look at an alternative (like Lago) sometime.
We're working on making the quoting process simpler indeed.
What we've learnt that the only companies that can afford a proper quoting system are enterprises: they implement Salesforce CPQ (configure price quote) or Zuora. They are mostly sales-driven, so the investment is worth it.
But it does not make sense for PLG companies, who start with self-serve and layer sales afterwards: the investment is not worth it, and it creates 2 different systems: self-serve and sales-driven billings, not great for the user experience (and for the internal processes!)
I think it's easier for billing systems to have 1 subscription for 1 customer. The reason behind this is mainly because you can apply several prices to the same feature belonging to two different subscriptions. Stripe does not work on it because they might consider this as a edge case.
When you look at usage-based billing, even if a billed feature is linked to consumption, it needs to be related to a subscription given the fact that this feature can be priced differently for several plans. Every company has a singular pricing model in mind and it's hard to have an all-in-one model fitting all the needs.
Even when we built internally the whole system for a fintech back in 2016, we had some edgecases creating conflict inside the company.
But I'd push back on the 1 subscription per customer idea. Consider any physical fulfillment business, where you have an optional annual membership (amazon prime, costco, whatever) and N subscriptions of varying frequencies for physical products.
It doesn't make sense to roll these into a single subscription on the backend (unless the periodicity happens to line up perfectly, and even then there's a heated debate, since you still probably want them to be separate charges).
You can go down the route of creating N "virtual" customers for each "real" customer, but it doesn't really solve the problems, because these N customers have a complex relationship with each other that you need to encode and manage.
Hence, the name of this post :). It's definitely not easy!
This is what I’m doing, but then you don’t get a clean history in Stripe, which is annoying to folks (e.g. to our support team). So, it’s something I’m thinking about changing.