Stripe Subscription
Sell products as recurring subscriptions with Stripe
A channel aware plugin that allows you to sell subscription based services or products through Vendure. This plugin was made in collaboration with the great people at isoutfitters.com.
- Vendure Stripe Subscription plugin
How it works
- A customer orders a product that represents a subscription
- During checkout, the customer is asked to pay the initial amount OR to only supply their credit card credentials when no initial payment is needed.
- After order placement, the subscriptions will be created. Created subscriptions will be logged as history entries on the order.
The default strategy defines subscriptions in the following manner:
- The product variant price is used as monthly price
- The customer pays the initial amount due during the checkout
- The subscription will start one month after purchase, because the first month has been paid during checkout.
You can easily define your own subscriptions with a custom subscription strategy.
Installation
- Add the plugin to your
vendure-config.tsplugins and admin UI compilation:
- Start the Vendure server and login to the admin UI
- Create a payment method and select
Stripe Subscriptionas handler - Fill in your
API key.Publishable keyandWebhook secretcan be left empty at first. - Save the payment method and refresh the Admin UI screen.
- The
Webhook secretfield should now have a value. This means webhooks have been created in your Stripe account. If not, check the server logs. - You can (and should) have only 1 payment method with the Stripe Subscription handler per channel.
Storefront usage
- On the product detail page of your subscription product, you can preview the subscription for a given variant with this query:
- The same can be done for all variants of a product with the query
previewStripeSubscriptionsForProduct - Add the item to cart with the default
AddItemToOrdermutation. - The subscriptions in the active order can be viewed by fetching subscriptions on an order line:
- Add a shipping address and a shipping method to the order (mandatory for all orders).
- You can create
createStripeSubscriptionIntentto receive a client secret. - :warning: Please make sure you render the correct Stripe elements: A created intent can be a
PaymentIntentor aSetupIntent. - Use this token to display the Stripe form elements on your storefront. See the Stripe docs for more information.
- The customer can now enter his credit card credentials.
- Vendure will create the subscriptions in the background, after the intent has successfully been completed by the customer.
- The order will be settled by Vendure when the subscriptions are created.
It's important to inform your customers what you will be billing them in the future: https://stripe.com/docs/payments/setup-intents#mandates
Retrieving the publishable key
You can optionally supply your publishable key in your payment method handler, so that you can retrieve it using the eligiblePaymentMethods query:
Custom subscription strategy
You can define your own subscriptions by implementing the StripeSubscriptionStrategy:
You can then pass the strategy into the plugin during initialization in vendure-config.ts:
Custom subscription inputs
You can pass custom inputs to your strategy, to change how a subscription is defined, for example by having a selectable start date:
- Define a custom field on an order line named
subscriptionStartDate - When previewing a subscription for a product, you can pass a
subscriptionStartDateto your strategy:
- In you custom strategy, you would handle the custom input:
- When adding a product to cart, make sure you also set the
subscriptionStartDateon the order line, so that you can access it in thedefineSubscriptionmethod of your strategy:
Multiple subscriptions per variant
It's possible to define multiple subscriptions per product. For example when you want to support down payments or yearly contributions.
Example: A customer pays $90 a month, but is also required to pay a yearly fee of $150:
Caveats
- This plugin overrides any set
OrderItemCalculationStrategy. The strategy in this plugin is used for calculating the amount due for a subscription, if the variant is a subscription. For non-subscription variants, Vendure's default order line calculation is used. Only 1 strategy can be used per Vendure instance, so any other OrderItemCalculationStrategies are overwritten by this plugin.
Additional features
Canceling subscriptions
You can cancel a subscription by canceling the corresponding order line of an order. The subscription will be canceled before the next billing cycle using Stripe's cancel_at_period_end parameter.
Refunding subscriptions
Only initial payments of subscriptions can be refunded. Any future payments should be refunded via the Stripe dashboard.
Payment eligibility checker
You can use the payment eligibility checker has-stripe-subscription-products-checker if you to use a different payment method for orders without subscriptions. The has-stripe-subscription-products-checker makes your payment method not eligible if it does not contain any subscription products.
The checker is added automatically, you can just select it via the Admin UI when creating or updating a payment method.
Contributing and dev server
You can locally test this plugin by checking out the source.
- Create a .env file with the following contents:
- Run
yarn start - Go to
http://localhost:3050/checkoutto view the Stripe checkout - Use a Stripe test card as credit card details.
- See the order being
PaymentSettledin the admin.
Changelog
- Upgraded to Vendure 3.5.3
- Documentation update
- Updated official documentation URL
- Don't throw errors for subscription with $0 amount.
- skip intent processing in handleIntentSucceeded if order is already PaymentSettled
- Upgrade to Vendure to 3.3.2
- moved default
['card']paymentMethods andsetup_future_usage: 'off_session'fromStripeSubscriptionService.createIntentByOrderand move it into thecreateStripeSubscriptionIntentresolver - BREAKING CHANGE:
StripeSubscriptionService.createIntentByOrder,StripeSubscriptionService.createIntent, andStripeSubscriptionService.createIntentForDraftOrdernow requires apaymentMethods: string[]andsetupFutureUsageargument; update all calls to pass your desired default (e.g.['card'])
- Don't validate webhook secret, but call Stripe API directly to get valid data.
- Skip job queue for subscription creation, but create synchronously instead, for direct feedback.
- Updated Stripe package to v17.7.0
- Update Vendure to 3.1.1
- Don't throw error while resolving
PaymentMethodQuote.stripeSubscriptionPublishableKeyif the stripe subscription publishable key is absent (#452)
- Update compatibility range (#480)
- Fix Vendure crash on payment method with "just" enabled: true/false update
- Updated Vendure to 2.2.6
- Refactored subscription logic into helper, to make it reusable between Accept Blue and Stripe plugin
- Remove
activecheck for admin API create Payment Intent asDraftorders are not the same asactiveorders and there is no adequate way to manipulate theactivestate directly.
- Allow admin API to create Payment Intent based on specified orderId, since there is no concept of an
activeOrderfor an admin
- Return empty array instead of throwing an error for variants that are not subscriptions
- Made
isSubscription()async and passed an instance ofInjector, so that consumers can fetch additional relations insideisSubscription(); subscriptionHashcustom field was removed: The plugin doesn't need an order line per subscription per se.
- Correctly calculate line price sum when multiple subscriptions are returned
- Extended the admin-api to include all of the same methods as the shop-api for Stripe subscription
- Extended the
HistoryEntryListenum to make stripe subscription custom history entry component work
- Return subscriptions per order line on orders
- Updated vendure to 2.1.1
- Major refactor: (#260)
- Scheduling has been taken out of this plugin.
- By default product variants are seen as monthly subscriptions
- Custom subscriptions can be defined by implementing the SubscriptionStrategy interface
- Expose proxy function to retrieve all subscriptions for current channel (#255)
- Fixed selecting schedules on a variant (#253)
- Expose Stripe publishable key via
eligiblePaymemtMethods.stripeSubscriptionPublishableKey(#242)
