import DocCardList from '@theme/DocCardList';
import DocCard from '@theme/DocCard';
import Icons from '@theme/Icon';
import LearningPath from '@site/src/components/LearningPath';

# Build Subscription-based Purchases

This document guides you through the different documentation resources that will help you build subscription-based purchasing in 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 will be captured for that order and, if the payment is successful, the fulfillment will be processed.

:::tip

Recommended read: [How Goodchef built subscription-based purchases with Medusa](https://medusajs.com/blog/goodchef-webbers-powering-subscriptions-with-medusas-commerce-modules/).

:::

<LearningPath pathName="subscriptions" />

---

## Save Subscription Details in the Database

Subscriptions have details related to the subscription interval, subscription period, and more.

Based on the approach you choose to implement the subscription logic (which is discussed in the next section), you might need to store different data in your backend.

If you want to store the subscription details in a new table in the database, you can do that by creating an entity. If you want to extend an existing entity in Medusa's core, such as the `Order` entity, to add details related to the subscription, you can extend an entity.

<DocCardList colSize={6} items={[
  {
    type: 'link',
    href: '/development/entities/create',
    label: "Create an Entity",
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to create an entity in Medusa.',
    }
  },
  {
    type: 'link',
    href: '/development/entities/extend-entity',
    label: 'Extend an Entity',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to extend an entity in Medusa.',
    }
  },
]} />

---

## Decide on Subscription Approach

There are different ways to implement subscriptions in your Medusa backend. This document discusses two options: using Stripe subscriptions, or implementing subscriptions logic within the backend, independent of a specific payment provider.

### Option 1: Using Stripe Subscriptions

Stripe provides a [subscription payments](https://stripe.com/docs/billing/subscriptions/overview) 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 does not support using other payment providers.

Medusa provides a Stripe plugin, however, it doesn't handle subscriptions. You can either use that plugin to add the subscription feature on top of it, or create a custom Stripe Subscription payment provider.

<DocCardList colSize={6} items={[
  {
    type: 'link',
    href: 'https://github.com/medusajs/medusa/tree/develop/packages/medusa-payment-stripe',
    label: "Use Medusa's Stripe Plugin",
    customProps: {
      icon: Icons['github'],
      description: "Check out Medusa's stripe plugin to build subscription on top of it.",
    }
  },
  {
    type: 'link',
    href: '/modules/carts-and-checkout/backend/add-payment-provider',
    label: 'Create Payment Processor',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Create a Stripe Subscription payment processor from scratch.',
    }
  },
]} />

### Option 2: Implement Subscription Logic

By implementing the subscription logic within your backend, you can have full control over the subscription logic. You'll also be independent of payment providers, allowing you to provide customers with more than payment provider option.

Implementing the logic depends on your use case, but you'll mainly need to do two things:

1. Perform an action when an order is placed, such as saving subscription details. This can be done using subscribers, which register handler functions to be triggered when an event is emitted. When an order is placed, the `order.placed` event is emitted.
2. Check daily for subscriptions that need renewal. This can be done using a scheduled job, which is a cron job that can be executed on a defined interval. Within that job, you can define your renewal logic.

<DocCardList colSize={6} items={[
  {
    type: 'link',
    href: '/development/events/create-subscriber',
    label: 'Create a Subscriber',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to create a subscriber in Medusa.',
    }
  },
  {
    type: 'link',
    href: '/development/scheduled-jobs/create',
    label: 'Create a Scheduled Job',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to create a scheduled job in Medusa.',
    }
  },
]} />

---

## Customize Admin

As you add subscription features to your store, you'll most likely need to customize the admin to provide an interface to manage these features.

Medusa's [admin plugin](../admin/quickstart.mdx) can be extended to add widgets or new blocks to existing pages, add UI routes to add new pages, or add setting pages.

<DocCardList colSize={4} items={[
  {
    type: 'link',
    href: '/admin/widgets',
    label: 'Create Admin Widget',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to add widgets into existing admin pages.',
    }
  },
  {
    type: 'link',
    href: '/admin/routes',
    label: 'Create Admin UI Routes',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to add new pages to your Medusa admin.',
    }
  },
  {
    type: 'link',
    href: '/admin/setting-pages',
    label: 'Create Admin Setting Page',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Learn how to add new page to the Medusa admin settings.',
    }
  },
]} />

---

## Build a Storefront

Medusa provides a Next.js Starter Template that you can use with Medusa. Since you've customized your Medusa project, you'll need to either customize the existing Next.js Starter Template, or create a custom storefront.

<DocCardList colSize={6} items={[
  {
    type: 'link',
    href: '/starters/nextjs-medusa-starter',
    label: 'Option 1: Use Next.js Starter Template',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Install the Next.js Starter Template to customize it.',
    }
  },
  {
    type: 'link',
    href: '/storefront/roadmap',
    label: 'Option 2: Build Custom Storefront',
    customProps: {
      icon: Icons['academic-cap-solid'],
      description: 'Find useful resources to build your own storefront.',
    }
  },
]} />

---

## Deploy Backend

Our documentation includes deployment guides for a basic Medusa backend. You should be able to follow it to deploy your customized backend, as well.

<DocCard item={{
  type: 'link',
  href: '/deployments/server',
  label: 'Deploy Backend',
  customProps: {
    icon: Icons['academic-cap-solid'],
    description: 'Learn how to deploy your subscription-based backend to different hosting providers.',
  }
}} />

---

## Additional Development

You can find other resources for your development in the [Medusa Development section](../development/overview.mdx) of this documentation.
