Create a subscription contract
A subscription contract is the agreement between a customer and a merchant over a specific term for recurring purchases over a set or undefined period of time.
This guide shows you how to create subscription contracts by illustrating two use cases: "Subscribe and save" subscriptions and "Prepaid" subscriptions.
RequirementsAnchor link to section titled "Requirements"
- Your app can make authenticated requests to the GraphQL Admin API.
- Your app has the
write_own_subscription_contractsaccess scopes. For more information on requesting access scopes when your app is installed, refer to Getting started with OAuth.
You've familiarized yourself with the concept of subscription contracts.
Step 1: Create a new subscription draftAnchor link to section titled "Step 1: Create a new subscription draft"
A subscription draft captures the intent to change a subscription contract. Apps can incrementally build subscription contracts.
A subscription draft provides a way to get the projected state of the contract with all of the updates applied. Subscription contracts should always be up-to-date and accurate so that you can report on subscriptions and email subscribers, and build flows based on subscription changes.
Depending on your selling strategy, you might create a "Subscribe and save" or a "Prepaid" subscription.
Subscribe and save subscriptionsAnchor link to section titled "Subscribe and save subscriptions"
The following example shows the creation of a new subscription draft for a monthly "Subscribe and save" subscription, with a minimum commitment of three orders.
For error codes related to subscription contracts, refer to
Prepaid subscriptionsAnchor link to section titled "Prepaid subscriptions"
Prepaid contracts are created by defining a delivery policy that is more frequent than the billing policy. In the following example, the policies combine to define a prepaid subscription with three monthly deliveries.
For error codes related to subscription contracts, refer to
Step 2: Add a line to the subscription draftAnchor link to section titled "Step 2: Add a line to the subscription draft"
You can call the
subscriptionDraftLineAdd mutation to add a subscription line to the subscription draft. In the following example, a subscription line is added to specify a product variant with its quantity and price:
Step 3: Commit the subscription draftAnchor link to section titled "Step 3: Commit the subscription draft"
When you're satisfied with the state of the subscription draft, you can commit it. When you commit a draft subscription, all of the changes are made active:
Viewing subscription contract detailsAnchor link to section titled "Viewing subscription contract details"
The View subscription button on the customer subscriptions card and the order subscriptions card allows merchants to navigate to the app and view the subscription contract details.
Customers page in the Shopify adminAnchor link to section titled "Customers page in the Shopify admin"
Order page in the Shopify adminAnchor link to section titled "Order page in the Shopify admin"
Redirecting to the subscription contract within the appAnchor link to section titled "Redirecting to the subscription contract within the app"
To redirect merchants to the relevant subscription contract, the app needs to implement a specific endpoint. After it's implemented, the endpoint redirects to the subscription contract page within the app for the subscription defined by
You can customize the View subscription link by managing the Subscription link app extension in your Partner Dashboard:
You can modify the link target URL, save the changes, or remove the app extension if it's already present:
If you don't customize the View subscription link, then the link is hardcoded. The hardcoded link has the following format:
Step 4: Create a billing attemptAnchor link to section titled "Step 4: Create a billing attempt"
To schedule and automate the billing of subscriptions, apps need to create a billing attempt. A subscription is renewed when an app makes a billing attempt.
A billing attempt represents an attempt at executing a billing cycle and charging the customer payment method for a subscription contract. A billing attempt executes a contract based on the billing cycle at the origin time if provided. Otherwise, the billing attempt is created for the current billing cycle by default. You can also create a billing attempt on a specific billing cycle.
A billing attempt starts in a pending status. After it has been processed, it either transitions to successful or failed, both of which are terminal states:
- If the billing attempt is successful, then an order is created.
- If the billing attempt fails, then it means that the transaction has failed.
If an action is pending on the part of the customer in regards to 3D Secure, then a 3D Secure challenge can occur before the billing attempt transitions to a terminal state.
Example callAnchor link to section titled "Example call"
To create a billing attempt, specify the following inputs in the
subscriptionContractId: The ID of the subscription contract.
idempotencyKey: A unique key generated by the client to avoid duplicate payments.
originTime: An optional field that changes the way fulfillment intervals are calculated. If nothing is provided, fulfillment is calculated using the date that the billing attempt was successful. Otherwise, fulfillment is calculated using the provided
originTimevalue. The UTC offset of
originTimeshould match the shop's
Billing attempts are processed asynchronously, which means the resulting order will not be available right away. You can fetch the billing attempt and inspect the
ready field to find out whether the order has been created (
true) or not (
Because the order isn't ready immediately, you can query the subscriptionBillingAttempt to get the resulting order information.
About 3D SecureAnchor link to section titled "About 3D Secure"
Shopify handles 3D Secure authentication by emailing the customer when the financial institution requires a challenge. This flow is demonstrated in the diagram below:
You can poll the
subscriptionBillingAttempt object until the
nextActionUrl field is available to see the URL. It's up to apps to attempt re-billing for failed payment attempts.
- Learn how to update a subscription contract with new information.