You can use the [Cart and Checkout Validation Function API](/docs/api/functions/reference/cart-checkout-validation) to ensure that purchases meet certain criteria before customers can complete an order. In this tutorial, you’ll use [Shopify Functions](/docs/apps/build/functions) to enforce product limits on store merchandise.
> Note:
> Errors from validation functions are exposed to the Storefront API's [`Cart`](/docs/storefronts/headless/building-with-the-storefront-api/cart/manage) object, in themes using the [`cart` template](/docs/storefronts/themes/architecture/templates/cart), and during checkout.

## 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.
- Create an Admin UI extension to configure your function.
## Requirements
> Tip:
> Shopify defaults to Rust as the most performant and recommended language choice to stay within the platform limits. For more information, refer to [language considerations](/docs/apps/build/functions/programming-languages).
- You've created a [Partner account](https://www.shopify.com/partners).
- You've created a [development store](/docs/api/development-stores#create-a-development-store-to-test-your-app)
with the [Checkout and Customer Accounts Extensibility developer preview enabled](/docs/api/developer-previews#enable-a-developer-preview).
- You've [created an app that uses Shopify CLI 3.49.5 or higher](/docs/apps/build/scaffold-app). If you previously installed Shopify CLI, then make sure that you're using the [latest version](/docs/api/shopify-cli#upgrade).
Start with an [extension-only app](/docs/apps/build/app-extensions/build-extension-only-app) and let Shopify host it for you.
- You've installed [Node.js](https://nodejs.org/en/download) 16 or higher.
- You've [installed your app](/docs/apps/build/scaffold-app#step-3-install-your-app-on-your-development-store) on the development store
with the [Checkout and Customer Accounts Extensibility developer preview enabled](/docs/api/developer-previews#enable-a-developer-preview).
### Rust-specific requirements
The following requirements are specific to Rust-based development with Shopify Functions.
- You've installed [Rust](https://www.rust-lang.org/tools/install).
On Windows, Rust requires the [Microsoft C++ Build Tools](https://docs.microsoft.com/en-us/windows/dev-environment/rust/setup). Make sure to select the **Desktop development with C++** workload when installing the tools.
- You've installed the [`wasm32-wasip1` target](https://doc.rust-lang.org/rustc/platform-support/wasm32-wasip1.html):
## Step 1: Create the validation function
To create a validation function, use Shopify CLI to [generate](/docs/api/shopify-cli/app/app-generate-extension) a starter function, specify the inputs for your function using an [input query](/docs/apps/build/functions/input-output/metafields-for-input-queries), and implement your function logic using JavaScript or Rust.
1. Navigate to your app directory:
1. Run the following command to create a new validation extension:
> Tip:
> Shopify Functions support any language that compiles to WebAssembly (Wasm), such as Rust, AssemblyScript, or TinyGo. You specify the Wasm template option when you're using a language other than Rust and can conform to the Wasm API. [Learn more about the Wasm API](/docs/apps/build/functions/programming-languages/webassembly-for-functions).
1. Choose the language that you want to use. For this tutorial, you should select either **Rust** or **JavaScript**.
Shopify defaults to Rust as the most performant and recommended language choice to stay within the platform limits. For more information, refer to [language considerations](/docs/apps/build/functions/programming-languages).
1. Navigate to the `extensions/cart-checkout-validation` directory:
1. Replace the contents of `src/run.graphql` file with the following code.
The `run.graphql` file defines the input for the function. You need to retrieve the quantity and merchandise ID of the current cart lines.
[Metafields](docs/apps/build/custom-data) allow your app to store custom data related to the validation function. Using the [`$app` reserved prefix](/docs/apps/build/custom-data/ownership#reserved-prefixes) makes the metafield private to your app.
> Note:
> The query differs slightly in Rust and JavaScript due to code generation requirements.
1. If you're using JavaScript, then run the following command to regenerate types based on your input query:
1. Replace the `src/run.rs` or `src/run.js` file with the following code.
The function logic checks that the quantity of each cart line isn't above the quantity set in the configuration metafield. You can configure the quantity limits for each product variant using the Admin UI extension that you will create in [step 2](#step-2-create-the-validation-user-interface-in-admin).
> Tip:
> You can associate a validation error with a specific checkout UI field, or a global error by specifying the `target` property. The `target` property follows the pattern that's provided in the [Cart and Checkout Validation API reference](/docs/api/functions/reference/cart-checkout-validation/graphql#supported-checkout-field-targets). For example, using the global target `$.cart` will result in a global error at the top of checkout.
2. If you're using Rust, then build the function's Wasm module:
If you encounter any errors, then ensure that you've [installed Rust and the `wasm32-wasip1` target](#requirements).
## Step 2: Create the validation user interface in admin
The following steps show how to build an [Admin UI extension](/docs/api/admin-extensions) that enables merchants to configure a validation function.

1. Navigate to your app directory:
1. Run the following command to create a new validation rule UI extension:
1. Choose the language that you want to use.
1. Navigate to the `extensions/validation-settings` directory:
1. Replace the validation settings UI code with the following code:
## Step 3: Link the user interface to the validation function
To link the Admin UI extension to the validation function, configure your validation function's TOML file. You can also configure the app's TOML file with necessary access scopes.
1. Navigate to the validation function directory:
1. Add the following code to the `shopify.extension.toml` file associated with the validation function:
1. Make sure that the `shopify.app.toml` file in your app root folder has the `read_products` access scope:
> Note:
> If you're adding new access scopes to an existing app, then you need to redeploy and reinstall the app on the store.
## Step 4: Test the validation on your development store
Run your development server and test the validation function and the corresponding Admin UI extension on your development store. You can test the validation behavior directly on checkout, or using the GraphQL Storefront API.
### Setup
1. If you're developing a function in a language other than JavaScript or TypeScript, ensure you have configured `build.watch` in your [function extension configuration](/docs/api/functions/configuration#properties).
1. Navigate back to your app root:
1. Use the Shopify CLI [`dev` command](/docs/api/shopify-cli/app/app-dev) to start app preview:
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 you can immediately test your changes.
1. Follow the CLI prompts to preview your app, and install it on your development store.
1. From the Shopify admin, go to **Settings** > **Checkout**.
1. Under **Checkout rules**, click **Add rule**. A new page opens and shows a list of checkout rules.

1. Find the `cart-checkout-validation` function that you want to test and select it.
1. In the validation configuration, set the limit to five for each product variant.
1. Click **Save**, but don't turn on the validation yet.
### Using checkout
1. Before turning on the validation, create a cart that exceeds the quantity limit you set. For example, in your development store, create a cart with a quantity of 10 products.
1. Go back to the checkout rules page in theShopify Admin and enable this validation by clicking on **Turn on**.
1. Optional. Control how checkout behaves when encountering runtime exceptions by selecting the validation under **Checkout rules** and toggling **Allow all customers to complete checkout**.
1. Complete a checkout in your online store and verify that the validation error message displays.

1. Verify that checkout progress is blocked. Clicking the **Continue to shipping** button in 3-page checkout, or the **Pay now** button in 1-page checkout, shouldn't redirect the user.
### Using GraphQL
1. You can also verify through the GraphQL Storefront API. Once the validation is turned on, create a cart with the [`cartCreate`](/docs/api/storefront/latest/mutations/cartCreate) mutation:
1. Using the Storefront API [`cartLinesAdd`](/docs/api/storefront/latest/mutations/cartLinesAdd) mutation, confirm that the mutation's `userErrors` field contains the function's error message, and that executing the mutation was unsuccessful.
### Debugging using logs
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.
1. Select the function execution from the top of the list. Press `q` to quit when you are finished debugging.
## Step 5: Deploy to production
When you're ready to release your changes to users, you can create and release an [app version](/docs/apps/launch/deployment/app-versions). An app version is a snapshot of your app configuration and all extensions.
1. Navigate to your app directory.
2. Run the following command.
Optionally, you can provide a name or message for the version using the `--version` and `--message` flags.
Releasing an app version replaces the current active version that's served to stores that have your app installed. It might take several minutes for app users to be upgraded to the new version.
> Tip:
> If you want to create a version, but avoid releasing it to users, then run the `deploy` command with a `--no-release` flag.
>
> You can release the unreleased app version using Shopify CLI's [`release`](/docs/api/shopify-cli/app/app-release) command, or through the Partner Dashboard.
## Next steps
- Learn more about how [Shopify Functions](/docs/apps/build/functions) work and the benefits of using Shopify Functions.
- Consult the [API references for Shopify Functions](/docs/api/functions).
- Learn how to use [variables](/docs/apps/build/functions/input-output/use-variables-input-queries) in your input query.