Discount apps integrate with the Shopify admin to provide discount types for app users. This guide introduces the ways that you can extend your app code into Shopify checkout and customize the discount experience.
- Use the [GraphQL Admin API](#build-with-the-graphql-admin-api) to create and manage [discounts that are native to Shopify](https://help.shopify.com/manual/discounts/discount-types).
- Use [Shopify Functions](#build-with-shopify-functions) to extend your app code into Shopify checkout and create discount functionality that isn't offered out of the box with Shopify.
## Build with the GraphQL Admin API
The [GraphQL Admin API](/docs/api/admin-graphql) enables you to create and manage Shopify discounts.
### Discount methods
You can create discounts that are either applied automatically, or applied with discount codes.
The following table describes the different discount methods you can use as part of your app using the GraphQL Admin API:
| Discount method | Description | Example use cases |
|---|---|---|
| Automatic discount | A discount that's automatically applied at checkout and on a cart if prerequisites are met. |
- A [Buy X Get Y or Spend X Get Y automatic discount](/docs/api/admin-graphql/latest/mutations/discountAutomaticBxgyCreate)
- A [percentage or fixed-amount automatic discount](/docs/api/admin-graphql/latest/mutations/discountAutomaticBasicCreate)
|
| Code discount | A discount that customers can redeem using a specific code. Merchants can create and share discount codes individually with customers. | - A [Buy X Get Y or Spend X Get Y code discount](/docs/api/admin-graphql/latest/mutations/discountCodeBxgyCreate)
- A [percentage or fixed-amount code discount](/docs/api/admin-graphql/latest/mutations/discountCodeBasicCreate)
- A [free shipping code discount](/docs/api/admin-graphql/latest/mutations/discountCodeFreeShippingCreate)
|
Visit the Shopify Help Center to learn about the limitations and considerations that apply to each discount type:
- [Automatic discounts](https://help.shopify.com/manual/discounts/discount-types#automatic-discounts)
- [Code discounts](https://help.shopify.com/manual/discounts/discount-types#considerations-for-creating-discount-codes)
### Access scopes
To use discount-related GraphQL mutations when building with the GraphQL Admin API, your app needs to request the following [access scopes](/docs/api/usage/access-scopes) for a Shopify store:
| Access scope | Required or optional? | Description |
|---|---|---|
| `write_discounts` | Required | Allows apps to create and update Shopify discounts |
| `read_customers` | Optional | Allows apps to query a store's customers |
| `read_products` | Optional | Allows apps to query a store's products |
| `read_shipping` | Optional | Allows apps to query the countries that a store ships to |
## Build with Shopify Functions
[Shopify Functions](/docs/apps/build/functions) enable you to create discount functionality that isn't offered out of the box with Shopify. For example, a discount function can be used to create volume discounts with different discount rates upon hitting specified volume breakpoints.
An app developer creates and deploys an app with a function that defines a new discount type. A user can then install the app on a Shopify store and create a new discount from a discount type provided by the app. Shopify executes the function to calculate the discount when a customer adds a product to their cart.
![How a developer can create, test, and deploy a function](/assets/api/functions/create-test-deploy.png)
### Discount classes
Discount classes are similar to native discount types. You can create one or more discount classes as part of your app using [Shopify Functions](/docs/apps/build/functions).
The following table describes the different discount classes in detail:
| Discount class | Description | Example use cases |
|---|---|---|
| [Order discount](/docs/api/functions/reference/order-discounts) | A discount that's applied to all merchandise in the cart. | - Money off the order subtotal. For example, $5 off the order subtotal.
- Money off products on an order. For example, 20% off all products on the order.
- Tiered discount by spend. For example, spend $100 to get 10% off all products.
|
| [Product discount](/docs/api/functions/reference/product-discounts) | A discount that's applied to a particular product or product variant in the cart | - Money off a product. For example, 20% off shirts.
- Money off a product variant. For example, $5 off blue shirts.
- Buy a specific quantity of a product for a specific amount. For example, $5 off up to 2 blue shirts.
- Buy a specific amount of a product, get a second amount at a discount. For example, buy 4 shirts and get 2 blue shirts free
|
| [Shipping discount](/docs/api/functions/reference/shipping-discounts) | A discount that's applied to one or more shipping rates at checkout | - Free shipping.
- A discount on shipping. For example, 20% off shipping or $5 off shipping.
- A discount on specific shipping rates. For example, 50% off Standard shipping.
|
## Related mutations and queries
Explore the following resources to manage discounts in your app. Use mutations to craft, modify, and remove discounts, and use queries to retrieve detailed listings.
> Tip:
> App discounts use a function ID as input to find the function to run. This enables the creation of custom discounting behavior that isn't offered out of the box with Shopify. [Learn more about how to build a discount function with Shopify Functions](/docs/apps/build/discounts/build-discount-function).
### Automatic discount mutations
The following table outlines some common mutations for creating, updating, and deleting [automatic](#discount-methods) discounts:
| Discount type | Mutations |
|---|---|
| Buy X Get Y or Spend X Get Y
| [discountAutomaticBxgyCreate](/docs/api/admin-graphql/latest/mutations/discountAutomaticBxgyCreate)
[discountAutomaticBxgyUpdate](/docs/api/admin-graphql/latest/mutations/discountAutomaticBxgyUpdate)
[discountAutomaticDelete](/docs/api/admin-graphql/latest/mutations/discountAutomaticDelete) |
| Percentage or fixed amount
| [discountAutomaticBasicCreate](/docs/api/admin-graphql/latest/mutations/discountAutomaticBasicCreate)
[discountAutomaticBasicUpdate](/docs/api/admin-graphql/latest/mutations/discountAutomaticBasicUpdate)
[discountAutomaticDelete](/docs/api/admin-graphql/latest/mutations/discountAutomaticDelete) |
| Free shipping
| [discountAutomaticFreeShippingCreate](/docs/api/admin-graphql/latest/mutations/discountAutomaticFreeShippingCreate)
[discountAutomaticFreeShippingUpdate](/docs/api/admin-graphql/latest/mutations/discountAutomaticFreeShippingUpdate)
[discountAutomaticDelete](/docs/api/admin-graphql/latest/mutations/discountAutomaticDelete) |
| App
| [discountAutomaticAppCreate](/docs/api/admin-graphql/latest/mutations/discountAutomaticAppCreate)
[discountAutomaticAppUpdate](/docs/api/admin-graphql/latest/mutations/discountAutomaticAppUpdate)
[discountAutomaticDelete](/docs/api/admin-graphql/latest/mutations/discountAutomaticDelete) |
### Code discount mutations
The following table outlines some common mutations for creating, updating, and deleting [code](#discount-methods) discounts:
| Discount type | Mutations |
|---|---|
| Buy X Get Y or Spend X Get Y
| [discountCodeBxgyCreate](/docs/api/admin-graphql/latest/mutations/discountCodeBxgyCreate)
[discountCodeBxgyUpdate](/docs/api/admin-graphql/latest/mutations/discountCodeBxgyUpdate)
[discountCodeDelete](/docs/api/admin-graphql/latest/mutations/discountCodeDelete) |
| Percentage or fixed amount
| [discountCodeBasicCreate](/docs/api/admin-graphql/latest/mutations/discountCodeBasicCreate)
[discountCodeBasicUpdate](/docs/api/admin-graphql/latest/mutations/discountCodeBasicUpdate)
[discountCodeDelete](/docs/api/admin-graphql/latest/mutations/discountCodeDelete) |
| Free shipping
| [discountCodeFreeShippingCreate](/docs/api/admin-graphql/latest/mutations/discountCodeFreeShippingCreate)
[discountCodeFreeShippingUpdate](/docs/api/admin-graphql/latest/mutations/discountCodeFreeShippingUpdate)
[discountCodeDelete](/docs/api/admin-graphql/latest/mutations/discountCodeDelete) |
| App
| [discountCodeAppCreate](/docs/api/admin-graphql/latest/mutations/discountCodeAppCreate)
[discountCodeAppUpdate](/docs/api/admin-graphql/latest/mutations/discountCodeAppUpdate)
[discountCodeDelete](/docs/api/admin-graphql/latest/mutations/discountCodeDelete) |
| Bulk actions
| [discountCodeBulkActivate](/docs/api/admin-graphql/latest/mutations/discountcodebulkactivate)
[discountCodeBulkDeactivate](/docs/api/admin-graphql/latest/mutations/discountcodebulkdeactivate)
[discountCodeBulkDelete](/docs/api/admin-graphql/latest/mutations/discountcodebulkdelete) |
### Queries
The following table outlines some common queries for interacting with [automatic and code](#discount-methods) discounts.
| Discount type | Queries |
|---|---|
| Automatic discounts | [automaticDiscountNode](/docs/api/admin-graphql/latest/queries/automaticDiscountNode)
[automaticDiscountNodes](/docs/api/admin-graphql/latest/queries/automaticDiscountNodes) |
| Code discounts | [codeDiscountNode](/docs/api/admin-graphql/latest/queries/codeDiscountNode)
[codeDiscountNodes](/docs/api/admin-graphql/latest/queries/codeDiscountNodes) |
## Admin UI extensions vs. Remix App UI
Developers creating a merchant-facing UI to manage function-powered discounts have the option to use either a UI extension or a Remix App UI. Each method provides distinct advantages and is appropriate for different scenarios.
### Admin UI extensions
Admin UI extensions provide a way to extend the Shopify admin with custom user interfaces built using [Shopify’s UI components](/docs/api/admin-extensions/latest/components). This method is great for simpler interfaces that integrate tightly with Shopify’s existing UI.
**Benefits:**
- The developer is only responsible for building the UI for discount controls that are specific to their discount function (e.g. managing metafield values for discount percentage).
- UI for common discount fields such as active dates, and customer eligibility are provided by the discount page.
- Developers don't need to manage GraphQL requests to create or save discounts because the UI extension integrates with the discount page's save bar when values are updated.
- Shopify hosts the UI code when apps are deployed, so developers don't need to build, deploy, and maintain web servers.
**Use Cases:**
- Ideal for adding simple form inputs to the discount page to manage quantities and discount amounts for a volume discount app.
![An image showing the discount details UI extension.](/assets/apps/discounts/discount-ui-extension.png)
### Remix App UI
Remix app UI allows developers to build dynamic and interactive user interfaces that manage the entire discount details page using the Remix framework. This approach is suited for creating complex discount functionality.
**Benefits:**
- Developers can customize the entire discount configuration page.
**Considerations:**
- Involves a higher complexity and a steeper learning curve.
- Involves the developer being responsible for all GraphQL queries and mutations to create and update discounts, including all required fields.
**Use Cases:**
- Ideal for creating detailed discount pages with custom forms and features as the developer prefers.
By understanding the differences between these two approaches, developers can choose the most appropriate method based on their specific needs and the complexity of the discount functionality they are planning to implement.
![An image showing the discount details UI extension.](/assets/apps/discounts/discount-remix-app.png)
## Limitations
- The maximum number of automatic app discounts for each store is 25.
- Shopify Functions [limitations](/docs/apps/build/functions#limitations-and-considerations) apply.
## Getting started
Follow the getting started tutorials to learn how to customize and extend discounts:
## Developer tools and resources
Explore the following developer tools and resources to learn more about building with Shopify Functions: