A prepaid subscription is a subscription type through which customers can pay up front for a product that's delivered on regular intervals. For example, a customer might purchase a three-month prepaid subscription for coffee bags in which they pay immediately but receive three separate shipments of coffee bags over the duration of the subscription.
This guide describes how prepaid subscriptions work and some considerations for managing fulfillments for prepaid subscriptions.
## Requirements
> Note:
>
> - Most subscriptions, pre-order and try before you buy apps need to request API access through the [Partner Dashboard](/docs/apps/build/authentication-authorization/access-tokens/authorization-code-grant#ask-for-permission). We give API access to apps that are designed according to our [principles for subscriptions, pre-order and TBYB apps] (/docs/apps/selling-strategies/purchase-options#shopifys-principles).
> - Public apps that use subscriptions, pre-order or TBYB need to meet [specific requirements](/docs/apps/launch/app-requirements-checklist#purchase-option-apps) to be published on the Shopify App Store.
> - Custom apps [created in the Shopify admin](/docs/apps/build/authentication-authorization/access-tokens/generate-app-access-tokens-admin) can't use subscriptions, pre-order or TBYB because these apps can't use extensions or request access to protected scopes. If you're building a solution for a single store, then build your custom app in the Partner Dashboard.
- Your app can make [authenticated requests](/docs/api/admin-graphql#authentication) to the GraphQL Admin API.
- Your app has the `merchant_managed_fulfillment_orders` and `third_party_fulfillment_orders` [access scopes](/docs/api/usage/access-scopes). Learn how to [configure your access scopes using Shopify CLI](/docs/apps/build/cli-for-apps/app-configuration).
- You're familiar with [selling plans](/docs/apps/build/purchase-options/subscriptions/selling-plans), [subscription contracts](/docs/apps/build/purchase-options/subscriptions/contracts), and the use and setup of [delivery anchors](/docs/apps/build/purchase-options/subscriptions/selling-plans#anchors).
- You're familiar with [managing fulfillments as an order management app](/docs/apps/build/orders-fulfillment/order-management-apps/build-fulfillment-solutions).
## Prepaid subscription components
When a customer purchases a prepaid subscription from a merchant, a subscription contract and an order are created. The order contains multiple fulfillment orders which are scheduled to be fulfilled at a later time. This enables support for prepaid subscription scenarios, where a customer wants to pay up front for a product that's delivered using billing and delivery intervals.
The scheduled fulfillment dates on the fulfillment orders are determined based on the [delivery anchors](/docs/apps/build/purchase-options/subscriptions/selling-plans#anchors) that are set up on the selling plan's [`sellingPlanRecurringDeliveryPolicy`](/docs/api/admin-graphql/objects/sellingplanrecurringdeliverypolicy), as well as the `originTime` that's provided during subsequent [billing attempts](/docs/api/admin-graphql/latest/objects/subscriptionbillingattempt).
A subscription contract is the agreement between a customer and a merchant for recurring purchases over a set or undefined period of time. When a buyer purchases a prepaid subscription from a merchant, a subscription contract and an order are created.
The order contains all the items that will be sent out for the duration of the prepaid subscription. The order has multiple associated fulfillment orders that are scheduled to be fulfilled at a later time, based on the delivery anchor, interval, and interval count set on the sellingPlanRecurringDeliveryPolicy. This enables payment and sold goods to be kept in the same order, supporting accurate reporting in Shopify.
A single line in a shopping cart. After a customer completes checkout for a prepaid subscription, the order contains the line items to be sent for the duration of the prepaid subscription.
## Example lifecycle
The follow image describes an example lifecycle for a prepaid subscription:
1. The customer begins checkout. The checkout line item is a three-month prepaid subscription of coffee bags and the quantity is one.
2. The customer completes the checkout. Both a subscription contract and an order are created. The order line item is coffee bags and the quantity is three.
3. Three fulfillment orders in a `SCHEDULED` state are created and associated with the order. The fulfillment orders have the following `fulfillAt` dates:
- Fulfillment order 1: Jan 15
- Fulfillment order 2: Feb 15
- Fulfillment order 3: Mar 15
When the `fulfillAt` date for each fulfillment order is reached, inventory is committed and the fulfillment order is transitioned to the `OPEN` state, marking the items in that fulfillment order as fulfillable.
On Jan 15, the first fulfillment order transitions to an `OPEN` state, indicating that fulfillment should begin for the item. Only the items that are meant to be fulfilled on January 15 are ready for fulfillment, whereas the remaining items are shown as scheduled:
> Warning:
Apps should be aware that `SCHEDULED` fulfillment orders aren't included in the calculation of the order `lineItem.fulfillableQuantity`. In this example lifecycle, before January 15 `lineItem.fulfillableQuantity` is `0`, and after January 15 it changes to `1`. After the item is fulfilled the value returns to `0`. Shopify recommends using `fulfillmentOrderLineItem.remainingQuantity` to determine remaining quantities to fulfill.
## Line item quantities for checkouts and orders
A subscription appears as one line item on the checkout. However, the line item quantity on the corresponding order represents the [interval count of the subscription billing policy](/docs/api/admin-graphql/latest/objects/sellingplanrecurringbillingpolicy#field-sellingplanrecurringbillingpolicy-intervalcount). For example, if a customer buys a three-month subscription of coffee beans, then the checkout line item quantity is `1` and order line item quantity is `3`.
## Fulfillment scheduling and statuses
The `fulfillAt` attribute of a fulfillment order represents when the merchant should start fulfilling the items in the fulfillment order. The attribute also contributes to the grouping of line items for fulfillment orders with the `SCHEDULED` status, along with [location](/docs/api/admin-graphql/latest/objects/location), [fulfillment service](/docs/api/admin-graphql/latest/objects/FulfillmentService), [delivery method](/docs/api/admin-graphql/latest/objects/DeliveryMethod), and [delivery profile](/docs/api/admin-graphql/latest/objects/deliveryprofile).
For fulfillment orders that are assigned to a third-party fulfillment service, the `fulfillAt` attribute represents when the merchant should request fulfillment from the fulfillment service.
The `SCHEDULED` status of `fulfillmentOrderStatus` represents the state of fulfillment orders that are created with a future `fulfillAt` date. The order's [`displayFulfillmentStatus`](/docs/api/admin-graphql/latest/objects/order#field-order-displayfulfillmentstatus) is `SCHEDULED` only when all associated fulfillment orders are in a `SCHEDULED` state.
> Warning:
> All cycles for a pre-paid subscription contract which has been billed apply to a single order. To make edits to these cycles, you need to use the [`Order`](/docs/api/admin-graphql/latest/objects/order) and [`FulfillmentOrder`](/docs/api/admin-graphql/latest/objects/fulfillmentorder) resources. Changes to fulfillment orders aren't automatically reflected on subscription contracts, and changes to subscription contracts don't automatically update existing fulfillment orders. Changes to the subscription contract are reflected only on new orders that are generated from the changed subscription contract.
> Learn more about [keeping orders and subscription contracts in sync](/docs/apps/build/purchase-options/subscriptions/fulfillments/sync-orders-subscriptions#keeping-orders-and-subscription-contracts-in-sync) for prepaid subscriptions.
## Contract renewals
When a pre-paid subscription contract is up for renewal, apps need to trigger a billing attempt using the [subscriptionBillingAttemptCreate](/docs/api/admin-graphql/latest/mutations/subscriptionbillingattemptcreate) mutation. The customer is then billed and a new order is generated for the new billing cycles.
## Refunds
A customer might request a refund for one or more scheduled fulfillments. Refunds are supported in the Shopify admin, but you can also support a variety of refund scenarios using the [`refundCreate`](/docs/api/admin-graphql/latest/mutations/refundcreate) mutation.
> Note:
> You should refund specific line items and quantities rather than refunding custom dollar amounts. Refunding custom amounts negatively impacts merchant sales reporting.
### How refunds work
> Caution:
> When you refund fulfillment orders, it doesn't automatically cancel the renewal that's associated with the subscription contract. To cancel the renewal, you also need to [update the subscription contract](/docs/apps/build/purchase-options/subscriptions/contracts/update-a-subscription-contract).
Refunds are made starting on the last scheduled fulfillment and then working backwards in reverse chronological order.
Fulfillment orders with `SCHEDULED` status are prioritized over those with `OPEN` status. The fulfillment orders are selected for refund using the value of `fulfillAt` in descending order.
Refer to the [Manage fulfillments for prepaid subscriptions](/docs/apps/build/purchase-options/subscriptions/fulfillments/manage-subscription-fulfillments) tutorial for an example of how refunds apply to scheduled fulfillments.
### Webhooks
You can subscribe to the [`refunds/create`](/docs/api/admin-graphql/latest/enums/webhooksubscriptiontopic) webhook in case the merchant does a refund on a prepaid subscription order through the Shopify admin or another app. In these scenarios, you can use the webhook as a trigger to communicate with the merchant that they might want to also cancel the associated subscription contract.
## Advanced fulfillment scenarios
Customers might add a combination of prepaid subscriptions, subscribe-and-save subscriptions, and non-subscription (one-time purchase) items to their cart. This section describes how fulfillment orders are created for some example scenarios.
For these example scenarios, the test shop has only one location, one manual fulfillment service, one delivery profile, and one delivery method.
### Multiple prepaid subscriptions
A customer might add multiple prepaid subscription items to their order.
In this example, a customer orders the following items on Jan 10:
- A three-month prepaid subscription for coffee filters
- A three-month prepaid subscription for coffee bags
If the subscriptions have different [anchor dates](/docs/apps/build/purchase-options/subscriptions/selling-plans#anchors), then the order is created with separate fulfillment orders for each line item. The following image shows the fulfillment orders for subscriptions with different anchor dates on the 15th and 17th of each month:
If the subscriptions share the same anchor date, then the fulfillment orders are combined for each billing cycle. The following image shows the fulfillment orders for each subscription with shared anchor dates on the 15th of each month:
### Prepaid subscription with non-subscription items
A customer might purchase a prepaid subscription item with a non-subscription (one-time purchase) item at the same time. The resulting order contains both of the purchased items.
In this example, the customer orders the following items on Jan 10:
- A three-month prepaid subscription for coffee bags
- A one-time purchase for a Seiko Coffee Machine
Because the Seiko Coffee Machine can be fulfilled immediately, four fulfillment orders are generated:
However, if the customer orders these items on the anchor date, then the one-time purchase is added to the same fulfillment order as the first cycle for the prepaid subscription. The following image shows that only three fulfillment orders are generated for this scenario:
### Prepaid subscription with pay-per-delivery subscription items
A customer might purchase a prepaid subscription item with a [subscribe-and-save](/docs/apps/build/purchase-options/subscriptions/selling-plans/build-a-selling-plan#step-1-create-a-selling-plan-group) subscription item at the same time. This creates two subscription contracts: one for the prepaid subscription and one for the subscribe-and-save subscription.
The first generated order includes all cycles of the prepaid item and only the first cycle of the subscribe-and-save item.
In this example, the customer orders the following items on Jan 10:
- A three-month prepaid subscription for coffee bags with an anchor date on the 15th of each month
- A subscribe-and-save subscription for coffee filters with billing and fulfillment anchor dates on the 12th of each month
The first order with ID 444 is generated on Jan 10 and has the following fulfillment orders:
The statuses on these fulfillment orders change on the anchor dates. The following diagram shows when the fulfillment status changes and inventory is committed for this first order:
On Feb 15, the fulfillment order for coffee bags on the prepaid subscription for the first order transitions to an `OPEN` status.
On Feb 12, a new order with ID 555 is generated for the subscribe-and-save subscription after a successful billing attempt. The inventory is committed upon order creation and the fulfillment order is created with an `OPEN` status.
## Webhooks
In API version 2023-01 and higher, your app can subscribe to webhooks for event notifications related to fulfillment orders. The following examples show the JSON responses from each of the available webhooks.
To learn how to set up and consume webhooks, refer to [Webhooks configuration overview](/docs/apps/build/webhooks/subscribe).
## Fulfillment order display on legacy clients
### Legacy mobile clients
For mobile clients (version 8.75.0 or older), scheduled fulfillment orders are hidden from the mobile UI. After a scheduled fulfillment order’s `fulfillAt` date expires and it transitions to an `OPEN` state, it becomes visible in the UI.
This means that scheduled fulfillment orders can't be manually marked as `OPEN` in advance of their `fulfillAt` date on legacy mobile clients.
### Legacy POS clients
POS Classic (Android & iOS) doesn't show the fulfillment statuses of scheduled orders.
For the [all-new POS](https://help.shopify.com/manual/sell-in-person) (iOS version 6.19 and older), fulfillment status isn't exposed for scheduled orders. Products that are sold as [subscription-only](/docs/apps/build/purchase-options/subscriptions/selling-plans/build-a-selling-plan#step-3-optional-configure-a-product-to-be-sold-only-as-a-subscription) aren't displayed in the product catalogue on POS. If an app adds a subscription-only product to the cart, then an error is raised.
## Next steps
- Learn how to [manage fulfillments for prepaid subscriptions](/docs/apps/build/purchase-options/subscriptions/fulfillments/manage-subscription-fulfillments), including how to manually open fulfillment orders, skip and reschedule fulfillment orders, and refund scheduled fulfillments.
- Learn how to [manage orders for prepaid subscriptions](/docs/apps/build/purchase-options/subscriptions/fulfillments/sync-orders-subscriptions) by keeping subscription contract and order information in sync.