--- gid: 60bd9a24-c5ec-4aa0-97af-b58496bd6fae title: Build a Product Discount Function description: Use Shopify Functions to add a Product Discount Function to an existing app. --- import RequirementPartial from 'app/views/partials/apps/discounts/requirements_partial.mdx'; import CreateFunction from 'app/views/partials/apps/discounts/create-function.mdx'; import DeployAndReinstallApp from 'app/views/partials/apps/discounts/deploy-and-reinstall-app.mdx'; import RegenerateTypes from 'app/views/partials/apps/discounts/regenerate-types.mdx'; You can create a new type of discount that's applied to a particular product or product variant in the cart. In this tutorial, you'll use [Shopify Functions](/docs/apps/build/functions) to create a new discount type called "Volume discount" that offers a percentage off when customers purchase more than the minimum quantity of a product. ## What you'll learn In this tutorial, you'll learn how to do the following tasks: - Generate starter code for Shopify Functions. - Use GraphQL to define the input of your Function. - Deploy Functions to the Shopify platform. - Review logs for your Function. ```bash shopify app generate extension --template product_discounts --name product-discount ``` ## Update the configuration ### Replace the content of the `run.graphql` file Replace the contents of `run.graphql`. This file defines the input for the Function target. Navigate to your extension's directory: ```bash cd extensions/product-discount ``` ## Update the Function logic ### Replace the content in `run.js` `run.rs` This Function logic applies a 10% discount to any cart lines with a quantity of two or more. Iterate through all cart lines to create discount targets, including only those with a quantity of two or more. Use the cart line ID to create each discount target. Apply the discount to the collected targets by creating a discount object and define a percentage-based discount.
The [shopify_function crate](https://crates.io/crates/shopify_function) serializes your [`FunctionRunResult`](/docs/api/functions/reference/product-discounts/graphql#functionrunresult) and writes it to STDOUT. The [@shopify/shopify_function package](https://www.npmjs.com/package/@shopify/shopify_function) applies `JSON.stringify()` to your [`FunctionRunResult`](/docs/api/functions/reference/product-discounts/graphql#functionrunresult).
## Preview the Function on a development store To test your Function, you need to make it available to your development store. 1. Ensure you have configured `build.watch` in your [function extension configuration](/docs/api/functions/configuration#properties). 1. Use Shopify CLI's [`dev` command](/docs/api/shopify-cli/app/app-dev) to preview the app: ```bash shopify app dev ``` You can keep the preview running as you work on your Function. When you make changes to a watched file, Shopify CLI rebuilds your Function and updates the Function extension's drafts, so that you can immediately test your changes. 1. Follow the CLI prompts to preview your app, and install it on your development store. ## Update your app's access scopes You must request the `write_discounts` [access scope](/docs/api/usage/access-scopes) to give your app the permissions that it needs to create and update discounts. In `shopify.app.toml`, located in the root of your app, add the `write_discounts` scope to the `access_scopes` array. ## Install the GraphiQL app To activate your Function, you must create a product discount on the store where you installed your app. You can do this using the [`discountAutomaticAppCreate`](/docs/api/admin-graphql/latest/mutations/discountAutomaticAppCreate) or [`discountCodeAppCreate`](/docs/api/admin-graphql/latest/mutations/discountCodeAppCreate) GraphQL mutations. 1. Install the [Shopify GraphiQL app](https://shopify-graphiql-app.shopifycloud.com/) on your store. 1. Make sure to select the `write_discounts` access scopes for the Admin API. 1. In the GraphiQL app, in the **API Version** field, select the **2023-07** version or higher. If you've already installed GraphiQL, then uninstall and reinstall it so that you can select the `write_discounts` access scope. ## Create the product discount with GraphiQL In this step, you'll use the Shopify GraphiQL app to create a Product Discount Function on your store. This involves querying your Function's ID and using it to create the discount with the appropriate GraphQL mutation. --- In subsequent tutorials, you'll use [metafields](/docs/api/checkout-ui-extensions/latest/apis/metafields) on this Product Discount Function to configure your Function, and create an interface so that users can configure the Function themselves. ### Query the shopify Function Use the [`shopifyFunctions`](/docs/api/admin-graphql/latest/queries/shopifyFunctions) query to get the ID of your Function. --- The result contains a node with your Function's ID. ```json { "app": { "title": "your-app-name-here" }, "apiType": "product_discounts", "title": "product-discount", "id": "YOUR_FUNCTION_ID_HERE" } ``` ### Create the Product Discount Function Use the [`discountAutomaticAppCreate`](/docs/api/admin-graphql/latest/mutations/discountAutomaticAppCreate) mutation to create a Product Discount Function. Add the Shopify Function ID from the [previous step](/docs/apps/build/discounts/build-discount-function?extension=rust#query-the-shopify-function) as the value for the `functionId` input.
You should receive a GraphQL response that includes the ID of the created product discount. If the response includes any messages under `userErrors`, then review the errors, check that your mutation and `functionId` are correct, and try the request again. If you receive a `Could not find Function` error, then confirm the following: - The Function ID is correct. - You've installed the app on your development store. - [Development store preview](#preview-the-function-on-a-development-store) is enabled in the Partner Dashboard. - Your app has the `write_discounts` access scope.
## Test the product discount ## Trigger the discount on your development store 1. From your Shopify admin, go to **Discounts**. You should now see the **Volume discount** that you created. ![An image showing a list of all active discounts for the store.](/assets/apps/discounts/functions-discount-list.png) 1. Deactivate or delete all other discounts to ensure that the **Volume discount** is the only active discount. 1. Open your development store and build a cart with a single item in it. No discounts should be applied to the cart. 1. Increase the item quantity to two. The 10% **Volume discount** should now be applied to the cart. ## Review the function execution 1. Open your terminal where `shopify app dev` is running, and review your function executions. --- When [testing functions on development stores](/docs/apps/build/functions/test-debug-functions#test-your-function-on-a-development-store), the output of `dev` includes executions of your functions, any debug logging you have added to them, and a link to a local file with the full function execution details. 1. In a new terminal window, use the Shopify CLI [`app function replay`](/docs/api/shopify-cli/app/app-function-replay) command to [replay a function execution locally](/docs/apps/build/functions/test-debug-functions#execute-the-function-locally-using-shopify-cli), and debug your function without the need to re-trigger the function execution on Shopify. ```bash shopify app function replay ``` 1. Select the function execution from the top of the list. Press `q` to quit when you are finished debugging.
## Tutorial complete! You've successfully created a Product Discount Function using Shopify Functions. You can now use this Function to apply discounts targeting cart lines with a quantity of two or more. ### Next Steps #### Build a user interface for your discount Function Add configuration to your discounts experience using metafields and build a user interface for your Function.