Create and manage fulfillments for prepaid subscriptions
You can create prepaid subscriptions with scheduled fulfillments. When a customer purchases a pre-paid subscription from a merchant, a subscriptionContract and an order are created. The order contains multiple fulfillment orders which are scheduled to be fulfilled at a later time. The dates are determined based on the delivery
intervalCount set on the sellingPlanRecurringDeliveryPolicy. This allows for payment and goods sold to be kept in the same order, supporting accurate reporting in Shopify.
This tutorial illustrates the calls you can make to manage fulfillments on subscriptions. It provides information about deferred fulfillment orders, manual changing of fulfillments, cutoffs, renewals, scheduling, skipping, and refunds.
- You've completed our Getting started with the GraphQL Admin and REST Admin APIs guide and you're authenticated with the API.
- You've completed the Create and manage selling plans and Create and manage subscription contracts tutorials.
- You're familiar with the following API objects: Order, LineItem, FulfillmentOrder, Fulfillment, FulfillmentLineItem, Refund, RefundLineItem.
Apps require the following permissions to reschedule or open fulfillment orders. These permissions enable apps to manage scheduled cycles for an order that was already billed:
read_merchant_managed_fulfillment_orders: Read scheduled fulfillment orders assigned to a merchant-managed location.
write_merchant_managed_fulfillment_orders: Reschedule and open fulfillment orders assigned to a merchant-managed location.
read_third_party_fulfillment_orders: Read scheduled fulfillment orders assigned to a third party service.
write_third_party_fulfillment_orders: Reschedule and open fulfillment orders assigned to a third party service.
Line items 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. For example, if a customer buys a three month subscription of coffee brans, then the checkout line item quantiy is 1 and order line item quantity is 3.
Fulfillment order attributes
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
SCHEDULED status, along with location, fulfillmentService, deliveryMethodType and deliveryProfile.
For fulfillment orders assigned to a third-party fulfillment service, the
fulfillAt attribute represents when the merchant should request fulfillment from the fulfillment service.
SCHEDULED state of
fulfillmentOrderStatus represents the state of fulfillment orders created with a future
fulfillAt date. The status is also represented at the order's displayFulfillmentStatus, for orders where all associated fulfillment orders are in a
When a customer purchases a prepaid subscription from a merchant, a subscription contract and an order are created. One or more fulfillment orders are also created and are associated with the order. 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.
|Subscription contract||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.|
|Order||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 allows for payment and goods sold to be kept in the same order, supporting accurate reporting in Shopify.|
|Line items||Represents 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.|
|Fulfillment orders||Units of work (for example, line items) that are grouped together for fulfillment based on the following:
What you'll build
The examples in this tutorial revolve around the scenario of creating a recurring three-month prepaid subscription of coffee bags. In this scenario, three separate fulfillment orders are created for the order. The test shop assumed in this scenario has the following setup:
The tutorial covers the following:
- Mark a fulfillment as open to make the items in that fulfillment order fulfillable
- Change the cutoff date for a selling plan
- Renew prepaid subscriptions
- Reschedule fulfillment orders
- Skip a fulfillment cycle
- Handle refunds
Prepaid subscription lifecycle
A successful prepaid subscription flow looks like the following:
- The customer begins checkout. The checkout line item is a three-month prepaid subscription of coffee bags and the quantity is one.
- 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.
- Three fulfillment orders in a
SCHEDULEDstate are created associated with the order. The fulfillment orders have the following
- Fulfillment order 1: January 15
- Fulfillment order 2: February 15
- Fulfillment order 3: March 15
fulfillAt date for each fulfillment order is reached, inventory is committed and the fulfillment order is transitioned to
OPEN state, marking the items in that fulfillment order as fulfillable.
On January 15, the first fulfillmentOrder transitions to an
OPEN state, indicating that fulfillment should begin for the item. Only the items meant to be fulfilled on January 15 are ready for fulfillment, whereas the remaining items are shown as scheduled:
Manually open a fulfillment order
Merchants can opt to Fulfill early for scheduled fulfillments in Shopify admin. For scheduled fulfillment orders, this changes the fulfillment order's status to
OPEN ahead of the
fulfillAt date. You can also use the API to set a fulfillment order's status to
OPEN, as demonstrated in the following example:
Set the cutoff date for a selling plan
Selling plans can be set up with a cutoff on the sellingPlanRecurringDeliveryPolicy. The cutoff indicates how many days in advance of the delivery anchor the order would need to be placed in order to qualify for the upcoming delivery cycle.
In the following example,
cutoff is set to 5. Orders would need to be placed five days in advance of the cutoff date (on the 10th at 23:59:59:999) to be included in the fulfillment order. The SellingPlanRecurringDeliveryPolicyPreAnchorBehavior field is set to
ASAP. The field determines when items are fulfilled. For example, if the customer completed the checkout on January 8, then the settings would function as follows:
fulfillAtdate would be January 15, February 15, and March 15.
fulfillAtdate would be January 8, February 15, and March 15.
The input below includes the
deliveryPolicy cutoff set to "5" with
preAnchorBehavior set to
Renew the subscription
When a pre-paid subscription contract is up for renewal, apps need to trigger a billing attempt using the subscriptionBillingAttemptCreate mutation. The customer is then billed and a new order is generated for the new billing cycles.
In the example scenario, after the last fulfillment order is fulfilled on March 15 then a new order needs to be created for the following three months (containing three scheduled fulfillment orders for the 15 of April, May and June).
Reschedule a fulfillment order
The following example reschedules a fulfillment by specifying a new value for
fulfillAt along with the ID of the fulfillment order.
Skip fulfillment orders
Customers can decide to skip a scheduled fulfillment of a product. For example, in the case of the three-month coffee subscription, the customer might decide to skip a fulfillment because they already have enough coffee that month. To support this use case, you need to make a call to reschedule the fulfillment order, and another call to change the renewal date by one cycle.
Reschedule the fulfillment order
The following mutation reschedules the fulfillment order which is scheduled for Feb 15 to April 15.
Change the renewal date
The following mutation changes the renewal date by one cycle. The renewal triggers on May 15, because the fulfillment order from Feb 15 was moved to April 15.
Customers can request refunds for one or more scheduled fulfillments. Also, refunds are supported in the Shopify admin. You can support a variety of refund scenarios using the refundCreate mutation.
How refunds work
Refunds are made starting on the last cycle and then working backwards in reverse chronological order.
Fulfillment orders with
SCHEDULED status are prioritized over those with
OPEN status. Also, the fulfillment orders are selected for refund using the value of
fulfillAt in descending order.
About refunds and cancelling subscription contracts
Refunding fulfillment orders doesn't automatically cancel the renewal associated with the subscription contract. To cancel the renewal, you need to update the subscription contract.
Example refund calls
The following examples can be used to implement some common refunding scenarios.
The following request cancels the remaining subscription cycles after the first cycle is already completed.
Refund last cycle
The following request cancels the last scheduled fulfillment.
Refund a specific amount of cycles
The following request cancels the last four months of a six-month subscription.
You can subscribe to the refunds/create 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.
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.
Legacy POS clients
POS Classic (Android & iOS) does not show the fulfillment statuses of scheduled orders.
For the all-new POS (iOS only), as of v6.19 and earlier, fulfillment status is not exposed for scheduled orders. Products that are sold as subscription-only are not displayed in the product catalogue on POS. Also, if an app adds a subscription to the cart, then an error is raised.