Subscriptions Recipe
This recipe provides the general steps to build subscription-based purchase with Medusa.
Overview#
Subscription-based purchase allows customers to purchase products for a specified period, and the payment and fulfillment is processed within a regular interval in that period.
For example, a customer can purchase a book subscription box for a period of three months. Each month, the payment is captured for that order and, if the payment is successful, the fulfillment is processed.
Medusa's Framework for customizations facilitates building subscription-based purchases. You can create a Subscription Module that implements data models for subscriptions, and link those data models to existing ones such as products and orders.
You can also expose custom features using API routes, and implement complex flows using workflows.
Save Subscription Details#
Subscriptions have details related to the subscription interval, subscription period, and more.
To store the subscription details, you can create a data model in a new subscription module. The module's main service provides data management feature of the data model.
You can link the subscription data model to models of other modules, such as the Order Module's Order
data model.
Link Subscription to Existing Data Models#
Define a module link that links a data model from your subscription module with a data model from another module.
For example, you can link the subscription data model to the Order Module's Order
data model.
If you want to create subscriptions on the product level, you can link the subscription data model to the Product Module's Product
data model.
Implement Subscription Approach#
There are different ways to implement subscriptions in your Medusa application. This recipe covers two options.
Option 1: Custom Subscription Logic#
By implementing the subscription logic within your application, you have full control over the subscription logic. You'll also be independent of payment providers, providing customers with more than one payment provider.
Implementing the logic depends on your use case, but you'll mainly implement the following:
- Create a workflow that completes a cart and creates a subscription for the order.
- Create an API route that executes the workflow.
- Create a scheduled job that checks daily for subscriptions that need renewal.
- Create another scheduled job that checks daily for subscriptions that are expired.
Option 2: Using Stripe Subscriptions#
Stripe provides a subscription payments feature that allows you to authorize payment on a subscription basis within Stripe. Stripe then handles checking for recurring payments and capturing payment at the specified interval.
This approach allows you to delegate the complications of implementing the subscription logic to Stripe, but doesn't support using other payment providers.
Although Medusa provides a Stripe Payment Module Provider, it doesn't handle subscriptions. You can create a custom Stripe Subscription Module Provider instead.
Customize Admin Dashboard#
Based on your use case, you may need to customize the Medusa Admin to add new widgets or pages.
For example, you can create a page that lists all subscriptions or a widget that shows an order's subscription information.
The Medusa Admin is an extensible application within your Medusa application. You can customize it by:
- Widgets: Adding widgets to existing pages, such as the order page.
- UI Routes: Adding new pages to the Medusa Admin, such as a page to manage subscriptions.
- Settings Pages: Adding new pages to the Medusa Admin settings, such as a page to manage subscription settings.
Customize or Build Storefront#
Medusa provides a Next.js Starter Storefront to use with your application. You can customize it to for your subscription use case, such as allowing customers to manage their subscriptions.
Alternatively, you can build your own storefront using the Medusa APIs. This headless approach gives you the flexibility to build a custom storefront without limitations on which tech stack you use, or the design of the storefront.