--- title: Build a subscription contract description: Learn how to create a subscription, and how to make a billing attempt to schedule and automate the billing of subscriptions in your app. source_url: html: https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract md: https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract.md --- ExpandOn this page * [Requirements](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#requirements) * [Step 1: Create a new subscription draft](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#step-1-create-a-new-subscription-draft) * [Step 2: Add a line to the subscription draft](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#step-2-add-a-line-to-the-subscription-draft) * [Step 3: Commit the subscription draft](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#step-3-commit-the-subscription-draft) * [Step 4: Create a billing attempt](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#step-4-create-a-billing-attempt) * [Next steps](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#next-steps) * [Shopify CLI commands](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#shopify-cli-commands) * [Next steps](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#next-steps) # Build a subscription contract A [subscription contract](https://shopify.dev/docs/api/admin-graphql/latest/queries/subscriptioncontract) 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. Note Shopify automatically creates subscription contracts when products with selling plans are purchased through checkout. *** ## Requirements Note * Most subscriptions, pre-order and try before you buy apps need to request API access through the [Partner Dashboard](https://shopify.dev/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](https://shopify.dev/docs/apps/launch/app-requirements-checklist#purchase-option-apps) to be published on the Shopify App Store. * Custom apps [created in the Shopify admin](https://shopify.dev/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](https://shopify.dev/docs/api/admin-graphql#authentication) to the GraphQL Admin API. - Your app has the `read_own_subscription_contracts` and `write_own_subscription_contracts` [access scopes](https://shopify.dev/docs/api/usage/access-scopes). Learn how to [configure your access scopes using Shopify CLI](https://shopify.dev/docs/apps/build/cli-for-apps/app-configuration). - You've created [products](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productcreate) and [product variants](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productvariantcreate) in your development store. * You've familiarized yourself with the concept of [subscription contracts](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts). * Subscription drafts can be created and committed without a payment method. However, the subscription contract must have a payment method before a billing attempt can be created successfully. An existing payment method can be used or customers can be directed to [customer accounts](https://help.shopify.com/manual/customers/customer-accounts) in order to add a new payment method. To be notified of new payment methods, you can subscribe to the [customer\_payment\_methods/create](https://shopify.dev/docs/api/webhooks) webhook topic. These webhooks occur whenever a customer payment method is created. *** ## Step 1: Create a new subscription draft Tip This guide shows you how to build a subscription contract incrementally. However, you can also create a subscription contract in one call with the [`subscriptionContractAtomicCreate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/subscriptioncontractatomiccreate) mutation. A [subscription draft](https://shopify.dev/docs/api/admin-graphql/latest/queries/subscriptiondraft) captures the intent to create a subscription contract. Apps can incrementally build subscription drafts and then commit the draft to create or update a subscription contract. 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 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 [`SubscriptionDraftErrorCode`](https://shopify.dev/docs/api/admin-graphql/latest/enums/subscriptiondrafterrorcode). Note Using the [`subscriptionContractCreate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/subscriptioncontractcreate) mutation doesn't affect existing fulfillments that have been paid for. To edit an existing order, apps should use the [`orderEditBegin`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/ordereditbegin) mutation. ## POST https\://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL query ```graphql mutation { subscriptionContractCreate( input: { customerId: "gid://shopify/Customer/3963517010085" nextBillingDate: "2022-10-15" currencyCode: USD contract: { note: "Dear John, I hope you enjoy this gift." status: ACTIVE paymentMethodId: "gid://shopify/CustomerPaymentMethod/424359b3cecf1229e56697ab1e71b3d4" billingPolicy: { interval: MONTH, intervalCount: 1, minCycles: 3 } deliveryPolicy: { interval: MONTH, intervalCount: 1 } deliveryPrice: 14.99 deliveryMethod: { shipping: { address: { firstName: "John" lastName: "McDonald" address1: "33 New Montgomery St" address2: "#750" city: "San Francisco" province: "California" country: "USA" zip: "94105" } } } } } ) { draft { id } userErrors { field message } } } ``` ## JSON response ```json { "data": { "subscriptionContractCreate": { "draft": { "id": "gid://shopify/SubscriptionDraft/22" }, "userErrors": [] } }, "extensions": { "cost": { "requestedQueryCost": 10, "actualQueryCost": 10, "throttleStatus": { "maximumAvailable": 1000.0, "currentlyAvailable": 990, "restoreRate": 50.0 } } } } ``` Note The [minCycle](https://shopify.dev/docs/api/admin-graphql/latest/objects/SubscriptionBillingPolicy#field-subscriptionbillingpolicy-mincycles) and [maxCycle](https://shopify.dev/docs/api/admin-graphql/latest/objects/SubscriptionBillingPolicy#field-subscriptionbillingpolicy-maxcycles) are not actively performing any functions; rather, they serve as informational elements for apps. The `nextBillingDate` field primarily serves as a reminder for apps. Any changes made to this field won't affect the fulfillment date. Apps are responsible of keeping the contract status up-to-date and scheduling the orders. ### 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 [`SubscriptionDraftErrorCode`](https://shopify.dev/docs/api/admin-graphql/latest/enums/subscriptiondrafterrorcode). Note Using the [`subscriptionContractCreate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/subscriptioncontractcreate) mutation does not affect existing fulfillments that have been paid for. To edit an existing order, apps should use the [`orderEditBegin`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/ordereditbegin) mutation. ## POST https\://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL query ```graphql mutation { subscriptionContractCreate( input: { customerId: "gid://shopify/Customer/3963517010085" nextBillingDate: "2022-10-15" currencyCode: USD contract: { note: "Dear Sam, I hope you enjoy this gift." status: ACTIVE paymentMethodId: "gid://shopify/CustomerPaymentMethod/424359b3cecf1229e56697ab1e71b3d4" billingPolicy: { interval: MONTH, intervalCount: 3 } deliveryPolicy: { interval: MONTH, intervalCount: 1 } deliveryPrice: 14.99 deliveryMethod: { shipping: { address: { firstName: "John" lastName: "McDonald" address1: "33 New Montgomery St" address2: "#750" city: "San Francisco" province: "California" country: "USA" zip: "94105" } } } } } ) { draft { id } userErrors { field message } } } ``` ## JSON response ```json { "data": { "subscriptionContractCreate": { "draft": { "id": "gid://shopify/SubscriptionDraft/22" }, "userErrors": [] } }, "extensions": { "cost": { "requestedQueryCost": 10, "actualQueryCost": 10, "throttleStatus": { "maximumAvailable": 1000.0, "currentlyAvailable": 990, "restoreRate": 50.0 } } } } ``` *** ## Step 2: Add a line to the subscription draft You can call the [`subscriptionDraftLineAdd`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/subscriptiondraftlineadd) mutation to add a [subscription line](https://shopify.dev/docs/api/admin-graphql/latest/objects/subscriptionline) to the subscription draft. In the following example, a subscription line is added to specify a product variant with its quantity and price: ## POST https\://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL query ```graphql mutation { subscriptionDraftLineAdd( draftId: "gid://shopify/SubscriptionDraft/22" input: { productVariantId: "gid://shopify/ProductVariant/2" quantity: 20 currentPrice: 25.00 } ) { lineAdded { id quantity productId variantId variantImage { id } title variantTitle currentPrice { amount currencyCode } requiresShipping sku taxable } draft { id } userErrors { field message code } } } ``` ## JSON response ```json { "data": { "subscriptionDraftLineAdd": { "lineAdded": { "id": "gid://shopify/SubscriptionLine/818b344f-1e7f-4b0e-9fc2-2b749d4b5494", "quantity": 20, "productId": "gid://shopify/Product/1", "variantId": "gid://shopify/ProductVariant/2", "variantImage": { "id": "gid://shopify/ImageSource/1474738389014" }, "title": "Aerodynamic Wool Coat", "variantTitle": "Rustic Plastic Computer", "currentPrice": { "amount": "25.0", "currencyCode": "USD" }, "requiresShipping": true, "sku": "", "taxable": true }, "draft": { "id": "gid://shopify/SubscriptionDraft/22" }, "userErrors": [] } }, "extensions": { "cost": { "requestedQueryCost": 11, "actualQueryCost": 11, "throttleStatus": { "maximumAvailable": 1000.0, "currentlyAvailable": 989, "restoreRate": 50.0 } } } } ``` *** ## 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: ## POST https\://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL query ```graphql mutation { subscriptionDraftCommit(draftId: "gid://shopify/SubscriptionDraft/22") { contract { id } userErrors { field message } } } ``` ## JSON response ```json { "data": { "subscriptionDraftCommit": { "contract": { "id": "gid://shopify/SubscriptionContract/33" }, "userErrors": [] } }, "extensions": { "cost": { "requestedQueryCost": 10, "actualQueryCost": 10, "throttleStatus": { "maximumAvailable": 1000.0, "currentlyAvailable": 990, "restoreRate": 50.0 } } } } ``` ### 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 admin ![Customers page screenshot](https://cdn.shopify.com/shopifycloud/shopify-dev/production/assets/assets/images/api/subscriptions/active-product-subscriptions-DXdvD6gN.png) #### Order page in the Shopify admin ![Order page screenshot](https://cdn.shopify.com/shopifycloud/shopify-dev/production/assets/assets/images/api/subscriptions/order-page-shopify-admin-C4tPNjM-.png) ### 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 `subscription_contract_id`. You can customize the **View subscription** link by managing the **Subscription link** app extension from your app through the Shopify CLI. To learn how to create and manage a subscription link extension from the Shopify CLI, refer to [Start building subscription link extensions](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/subscription-link-extensions/start-building). If you don't customize the **View subscription** link, then the link is hardcoded. The hardcoded link has the following format: `{app_application_url}/subscriptions?customer_id={customer_id}&hmac={hmac}&id={subscription_contract_id}&shop={myshopify_domain}` *** ## Step 4: Create a billing attempt To bill a subscription contract and create an order, apps need to create a [billing attempt](https://shopify.dev/docs/api/admin-graphql/latest/queries/subscriptionbillingattempt). 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](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/billing-cycles) 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. ### Statuses 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](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#about-3d-secure), then a 3D Secure challenge can occur before the billing attempt transitions to a terminal state. Note A billing attempt can fail if Shopify's [fraud analysis service](https://help.shopify.com/manual/orders/fraud-analysis) has flagged a subscription contract's origin order. It is strongly recommended to check the [order risk level](https://shopify.dev/docs/api/admin-graphql/current/objects/Order#field-order-risklevel) of a contract's [origin order](https://shopify.dev/docs/api/admin-graphql/current/objects/SubscriptionContract#field-subscriptioncontract-originorder) before executing a billing attempt. ### Example call To create a billing attempt, specify the following inputs in the [`subscriptionBillingAttemptCreate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/subscriptionbillingattemptcreate) mutation: * `subscriptionContractId`: The ID of the subscription contract. * `subscriptionBillingAttemptInput` * `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 `originTime` value. The UTC offset of `originTime` should match the shop's [`timezoneOffset`](https://shopify.dev/docs/api/admin-graphql/latest/objects/shop#fields-Shop-OBJECT). Billing attempts are processed asynchronously, which means the resulting order won't 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 (`false`). Note If you have adopted [Subscriptions Billing Cycle APIs](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/billing-cycles), you can [create orders by charging a billing cycle directly](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/billing-cycles/manage-billing-cycle-contracts#step-5-create-an-order). This approach enables more precise management of billing cycles by directly linking order creation to the specific cycle being billed. ## POST https\://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL query ```graphql mutation { subscriptionBillingAttemptCreate( subscriptionContractId: "gid://shopify/SubscriptionContract/33" subscriptionBillingAttemptInput: { idempotencyKey: "abc123" originTime: "2022-10-30T04:05:02+14:00" } ) { subscriptionBillingAttempt { id originTime errorMessage nextActionUrl order { id } ready } } } ``` ## JSON response ```json { "data": { "subscriptionBillingAttemptCreate": { "subscriptionBillingAttempt": { "id": "gid://shopify/SubscriptionBillingAttempt/82", "originTime": "2022-10-30T04:05:02+14:00", "errorMessage": null, "nextActionUrl": null, "order": null, "ready": false } } }, "extensions": { "cost": { "requestedQueryCost": 11, "actualQueryCost": 11 } } } ``` Because the order isn't ready immediately, you can query the [subscriptionBillingAttempt](https://shopify.dev/docs/api/admin-graphql/latest/queries/subscriptionbillingattempt) to get the resulting order information. ## POST https\://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL query ```graphql query { subscriptionBillingAttempt( id: "gid://shopify/SubscriptionBillingAttempt/524310" ) { id errorMessage nextActionUrl order { id } ready } } ``` ## JSON response ```json { "data": { "subscriptionBillingAttempt": { "id": "gid://shopify/SubscriptionBillingAttempt/32933", "errorMessage": null, "nextActionUrl": null, "order": { "id": "gid://shopify/Order/2014567596054" }, "ready": true } }, "extensions": { "cost": { "requestedQueryCost": 2, "actualQueryCost": 2, "throttleStatus": { "maximumAvailable": 1000.0, "currentlyAvailable": 998, "restoreRate": 50.0 } } } } ``` ### 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: ![Subscription contracts objects diagram](https://cdn.shopify.com/shopifycloud/shopify-dev/production/assets/assets/images/api/3ds-flow-CNO7Vmvl.png) You can poll the [`subscriptionBillingAttempt`](https://shopify.dev/docs/api/admin-graphql/latest/queries/subscriptionbillingattempt) object until the `nextActionUrl` field is available to see the URL. Note The [subscription\_billing\_attempts/success](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts#subscription-related-webhooks) and [subscription\_billing\_attempts/failure](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts#subscription-related-webhooks) webhooks aren't triggered until the challenge is completed. If the customer doesn't complete the challenge, then your app won't be notified. ## POST https\://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL query ```graphql query { subscriptionBillingAttempt( id: "gid://shopify/SubscriptionBillingAttempt/123" ) { id errorMessage errorCode nextActionUrl order { id } ready } } ``` ## JSON response ```json { "data": { "subscriptionBillingAttempt": { "id": "gid:\/\/shopify\/SubscriptionBillingAttempt\/123", "errorMessage": null, "errorCode": null, "nextActionUrl": "https:\/\/example.com\/subscriptions\/billing\/959c1a7cec286e06bfe7f16ff351c101\/challenge", "order": null, "ready": false } }, "extensions": { "cost": { "requestedQueryCost": 2, "actualQueryCost": 2 } } } ``` ### About re-billing failed payment attempts It's up to apps to attempt re-billing for failed payment attempts. We expose many signals to help you make the right decision about when to re-bill failed payment attempts and how often. * Only rebill payment attempts that failed with error codes that make sense to retry, such as [`insufficient_funds`](https://shopify.dev/docs/api/admin-graphql/latest/enums/SubscriptionBillingAttemptErrorCode#value-insufficientfunds). * Avoid re-billing failed payments with the same customer payment method more than 30 times in 35 days. These requests will be failed and the payment method will be revoked. You can keep track of how Shopify correlates failed payments by leveraging the [`payment_session_id`](https://shopify.dev/docs/api/admin-graphql/latest/objects/SubscriptionBillingAttempt#field-paymentsessionid) and [`payment_group_id`](https://shopify.dev/docs/api/admin-graphql/latest/objects/SubscriptionBillingAttempt#field-paymentgroupid) fields. Retrying billing for the same contract identity will result in billing attempts with the same `payment_group_id`. You can use this to track all failed, or the final successful, billing attempt linked to a final order. All billing attempts that kept their payment details identical will share the same `payment_session_id`. When surfacing merchants' payment success metrics, ensure that only the last billing attempt in a group that shares the same `payment_session_id` and `payment_group_id` is counted, as all the billing attempts in that group were retries of one another. ### Inventory tracking Similar to creating a new order through checkout, the availability of inventory is checked during the billing attempt process. Merchants can adjust inventory tracking so that they can [continue to sell product variants when out of stock](https://help.shopify.com/manual/products/inventory/getting-started-with-inventory/selling-when-out-of-stock). They can also adjust inventory tracking to prevent selling product variants when out of stock. If one or more of a subscription's product variants are out of stock (and aren't configured to continue selling), then the billing attempt moves to a failed state with either an [insufficient inventory](https://shopify.dev/docs/api/admin-graphql/latest/enums/SubscriptionBillingAttemptErrorCode#value-insufficientinventory) or a [inventory location](https://shopify.dev/docs/api/admin-graphql/latest/enums/SubscriptionBillingAttemptErrorCode#value-inventoryallocationsnotfound) error. *** ## Next steps * Learn how to [update a subscription contract](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/update-a-subscription-contract) with new information. *** ## Shopify CLI commands For a complete reference of Shopify CLI commands to help you build apps and themes, see the [Shopify CLI command reference](https://shopify.dev/docs/api/shopify-cli). Note The Shopify CLI is available as an [npm package](https://www.npmjs.com/package/@shopify/cli) and as a [standalone binary](https://github.com/Shopify/cli/releases/latest). ### App commands The following commands help you build Shopify apps: | Command | Description | | - | - | | [`shopify app build`](https://shopify.dev/docs/api/shopify-cli/commands/app/build) | Build the app | | [`shopify app config link`](https://shopify.dev/docs/api/shopify-cli/commands/app/config/link) | Link an app to a configuration file | | [`shopify app config push`](https://shopify.dev/docs/api/shopify-cli/commands/app/config/push) | Push your app configuration to the Partner Dashboard | | [`shopify app deploy`](https://shopify.dev/docs/api/shopify-cli/commands/app/deploy) | Deploy the app | | [`shopify app dev`](https://shopify.dev/docs/api/shopify-cli/commands/app/dev) | Start a development server | | [`shopify app env pull`](https://shopify.dev/docs/api/shopify-cli/commands/app/env/pull) | Pull app and extensions environment variables | | [`shopify app function build`](https://shopify.dev/docs/api/shopify-cli/commands/app/function/build) | Build a function | | [`shopify app function run`](https://shopify.dev/docs/api/shopify-cli/commands/app/function/run) | Run a function | | [`shopify app function schema`](https://shopify.dev/docs/api/shopify-cli/commands/app/function/schema) | Print the schema for a function | | [`shopify app generate extension`](https://shopify.dev/docs/api/shopify-cli/commands/app/generate/extension) | Generate a new app extension | | [`shopify app generate schema`](https://shopify.dev/docs/api/shopify-cli/commands/app/generate/schema) | Generate GraphQL types for the Admin API | | [`shopify app info`](https://shopify.dev/docs/api/shopify-cli/commands/app/info) | Print basic information about your app and extensions | | [`shopify app versions list`](https://shopify.dev/docs/api/shopify-cli/commands/app/versions/list) | List deployed versions | ### Auth commands The following commands help you authenticate with Shopify: | Command | Description | | - | - | | [`shopify auth logout`](https://shopify.dev/docs/api/shopify-cli/commands/auth/logout) | Log out of Shopify | ### Theme commands The following commands help you build Shopify themes: | Command | Description | | - | - | | [`shopify theme check`](https://shopify.dev/docs/api/shopify-cli/commands/theme/check) | Run theme checks | | [`shopify theme delete`](https://shopify.dev/docs/api/shopify-cli/commands/theme/delete) | Delete remote themes | | [`shopify theme dev`](https://shopify.dev/docs/api/shopify-cli/commands/theme/dev) | Start a development server | | [`shopify theme init`](https://shopify.dev/docs/api/shopify-cli/commands/theme/init) | Create a new theme | | [`shopify theme language-server`](https://shopify.dev/docs/api/shopify-cli/commands/theme/language-server) | Start a Language Server Protocol server | | [`shopify theme list`](https://shopify.dev/docs/api/shopify-cli/commands/theme/list) | List remote themes | | [`shopify theme open`](https://shopify.dev/docs/api/shopify-cli/commands/theme/open) | Open your theme in the Shopify admin or online store | | [`shopify theme package`](https://shopify.dev/docs/api/shopify-cli/commands/theme/package) | Package your theme | | [`shopify theme publish`](https://shopify.dev/docs/api/shopify-cli/commands/theme/publish) | Set a remote theme as the live theme | | [`shopify theme pull`](https://shopify.dev/docs/api/shopify-cli/commands/theme/pull) | Download your remote theme files locally | | [`shopify theme push`](https://shopify.dev/docs/api/shopify-cli/commands/theme/push) | Upload your local theme files to Shopify | | [`shopify theme share`](https://shopify.dev/docs/api/shopify-cli/commands/theme/share) | Create a shareable, unpublished theme preview | ### General commands The following commands help you work with the Shopify CLI: | Command | Description | | - | - | | [`shopify search`](https://shopify.dev/docs/api/shopify-cli/commands/search) | Search for CLI commands | | [`shopify upgrade`](https://shopify.dev/docs/api/shopify-cli/commands/upgrade) | Upgrade the Shopify CLI | | [`shopify version`](https://shopify.dev/docs/api/shopify-cli/commands/version) | Print the version number | *** ## Next steps * Learn how to [create a new app](https://shopify.dev/docs/apps/build/scaffold-app) using the Shopify CLI. * Learn how to [create a new theme](https://shopify.dev/docs/storefronts/themes/getting-started/create) using the Shopify CLI. *** * [Requirements](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#requirements) * [Step 1: Create a new subscription draft](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#step-1-create-a-new-subscription-draft) * [Step 2: Add a line to the subscription draft](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#step-2-add-a-line-to-the-subscription-draft) * [Step 3: Commit the subscription draft](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#step-3-commit-the-subscription-draft) * [Step 4: Create a billing attempt](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#step-4-create-a-billing-attempt) * [Next steps](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#next-steps) * [Shopify CLI commands](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#shopify-cli-commands) * [Next steps](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/contracts/build-a-subscription-contract#next-steps)