Cashier-stripe: Move stripe customer to separate model

Created on 2 Aug 2018  ·  12Comments  ·  Source: laravel/cashier-stripe

Rather than modify an existing model (e.g. users, etc), we create a new model - StripeCustomer which can then have a polymorphic relation to any model. Subscriptions then would be related to the StripeCustomer. A new IsStripeCustomer trait could then implement the relation back to the StripeCustomer.

So, an Uber clone could make multiple models billable very easily, e.g. Drivers, Passengers, Companies

This would have the benefit of:

  • Reduce the configuration required, just add the trait to a model and voila. No need to modify your model, etc.
  • Once the StripeCustomer is abstracted, would make it (logically) easier to add a StripeAccount trait which would do a similar thing but to support stripe custom accounts
  • Makes it easier to trigger Stripe requests with queue, because you just need to queue things from StripeCustomer not from a number of different models
  • Webhooks only need to reference and update one model

The downsides:

  • none that I can think of, maybe a bit more complexity / challenge to maintain?
enhancement

Most helpful comment

FYI: we've implemented support for this into Cashier Paddle: https://github.com/laravel/cashier-paddle/pull/18

We're considering doing this for Cashier Stripe as well maybe but the breaking change would be quite big.

Edit: I sent in a follow up PR to make subscriptions polymorphic as well. Because Laravel lacks a ManyToMorph relationship we need to solve it like this. Ideally the retrieval is done through the Customer table.

All 12 comments

Hmm, this is interesting but unsure how complicated this will get. I'll ping @taylorotwell to see what he has to say.

Any progress?

Thanks.

I quite like the idea of this. I have two applications that are “multi-sided marketplaces”:

  1. A video on demand site where my customers connect their Stripe accounts to offer subscriptions/rentals to their customers.
  2. A multi-tenant CMS where my customers subscribe to use the service, but can also connect their own Stripe accounts to add e-commerce functionality to their websites.

You could just alter the migrations after publishing them, and created an accounts or customers table, that has a polymorphic relationship to the "accountable" or "customerable" relationship (user, organization, etc.). Each account would have your stripe_id, card_brand, card_last_four, trial_ends_at etc.

+1 for this being considered as it affects any application that has multiple models with subscriptions.

@logan-jobzmall Have you had success with this method? There are specifically some methods in Billable that I think would need to be overwritten. Then, do you include Billable direct on the user or on your "accounts" model?

@coryrose1 You have to add Billable directly to the account model. The only thing you have to figure out is where the email comes from (that is cashier creates stripe customers). You could add the email to the account model, or attach another "contactable" polymorph to the account model, and return that "contactable"'s email to to the getEmailAttribute on the account model

@logan-jobzmall Brilliant, thank you

I guess my use case would fit in this Issue. I have Users that have N shops, and each of these shops have a Subscription. User pays for those subscriptions, so he does not have a Subscription himself but shops do.

@gerardnll can't you proxy those subscription calls then through the linked user in your Shop model?

@gerardnll Did you find a solution for this? I'm looking for something similar where (in this example) the shops have for example bronze, silver and gold plans. Each plan unlocks more features for the shop.

I've just had a brief chat with Taylor about this and this is definitely something we can consider. However, it would probably be something we'd implement ourselves so we can have a thorough thought about how we'd like to see this implemented. When that'd be we don't know but in the meantime feel free to leave any ideas about this or provide this as a third party implementation. Thanks all.

FYI: we've implemented support for this into Cashier Paddle: https://github.com/laravel/cashier-paddle/pull/18

We're considering doing this for Cashier Stripe as well maybe but the breaking change would be quite big.

Edit: I sent in a follow up PR to make subscriptions polymorphic as well. Because Laravel lacks a ManyToMorph relationship we need to solve it like this. Ideally the retrieval is done through the Customer table.

Was this page helpful?
0 / 5 - 0 ratings