VulcanJS / Vulcan

🌋 A toolkit to quickly build apps with React, GraphQL & Meteor
http://vulcanjs.org
MIT License
7.98k stars 1.88k forks source link

Vulcan Payments: better Stripe support #1893

Open SachaG opened 6 years ago

SachaG commented 6 years ago

Let's discuss adding support for subscriptions, subscription items, and invoice items.

SachaG commented 6 years ago

@justinr1234 on Slack:


I think that's the proper abstraction as we talked about I don't know though I think it makes sense to leave it all as addProduct End of the day that's the abstraction here I think we can add helper functions on top probalby addPlan and addSubscriptionItem, addInvoiceItem would basically just enforce the required items but end of the day we'd still have the same global product list to pull from (edited) then the <Checkout> component could have mutually exclusive keys:

productKey, planKey, subscriptionItemKey, invoiceItemKey but all of that would just be syntactic sugar on top of an underlying single collection for addProduct So you could theoretically only use addProduct if you didn't care where addPlan enforces currency, interval, and name addSubscriptionItem enforces requiring plan and optionally parentPlan We'd have to make some assumptions about defaults though It looks like you can't set a subscription id https://stripe.com/docs/api/node#create_subscription So we'd have to have a way to store subscription ID returned from subscribeUser in our Charges database. We'd need to write a post processing function for subscribeUser the same as processCharge. We'd have to operate under the assumption that a user can only be subscribed to a single plan once

SachaG commented 6 years ago

@justinr1234 on Slack:


So then the definition of a invoice_item or a subscription_item would be able to reference a plan instead of a particular subscription's id. A subscription id is generated when you tell Stripe to subscribe the user and looks like this: sub_CGjapA5I9xCR35

An invoice_item doesn't necessarily have to be tied to a particular subscription: The ID of a subscription to add this invoice item to. When left blank, the invoice item will be be added to the next upcoming scheduled invoice. When set, scheduled invoices for subscriptions other than the specified subscription will ignore the invoice item. Use this when you want to express that an invoice item has been accrued within the context of a particular subscription.

But I think a sane default would be to say that an invoice_item IS tied to a particular existing subscription. And again, if we go with the sane assumption that a user can only be subscribed to a plan once, we can say that the definition of an invoice_item can actually be associated with a plan:

   description: 'My Invoice Item',
   currency: 'USD',
   amount: 45000, // optional, can be specified via "properties" at runtime to allow the charge to be generated dynamically. For example, a dynamic charge could be # of hours worked in a pay period. A static charge could be a 1-time setup fee for a service.
   parentPlan: 'bronze-tier-subscription-plan',
});

A subscription_item DOES have to be tied to both a plan and an existing subscription (created when we called subscribeUser for instance). Since again the ID of a subscription is automatically generated from Stripe, we need a way to look this up. Again following with the constraint that a user can only be subscribed to a particular plan once, we could associate the subscription_item with a particular plan and then say the parentPlan field for the plan of the subscription we would then lookup in our database or even via the Stripe API. For instance we could use https://stripe.com/docs/api/node#list_subscriptions and then filter on customer for the current customer to find a subscription that matches the plan.


   plan: 'my-plan',
   parentPlan: 'bronze-tier-subscription-plan',
   quantity: 4, // optional, can be specified via "properties" at runtime to allow you to dynamically subscribe them
});```
stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.