Move to a "Product Variant" architecture #4838
Replies: 1 comment
-
Great write-up as always @frankie567. I think this makes a lot of sense and really like the approach and solutions to ensure this larger change would not break backward compatibility and your proposed solutions there. I'd love to mull it over though over the weekend given the scope of the change. The concept around an alternative Need to wrestle a bit to settle on this in my mind over the weekend. But feeling 99.9% confident your write-up is the right approach here :) |
Beta Was this translation helpful? Give feedback.
-
In our discussions related to usage-based billing, we are considering to change how Product / Price and Benefits are articulated. In particular, we are interested in implementing a "Product Variant" approach. Besides, this is quite a common request, so this would also address this kind of use cases.
Current state
Currently, a
Product
is linked to one or severalProductPrice
and to someBenefit
.When a customer buys a
Product
, we create anOrder
and aSubscription
linked to thatProduct
and selectedProductPrice
. We also grant them theBenefit
linked to that product.Limitations
While simple, this has some limitations. In particular, it's not possible to have specific benefits following the pricing. Typically, a yearly pricing may grant some bonus benefit as a nudge to subscribe for longer periods. The current workaround is to create several Products, with the drawback that you need to repeat the title, description, custom fields and such. We already had complains it's not really practical.
Also, it's hard to come up with a "variant selection" screen at checkout, where we could nudge the customer to go for a more expensive pricing or longer engagement periods. It works for monthly/yearly, but it's more a specific use-case handled specifically than a generic behavior.
Proposal
To solve those limitations, we propose to add another layer which is commonly referred in the industry as "Variants". Personally, I don't really like that name, but we probably should follow the trend to be easily understandable.
In this new architecture, a
Product
would be tied to one or severalProductVariant
. TheProductPrice
andBenefit
would move toProductVariant
. Thus,Product
would only consist of a title, a description and the custom fields configuration (we could discuss that last point, but I think it makes sense).The key thing in this approach is that a
ProductVariant
can be only be tied to 1ProductPrice
1. It means that, monthly/yearly pricing would be handled by two variants: one with a monthly period pricing and another one with a yearly period pricing; allowing to tweak the benefits granted.Order
andSubscription
would now be tied to theProductVariant
instead of theProduct
.By doing this, a
Product
can have an indefinite amount of pricing schemes, each one granting its own set of benefits.Limitations and quirks
The main drawback with this approach is that it forces you to repeat the set of common benefits for each
ProductVariant
. SinceBenefits
are configured on their own, I think that's kinda OK (it's just a toggle to click on / an ID to pass). We may even solve that with a clever UI without having to tie commonBenefit
to theProduct
itself, which would be quite messy.Another thing is more of a "bad-usage risk". Indeed, with an approach like that, it could be easy for a user to create a mega
Product
with all their tiers inside, e.g.:I don't really know if it's a bad thing, but that something we should be prepared for.
Migration challenges
ProductVariant
for eachProduct
, copying the pricing and Benefitsproduct_price_id
so they are tied to aproduct_variant_id
Backward-compatibility challenges
There a few things that would pose backward-compatibility problems.
1. Checkout Session and Checkout Links
Currently, we can create a Checkout Session / Checkout Links by setting either a
product_id
or aproduct_price_id
.With this new approach, I propose we do the following:
product_id
: take the first available variant, and automatically propose the other variants in the checkout UIproduct_variant_id
. We might also want to introduce a parameter to allow/disallow switching variants in the checkout UIproduct_price_id
. Still support it at first (i.e. translate to a variant), but recommend to migrate toproduct_variant_id
2. Order and Subscription
Currently,
Order
andSubscription
exposeproduct_id
in their API output. They should now outputproduct_variant_id
. For backward compatibility (but also for DX), continue to exposeproduct_id
, which should be fairly easy to get from the variant.Feedback and requests
Have some feedback or specific requests regarding this proposal? Feel free to share it with us 👇
Footnotes
To be more exact, one active price and potentially a list of archived prices ↩
Beta Was this translation helpful? Give feedback.
All reactions