---
title: Product Discount Function API (deprecated)
description: >-
  Use the Product Discount Function API to create a new type of discount that's
  applied to particular product variants or cart lines.
api_version: 2026-10
source_url:
  html: 'https://shopify.dev/docs/api/functions/latest/product-discount'
  md: 'https://shopify.dev/docs/api/functions/latest/product-discount.md'
api_type: functions
api_name: product-discount
---

# Product Discount Function API (deprecated)

**Deprecated:**

This is a deprecated API. You should migrate to the [Discount Function API](https://shopify.dev/docs/api/functions/latest/discount#product-discount-function-api-and-order-discount-function-api), which provides a unified schema for creating discount function extensions.

[Product discounts](https://shopify.dev/docs/apps/build/discounts#discount-classes) are discounts on the price of specific products that merchants offer to encourage sales. They can be set as a percentage off, a fixed amount off, or as part of a buy X get Y offer. Product discounts can be [combined with other discount classes](https://help.shopify.com/manual/discounts/discount-combinations) under certain conditions. To create a new type of discount that's applied to particular product variants or cart lines, and isn't [offered out of the box by Shopify](https://help.shopify.com/manual/discounts/discount-types), you can only use the Product Discount API.

[Shopify Functions](https://shopify.dev/docs/api/functions/current) enable you to customize Shopify's backend logic. The Product Discount API integrates this logic into the checkout flow.

Use the API to create custom product discount functionality, with associated data such as buyer identity, cost, and delivery groups.

### Use cases

* Offer a discount on a product or product variant.
* Offer a discount on a cart line, such as 10% off products with a name engraving option.
* Offer a discount on a specific quantity of a product for a specific amount.
* Offer a discount on a specific quantity of a product, and get additional quantities of the product at a discount.

## Function target

Checkout

### Compatibility with Shopify surfaces Supported (7) Partially supported (2) Unsupported (5)

* [B2B](https://shopify.dev/docs/apps/build/b2b): Supported

* [Cart](https://shopify.dev/docs/storefronts/themes/architecture/templates/cart): Supported

* [Checkout](https://shopify.dev/docs/apps/build/checkout): Supported

* [Create Order API](https://shopify.dev/docs/api/admin-graphql/latest/mutations/orderCreate): Not supported

* [Draft Order (Admin)](https://shopify.dev/docs/apps/build/b2b/draft-orders): Partially supported

  This option is disabled by default.

* [Draft Order (Checkout)](https://shopify.dev/docs/apps/build/b2b/draft-orders): Partially supported

  This option is disabled by default.

* [Order Edit (Admin)](https://shopify.dev/docs/apps/build/orders-fulfillment/order-management-apps/edit-orders): Not supported

* [Order Edit (Checkout)](https://shopify.dev/docs/apps/build/orders-fulfillment/order-management-apps/edit-orders): Not supported

* [POS](https://shopify.dev/docs/apps/build/pos): Supported

* [Pre-order and Try Before You Buy](https://shopify.dev/docs/apps/build/purchase-options/deferred): Not supported

* [Shopify Admin](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries#creating-your-merchant-interface): Supported

* [Storefront](https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/): Supported

* [Storefront Accelerated Checkout](https://shopify.dev/docs/storefronts/themes/pricing-payments/accelerated-checkout): Supported

* [Subscription (Recurring Orders)](https://shopify.dev/docs/apps/build/purchase-options/subscriptions): Not supported

***

## Getting started

Scaffolding the function using [Shopify CLI](https://shopify.dev/docs/api/shopify-cli) will automatically configure your TOML file. You can alter the default [configuration](https://shopify.dev/docs/api/functions/2026-10#configuration) to customize the way your function operates.

## Terminal

```terminal
shopify app generate extension --template product_discounts
```

***

## Targets

A [target](https://shopify.dev/docs/apps/build/app-extensions/configure-app-extensions#targets) is an identifier in `shopify.extension.toml` that specifies where you're injecting code into Shopify Function APIs, or other parts of the Shopify platform. Each target is composed of three to four namespaces. The name begins with a broad Shopify context and ends with the behavior of the extensible element.

***

### Run target

`purchase.product-discount.run`

The run target applies discounts to products, using Shopify data or hardcoded values. The target returns a list of discounts and strategies to be applied to each item in a cart.

For example, you might use this to offer a specific quantity of a product for a specific amount, such as $5.00 off up to 2 blue shirts.

* Input

  OBJECT

  The `Input` object is the complete GraphQL schema that your function can query as input to customize discounts. Your function receives only the fields that you request in the input query. To optimize performance, we highly recommend that you request only the fields that your function requires.

  * cart

    Cart!

    non-null

    The cart where the Function is running. A cart contains the merchandise that a customer intends to purchase and information about the customer, such as the customer's email address and phone number.

    * attribute

      Attribute

      The custom attributes associated with a cart to store additional information. Cart attributes allow you to collect specific information from customers on the **Cart** page, such as order notes, gift wrapping requests, or custom product details. Attributes are stored as key-value pairs.

      * key

        String

        ### Arguments

        The key of the cart attribute to retrieve. For example, `"gift_wrapping"`.

      ***

      * key

        String!

        non-null

        ### Fields

        The key or name of the attribute. For example, `"customer_first_order"`.

      * value

        String

        The value of the attribute. For example, `"true"`.

    * billing​Address

      Mailing​Address

      The billing address associated with the cart.

      * address1

        String

        The first line of the address. Typically the street address or PO Box number.

      * address2

        String

        The second line of the address. Typically the number of the apartment, suite, or unit.

      * city

        String

        The name of the city, district, village, or town.

      * company

        String

        The name of the customer's company or organization.

      * country​Code

        Country​Code

        The two-letter code for the country of the address. For example, US.

        * AC, AD, AE, AF, AG, AI, AL, AM, AN, AO, AR, AT, AU, AW, AX, AZ, BA, BB, BD, BE, BF, BG, BH, BI, BJ, BL, BM, BN, BO, BQ, BR, BS, BT, BV, BW, BY, BZ, CA, CC, CD, CF, CG, CH, CI, CK, CL, CM, CN, CO, CR, CU, CV, CW, CX, CY, CZ, DE, DJ, DK, DM, DO, DZ, EC, EE, EG, EH, ER, ES, ET, FI, FJ, FK, FO, FR, GA, GB, GD, GE, GF, GG, GH, GI, GL, GM, GN, GP, GQ, GR, GS, GT, GW, GY, HK, HM, HN, HR, HT, HU, ID, IE, IL, IM, IN, IO, IQ, IR, IS, IT, JE, JM, JO, JP, KE, KG, KH, KI, KM, KN, KP, KR, KW, KY, KZ, LA, LB, LC, LI, LK, LR, LS, LT, LU, LV, LY, MA, MC, MD, ME, MF, MG, MK, ML, MM, MN, MO, MQ, MR, MS, MT, MU, MV, MW, MX, MY, MZ, NA, NC, NE, NF, NG, NI, NL, NO, NP, NR, NU, NZ, OM, PA, PE, PF, PG, PH, PK, PL, PM, PN, PS, PT, PY, QA, RE, RO, RS, RU, RW, SA, SB, SC, SD, SE, SG, SH, SI, SJ, SK, SL, SM, SN, SO, SR, SS, ST, SV, SX, SY, SZ, TA, TC, TD, TF, TG, TH, TJ, TK, TL, TM, TN, TO, TR, TT, TV, TW, TZ, UA, UG, UM, US, UY, UZ, VA, VC, VE, VG, VN, VU, WF, WS, XK, YE, YT, ZA, ZM, ZW, ZZ

      * first​Name

        String

        The first name of the customer.

      * last​Name

        String

        The last name of the customer.

      * latitude

        Float

        The approximate latitude of the address.

      * longitude

        Float

        The approximate longitude of the address.

      * name

        String

        The full name of the customer, based on firstName and lastName.

      * phone

        String

        A unique phone number for the customer. Formatted using E.164 standard. For example, +16135551111.

      * province​Code

        String

        The alphanumeric code for the region. For example, ON.

      * zip

        String

        The zip or postal code of the address.

      * market

        Market

        Deprecated

        * handle

          Handle!

          non-null

          A human-readable unique string for the market automatically generated from its title.

        * id

          ID!

          non-null

          A globally-unique identifier.

        * metafield

          Metafield

          A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

          * namespace

            String

            ### Arguments

            A category that organizes a group of metafields. Namespaces are used to prevent naming conflicts between different apps or different parts of the same app. If omitted, then the [app-reserved namespace](https://shopify.dev/docs/apps/build/custom-data/ownership) is used.

          * key

            String!

            required

            The unique identifier for the metafield within its namespace. A metafield is composed of a namespace and a key, in the format `namespace.key`.

          ***

          * json​Value

            JSON!

            non-null

            ### Fields

            The data that's stored in the metafield, using JSON format.

          * type

            String!

            non-null

            The [type of data](https://shopify.dev/apps/metafields/types) that the metafield stores in the `value` field.

          * value

            String!

            non-null

            The data that's stored in the metafield. The data is always stored as a string, regardless of the [metafield's type](https://shopify.dev/apps/metafields/types).

        * regions

          \[Market​Region!]!

          non-null

          A geographic region which comprises a market.

          * name

            String

            The name of the region in the language of the current localization.

    * buyer​Identity

      Buyer​Identity

      Information about the customer that's interacting with the cart. It includes details such as the customer's email and phone number, and the total amount of money the customer has spent in the store. This information helps personalize the checkout experience and ensures that accurate pricing and delivery options are displayed to customers.

      * customer

        Customer

        The [customer](https://help.shopify.com/manual/customers/manage-customers) that's interacting with the cart.

        * amount​Spent

          Money​V2!

          non-null

          The total amount that the customer has spent on orders. The amount is converted from the shop's currency to the currency of the cart using a market rate.

          * amount

            Decimal!

            non-null

            A monetary value in decimal format, allowing for precise representation of cents or fractional currency. For example, 12.99.

          * currency​Code

            Currency​Code!

            non-null

            The three-letter currency code that represents a world currency used in a store. Currency codes include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, and non-standard codes. For example, USD.

            * AED, AFN, ALL, AMD, AOA, ARS, AUD, AWG, AZN, BAM, BBD, BDT, BGN, BHD, BIF, BMD, BND, BOB, BRL, BSD, BTN, BWP, BYN, BZD, CAD, CDF, CHF, CLP, CNY, COP, CRC, CVE, CZK, DJF, DKK, DOP, DZD, EGP, ERN, ETB, EUR, FJD, FKP, GBP, GEL, GHS, GIP, GMD, GNF, GTQ, GYD, HKD, HNL, HRK, HTG, HUF, IDR, ILS, INR, IQD, IRR, ISK, JEP, JMD, JOD, JPY, KES, KGS, KHR, KID, KMF, KRW, KWD, KYD, KZT, LAK, LBP, LKR, LRD, LSL, LTL, LVL, LYD, MAD, MDL, MGA, MKD, MMK, MNT, MOP, MRU, MUR, MVR, MWK, MXN, MYR, MZN, NAD, NGN, NIO, NOK, NPR, NZD, OMR, PAB, PEN, PGK, PHP, PKR, PLN, PYG, QAR, RON, RSD, RUB, RWF, SAR, SBD, SCR, SDG, SEK, SGD, SHP, SLL, SOS, SRD, SSP, STN, SYP, SZL, THB, TJS, TMT, TND, TOP, TRY, TTD, TWD, TZS, UAH, UGX, USD, USDC, UYU, UZS, VED, VES, VND, VUV, WST, XAF, XCD, XCG, XOF, XPF, XXX, YER, ZAR, ZMW, ANG, BYR, STD, VEF

        * created​At

          Date​Time!

          non-null

          The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) at which the customer was created in Shopify.

        * display​Name

          String!

          non-null

          The full name of the customer, based on the values for `firstName` and `lastName`. If `firstName` and `lastName` aren't specified, then the value is the customer's email address. If the email address isn't specified, then the value is the customer's phone number.

        * email

          String

          The customer's email address.

        * first​Name

          String

          The customer's first name.

        * has​Any​Tag

          Boolean!

          non-null

          Whether the customer is associated with any of the specified tags. The customer must have at least one tag from the list to return `true`.

          * tags

            \[String!]!

            requiredDefault:\[]

            ### Arguments

            A comma-separated list of searchable keywords that are associated with the customer. For example, `"VIP, Gold"` returns customers with either the `VIP` or `Gold` tag.

          ***

        * has​Tags

          \[Has​Tag​Response!]!

          non-null

          Whether the customer is associated with the specified tags.

          * tags

            \[String!]!

            requiredDefault:\[]

            ### Arguments

            A comma-separated list of searchable keywords that are associated with the customer. For example, `"VIP, Gold"` returns customers with both the `VIP` and `Gold` tags.

          ***

          * has​Tag

            Boolean!

            non-null

            ### Fields

            Whether the Shopify resource has the tag.

          * tag

            String!

            non-null

            A searchable keyword that's associated with a Shopify resource, such as a product or customer. For example, a merchant might apply the `sports` and `summer` tags to products that are associated with sportswear for summer.

        * id

          ID!

          non-null

          A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) for the customer.

        * last​Name

          String

          The customer's last name.

        * metafield

          Metafield

          A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

        * number​Of​Orders

          Int!

          non-null

          The total number of orders that the customer has made at the store.

      * email

        String

        The email address of the customer that's interacting with the cart.

      * is​Authenticated

        Boolean!

        non-null

        Whether the customer is authenticated through their [customer account](https://help.shopify.com/manual/customers/customer-accounts).

      * phone

        String

        The phone number of the customer that's interacting with the cart.

      * purchasing​Company

        Purchasing​Company

        The company of a B2B customer that's interacting with the cart. Used to manage and track purchases made by businesses rather than individual customers.

        * company

          Company!

          non-null

          The company associated to the order or draft order.

          * created​At

            Date​Time!

            non-null

            The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) at which the company was created in Shopify.

          * external​Id

            String

            A unique externally-supplied ID for the company.

          * id

            ID!

            non-null

            The ID of the company.

          * metafield

            Metafield

            A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

          * name

            String!

            non-null

            The name of the company.

          * updated​At

            Date​Time!

            non-null

            The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) at which the company was last modified.

        * contact

          Company​Contact

          The company contact associated to the order or draft order.

          * created​At

            Date​Time!

            non-null

            The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) at which the company contact was created in Shopify.

          * id

            ID!

            non-null

            The ID of the company.

          * locale

            String

            The company contact's locale (language).

          * title

            String

            The company contact's job title.

          * updated​At

            Date​Time!

            non-null

            The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) at which the company contact was last modified.

        * location

          Company​Location!

          non-null

          The company location associated to the order or draft order.

          * created​At

            Date​Time!

            non-null

            The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) at which the company location was created in Shopify.

          * external​Id

            String

            A unique externally-supplied ID for the company.

          * id

            ID!

            non-null

            The ID of the company.

          * locale

            String

            The preferred locale of the company location.

          * metafield

            Metafield

            A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

          * name

            String!

            non-null

            The name of the company location.

          * orders​Count

            Int!

            non-null

            The number of orders placed at this company location.

          * total​Spent

            Money​V2!

            non-null

            The total amount spent at this company location.

            * amount

              Decimal!

              non-null

              A monetary value in decimal format, allowing for precise representation of cents or fractional currency. For example, 12.99.

            * currency​Code

              Currency​Code!

              non-null

              The three-letter currency code that represents a world currency used in a store. Currency codes include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, and non-standard codes. For example, USD.

          * updated​At

            Date​Time!

            non-null

            The date and time ([ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601)) at which the company location was last modified.

      * shop​User

        Shop​User

        Represents the [Shop User](https://help.shopify.com/en/manual/online-sales-channels/shop/sign-in-features) corresponding to the customer within the shop, if the buyer is a Shop User. Can be used to request [Shop User metafields](https://shopify.dev/docs/api/shop-user-custom-data).

        * metafield

          Metafield

          A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

    * cost

      Cart​Cost!

      non-null

      A breakdown of the costs that the customer will pay at checkout. It includes the total amount, the subtotal before taxes and duties, the tax amount, and duty charges.

      * subtotal​Amount

        Money​V2!

        non-null

        The amount, before taxes and cart-level discounts, for the customer to pay.

        * amount

          Decimal!

          non-null

          A monetary value in decimal format, allowing for precise representation of cents or fractional currency. For example, 12.99.

        * currency​Code

          Currency​Code!

          non-null

          The three-letter currency code that represents a world currency used in a store. Currency codes include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, and non-standard codes. For example, USD.

      * total​Amount

        Money​V2!

        non-null

        The total amount for the customer to pay at checkout.

        * amount

          Decimal!

          non-null

          A monetary value in decimal format, allowing for precise representation of cents or fractional currency. For example, 12.99.

        * currency​Code

          Currency​Code!

          non-null

          The three-letter currency code that represents a world currency used in a store. Currency codes include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, and non-standard codes. For example, USD.

      * total​Duty​Amount

        Money​V2

        The duty charges for a customer to pay at checkout.

        * amount

          Decimal!

          non-null

          A monetary value in decimal format, allowing for precise representation of cents or fractional currency. For example, 12.99.

        * currency​Code

          Currency​Code!

          non-null

          The three-letter currency code that represents a world currency used in a store. Currency codes include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, and non-standard codes. For example, USD.

      * total​Tax​Amount

        Money​V2

        The total tax amount for the customer to pay at checkout.

        * amount

          Decimal!

          non-null

          A monetary value in decimal format, allowing for precise representation of cents or fractional currency. For example, 12.99.

        * currency​Code

          Currency​Code!

          non-null

          The three-letter currency code that represents a world currency used in a store. Currency codes include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, and non-standard codes. For example, USD.

    * deliverable​Lines

      \[Deliverable​Cart​Line!]!

      non-null

      The items in a cart that are eligible for fulfillment and can be delivered to the customer.

      * attribute

        Attribute

        The custom attributes associated with a cart to store additional information. Cart attributes allow you to collect specific information from customers on the **Cart** page, such as order notes, gift wrapping requests, or custom product details. Attributes are stored as key-value pairs.

        Cart line attributes are equivalent to the [`line_item`](https://shopify.dev/docs/api/liquid/objects/line_item) object in Liquid.

      * id

        ID!

        non-null

        The ID of the cart line.

      * merchandise

        Merchandise!

        non-null

        The item that the customer intends to purchase.

        * Custom​Product

          OBJECT

          A custom product represents a product that doesn't map to Shopify's [standard product categories](https://help.shopify.com/manual/products/details/product-type). For example, you can use a custom product to manage gift cards, shipping requirements, localized product information, or weight measurements and conversions.

          * is​Gift​Card

            Boolean!

            non-null

            Whether the merchandise is a gift card.

          * requires​Shipping

            Boolean!

            non-null

            Whether the item needs to be shipped to the customer. For example, a digital gift card doesn't need to be shipped, but a t-shirt does need to be shipped.

          * title

            String!

            non-null

            The localized name for the product that displays to customers. The title is used to construct the product's handle, which is a unique, human-readable string of the product's title. For example, if a product is titled "Black Sunglasses", then the handle is `black-sunglasses`.

          * weight

            Float

            The product variant's weight, in the system of measurement set in the `weightUnit` field.

          * weight​Unit

            Weight​Unit!

            non-null

            The unit of measurement for weight.

            * GRAMS, KILOGRAMS, OUNCES, POUNDS

        * Product​Variant

          OBJECT

          A specific version of a product that comes in more than one option, such as size or color. For example, if a merchant sells t-shirts with options for size and color, then a small, blue t-shirt would be one product variant and a large, blue t-shirt would be another.

          * id

            ID!

            non-null

            A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) for the product variant.

          * in​Any​Collection

            Boolean!

            non-null

            Whether the product variant is in any of the specified collections. The variant must be in at least one collection from the list to return `true`. A variant is considered to be in a collection when the variant itself is a member of the collection, or when its product is a member of the collection.

            A collection is a group of products that can be displayed in online stores and other sales channels in categories, which makes it easy for customers to find them. For example, an athletics store might create different collections for running attire and accessories.

          * in​Collections

            \[Collection​Membership!]!

            non-null

            Whether the product variant is in each of the specified collections. A variant is considered to be in a collection when the variant itself is a member of the collection, or when its product is a member of the collection.

            A collection is a group of products that can be displayed in online stores and other sales channels in categories, which makes it easy for customers to find them. For example, an athletics store might create different collections for running attire and accessories.

            * ids

              \[ID!]!

              requiredDefault:\[]

              ### Arguments

              A list of [globally-unique collection IDs](https://shopify.dev/docs/api/usage/gids) to check membership against. For example, `gid://shopify/Collection/123`, `gid://shopify/Collection/456`.

            ***

            * collection​Id

              ID!

              non-null

              ### Fields

              A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) for the collection.

            * is​Member

              Boolean!

              non-null

              Whether the product is in the specified collection.

          * metafield

            Metafield

            A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

          * product

            Product!

            non-null

            The product associated with the product variant. For example, if a merchant sells t-shirts with options for size and color, then a small, blue t-shirt would be one product variant and a large, blue t-shirt would be another. The product associated with the product variant would be the t-shirt itself.

            * handle

              Handle!

              non-null

              A unique, human-readable string of the product's title. A handle can contain letters, hyphens (`-`), and numbers, but not spaces. The handle is used in the online store URL for the product. For example, if a product is titled "Black Sunglasses", then the handle is `black-sunglasses`.

            * has​Any​Tag

              Boolean!

              non-null

              Whether the product is associated with any of the specified tags. The product must have at least one tag from the list to return `true`.

            * has​Tags

              \[Has​Tag​Response!]!

              non-null

              Whether the product is associated with the specified tags.

            * id

              ID!

              non-null

              A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) for the product.

            * in​Any​Collection

              Boolean!

              non-null

              Whether the product is in any of the specified collections. The product must be in at least one collection from the list to return `true`.

              A collection is a group of products that can be displayed in online stores and other sales channels in categories, which makes it easy for customers to find them. For example, an athletics store might create different collections for running attire and accessories.

            * in​Collections

              \[Collection​Membership!]!

              non-null

              Whether the product is in the specified collections. The product must be in all of the collections in the list to return `true`.

              A collection is a group of products that can be displayed in online stores and other sales channels in categories, which makes it easy for customers to find them. For example, an athletics store might create different collections for running attire and accessories.

            * is​Gift​Card

              Boolean!

              non-null

              Whether the product is a gift card.

            * metafield

              Metafield

              A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

            * product​Type

              String

              A custom category for a product. Product types allow merchants to define categories other than the ones available in Shopify's [standard product categories](https://help.shopify.com/manual/products/details/product-type).

            * title

              String!

              non-null

              The localized name for the product that displays to customers. The title is used to construct the product's handle, which is a unique, human-readable string of the product's title. For example, if a product is titled "Black Sunglasses", then the handle is `black-sunglasses`.

            * vendor

              String

              The name of the product's vendor.

          * requires​Shipping

            Boolean!

            non-null

            Whether the item needs to be shipped to the customer. For example, a digital gift card doesn't need to be shipped, but a t-shirt does need to be shipped.

          * sku

            String

            A case-sensitive identifier for the product variant in the merchant's store. For example, `"BBC-1"`. A product variant must have a SKU to be connected to a [fulfillment service](https://shopify.dev/docs/apps/build/orders-fulfillment/fulfillment-service-apps/build-for-fulfillment-services).

          * title

            String

            The localized name for the product variant that displays to customers.

          * weight

            Float

            The product variant's weight, in the system of measurement set in the `weightUnit` field.

          * weight​Unit

            Weight​Unit!

            non-null

            The unit of measurement for weight.

      * quantity

        Int!

        non-null

        The quantity of the item that the customer intends to purchase.

    * delivery​Groups

      \[Cart​Delivery​Group!]!

      non-null

      A collection of items that are grouped by shared delivery characteristics. Delivery groups streamline fulfillment by organizing items that can be shipped together, based on the customer's shipping address. For example, if a customer orders a t-shirt and a pair of shoes that can be shipped together, then the items are included in the same delivery group.

      In the [Order Discount](https://shopify.dev/docs/api/functions/reference/order-discounts) and [Product Discount](https://shopify.dev/docs/api/functions/reference/product-discounts) legacy APIs, the `cart.deliveryGroups` input is always an empty array. This means you can't access delivery groups when creating Order Discount or Product Discount Functions. If you need to apply discounts to shipping costs, then use the [Discount Function API](https://shopify.dev/docs/api/functions/reference/discount) instead.

      * cart​Lines

        \[Cart​Line!]!

        non-null

        Information about items in a cart that a customer intends to purchase. A cart line is an entry in the customer's cart that represents a single unit of a product variant. For example, if a customer adds two different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line.

        * attribute

          Attribute

          The custom attributes associated with a cart to store additional information. Cart attributes allow you to collect specific information from customers on the **Cart** page, such as order notes, gift wrapping requests, or custom product details. Attributes are stored as key-value pairs.

          Cart line attributes are equivalent to the [`line_item`](https://shopify.dev/docs/api/liquid/objects/line_item) object in Liquid.

        * cost

          Cart​Line​Cost!

          non-null

          The cost of an item in a cart that the customer intends to purchase. Cart lines are entries in the customer's cart that represent a single unit of a product variant. For example, if a customer adds two different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line.

        * discount​Allocations

          \[Discount​Allocation!]!

          non-null

          The discounts that have been applied to the cart line.

          * discount​Application

            Discount​Application!

            non-null

            The discount that was applied.

            * allocation​Method

              Discount​Application​Allocation​Method!

              non-null

              The method by which the discount's value is allocated to its entitled items.

              * ACROSS, EACH

            * metafield

              Metafield

              A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

            * target​Selection

              Discount​Application​Target​Selection!

              non-null

              The lines on the cart targeted by the discount.

              * ALL, ENTITLED, EXPLICIT

            * target​Type

              Discount​Application​Target!

              non-null

              The type of line (i.e. line item or shipping line) on a cart that the discount is applicable towards.

              * LINE_ITEM, SHIPPING_LINE

            * total​Allocated​Amount

              Money​V2!

              non-null

              The total allocated amount of the discount across all items.

              * amount

                Decimal!

                non-null

                A monetary value in decimal format, allowing for precise representation of cents or fractional currency. For example, 12.99.

              * currency​Code

                Currency​Code!

                non-null

                The three-letter currency code that represents a world currency used in a store. Currency codes include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, and non-standard codes. For example, USD.

            * value

              Pricing​Value!

              non-null

              The value of the discount.

              * Money​V2

                OBJECT

                A precise monetary value and its associated currency. Combines a decimal amount with a three-letter currency code to express prices, costs, and other financial values throughout the API. For example, 12.99 USD.

                * amount

                  Decimal!

                  non-null

                  A monetary value in decimal format, allowing for precise representation of cents or fractional currency. For example, 12.99.

                * currency​Code

                  Currency​Code!

                  non-null

                  The three-letter currency code that represents a world currency used in a store. Currency codes include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, and non-standard codes. For example, USD.

              * Pricing​Percentage​Value

                OBJECT

                The percentage value of a discount.

                * value

                  Decimal!

                  non-null

                  The percentage value of the discount.

          * discounted​Amount

            Money​V2!

            non-null

            The amount that was discounted.

            * amount

              Decimal!

              non-null

              A monetary value in decimal format, allowing for precise representation of cents or fractional currency. For example, 12.99.

            * currency​Code

              Currency​Code!

              non-null

              The three-letter currency code that represents a world currency used in a store. Currency codes include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, and non-standard codes. For example, USD.

        * id

          ID!

          non-null

          The ID of the cart line.

        * merchandise

          Merchandise!

          non-null

          The item that the customer intends to purchase.

        * parent​Relationship

          Cart​Line​Parent​Relationship

          The [nested relationship](https://shopify.dev/docs/apps/build/product-merchandising/nested-cart-lines) between this line and its parent line, if any.

          * parent

            Cart​Line!

            non-null

            The parent line in the relationship.

        * quantity

          Int!

          non-null

          The quantity of the item that the customer intends to purchase.

        * selling​Plan​Allocation

          Selling​Plan​Allocation

          The [selling plan](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/selling-plans) associated with the cart line, including information about how a product variant can be sold and purchased.

          * price​Adjustments

            \[Selling​Plan​Allocation​Price​Adjustment!]!

            non-null

            A list of price adjustments, with a maximum of two. When there are two, the first price adjustment goes into effect at the time of purchase, while the second one starts after a certain number of orders. A price adjustment represents how a selling plan affects pricing when a variant is purchased with a selling plan. Prices display in the customer's currency if the shop is configured for it.

            * per​Delivery​Price

              Money​V2!

              non-null

              The effective price for a single delivery. For example, for a prepaid subscription plan that includes 6 deliveries at the price of $48.00, the per delivery price is $8.00.

              * amount

                Decimal!

                non-null

                A monetary value in decimal format, allowing for precise representation of cents or fractional currency. For example, 12.99.

              * currency​Code

                Currency​Code!

                non-null

                The three-letter currency code that represents a world currency used in a store. Currency codes include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, and non-standard codes. For example, USD.

            * price

              Money​V2!

              non-null

              The price of the variant when it's purchased with a selling plan For example, for a prepaid subscription plan that includes 6 deliveries of $10.00 granola, where the customer gets 20% off, the price is 6 x $10.00 x 0.80 = $48.00.

              * amount

                Decimal!

                non-null

                A monetary value in decimal format, allowing for precise representation of cents or fractional currency. For example, 12.99.

              * currency​Code

                Currency​Code!

                non-null

                The three-letter currency code that represents a world currency used in a store. Currency codes include standard [standard ISO 4217 codes](https://en.wikipedia.org/wiki/ISO_4217), legacy codes, and non-standard codes. For example, USD.

          * selling​Plan

            Selling​Plan!

            non-null

            A representation of how products and variants can be sold and purchased. For example, an individual selling plan could be '6 weeks of prepaid granola, delivered weekly'.

            * description

              String

              The description of the selling plan.

            * id

              ID!

              non-null

              A globally-unique identifier.

            * metafield

              Metafield

              A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

            * name

              String!

              non-null

              The name of the selling plan. For example, '6 weeks of prepaid granola, delivered weekly'.

            * recurring​Deliveries

              Boolean!

              non-null

              Whether purchasing the selling plan will result in multiple deliveries.

      * delivery​Address

        Mailing​Address

        The shipping or destination address associated with the delivery group.

        * address1

          String

          The first line of the address. Typically the street address or PO Box number.

        * address2

          String

          The second line of the address. Typically the number of the apartment, suite, or unit.

        * city

          String

          The name of the city, district, village, or town.

        * company

          String

          The name of the customer's company or organization.

        * country​Code

          Country​Code

          The two-letter code for the country of the address. For example, US.

        * first​Name

          String

          The first name of the customer.

        * last​Name

          String

          The last name of the customer.

        * latitude

          Float

          The approximate latitude of the address.

        * longitude

          Float

          The approximate longitude of the address.

        * name

          String

          The full name of the customer, based on firstName and lastName.

        * phone

          String

          A unique phone number for the customer. Formatted using E.164 standard. For example, +16135551111.

        * province​Code

          String

          The alphanumeric code for the region. For example, ON.

        * zip

          String

          The zip or postal code of the address.

        * market

          Market

          Deprecated

      * delivery​Options

        \[Cart​Delivery​Option!]!

        non-null

        The delivery options available for the delivery group. Delivery options are the different ways that customers can choose to have their orders shipped. Examples include express shipping or standard shipping.

        * code

          String

          A unique identifier that represents the delivery option offered to customers. For example, `Canada Post Expedited`.

        * cost

          Money​V2!

          non-null

          The amount that the customer pays if they select the delivery option.

        * delivery​Method​Type

          Delivery​Method!

          non-null

          The delivery method associated with the delivery option. A delivery method is a way that merchants can fulfill orders from their online stores. Delivery methods include shipping to an address, [local pickup](https://help.shopify.com/manual/fulfillment/setup/delivery-methods/pickup-in-store), and shipping to a [pickup point](https://help.shopify.com/manual/fulfillment/shopify-shipping/pickup-points), all of which are natively supported by Shopify checkout.

          * LOCAL, NONE, PICK_UP, PICKUP_POINT, RETAIL, SHIPPING

        * description

          String

          A single-line description of the delivery option, with HTML tags removed.

        * handle

          Handle!

          non-null

          A unique, human-readable identifier of the delivery option's title. A handle can contain letters, hyphens (`-`), and numbers, but not spaces. For example, `standard-shipping`.

        * metafield

          Metafield

          A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

        * title

          String

          The name of the delivery option that displays to customers. The title is used to construct the delivery option's handle. For example, if a delivery option is titled "Standard Shipping", then the handle is `standard-shipping`.

      * discount​Allocations

        \[Discount​Allocation!]!

        non-null

        The discounts that have been applied to the delivery group.

      * group​Type

        Cart​Delivery​Group​Type!

        non-null

        The type of merchandise in the delivery group.

        * ONE_TIME_PURCHASE, SUBSCRIPTION

      * id

        ID!

        non-null

        A [globally-unique ID](https://shopify.dev/docs/api/usage/gids) for the delivery group.

      * selected​Delivery​Option

        Cart​Delivery​Option

        Information about the delivery option that the customer has selected.

        * code

          String

          A unique identifier that represents the delivery option offered to customers. For example, `Canada Post Expedited`.

        * cost

          Money​V2!

          non-null

          The amount that the customer pays if they select the delivery option.

        * delivery​Method​Type

          Delivery​Method!

          non-null

          The delivery method associated with the delivery option. A delivery method is a way that merchants can fulfill orders from their online stores. Delivery methods include shipping to an address, [local pickup](https://help.shopify.com/manual/fulfillment/setup/delivery-methods/pickup-in-store), and shipping to a [pickup point](https://help.shopify.com/manual/fulfillment/shopify-shipping/pickup-points), all of which are natively supported by Shopify checkout.

        * description

          String

          A single-line description of the delivery option, with HTML tags removed.

        * handle

          Handle!

          non-null

          A unique, human-readable identifier of the delivery option's title. A handle can contain letters, hyphens (`-`), and numbers, but not spaces. For example, `standard-shipping`.

        * metafield

          Metafield

          A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

        * title

          String

          The name of the delivery option that displays to customers. The title is used to construct the delivery option's handle. For example, if a delivery option is titled "Standard Shipping", then the handle is `standard-shipping`.

    * discount​Applications

      \[Discount​Application!]!

      non-null

      The discounts that have been applied to the cart.

      * allocation​Method

        Discount​Application​Allocation​Method!

        non-null

        The method by which the discount's value is allocated to its entitled items.

      * metafield

        Metafield

        A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

      * target​Selection

        Discount​Application​Target​Selection!

        non-null

        The lines on the cart targeted by the discount.

      * target​Type

        Discount​Application​Target!

        non-null

        The type of line (i.e. line item or shipping line) on a cart that the discount is applicable towards.

      * total​Allocated​Amount

        Money​V2!

        non-null

        The total allocated amount of the discount across all items.

      * value

        Pricing​Value!

        non-null

        The value of the discount.

    * lines

      \[Cart​Line!]!

      non-null

      The items in a cart that the customer intends to purchase. A cart line is an entry in the customer's cart that represents a single unit of a product variant. For example, if a customer adds two different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line.

      * attribute

        Attribute

        The custom attributes associated with a cart to store additional information. Cart attributes allow you to collect specific information from customers on the **Cart** page, such as order notes, gift wrapping requests, or custom product details. Attributes are stored as key-value pairs.

        Cart line attributes are equivalent to the [`line_item`](https://shopify.dev/docs/api/liquid/objects/line_item) object in Liquid.

      * cost

        Cart​Line​Cost!

        non-null

        The cost of an item in a cart that the customer intends to purchase. Cart lines are entries in the customer's cart that represent a single unit of a product variant. For example, if a customer adds two different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line.

      * discount​Allocations

        \[Discount​Allocation!]!

        non-null

        The discounts that have been applied to the cart line.

      * id

        ID!

        non-null

        The ID of the cart line.

      * merchandise

        Merchandise!

        non-null

        The item that the customer intends to purchase.

      * parent​Relationship

        Cart​Line​Parent​Relationship

        The [nested relationship](https://shopify.dev/docs/apps/build/product-merchandising/nested-cart-lines) between this line and its parent line, if any.

      * quantity

        Int!

        non-null

        The quantity of the item that the customer intends to purchase.

      * selling​Plan​Allocation

        Selling​Plan​Allocation

        The [selling plan](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/selling-plans) associated with the cart line, including information about how a product variant can be sold and purchased.

    * localized​Fields

      \[Localized​Field!]!

      non-null

      The additional fields on the **Cart** page that are required for international orders in specific countries, such as customs information or tax identification numbers.

      * keys

        \[Localized​Field​Key!]!

        requiredDefault:\[]

        ### Arguments

        The keys of the localized fields to retrieve.

        * SHIPPING_CREDENTIAL_BR, SHIPPING_CREDENTIAL_CL, SHIPPING_CREDENTIAL_CN, SHIPPING_CREDENTIAL_CO, SHIPPING_CREDENTIAL_CR, SHIPPING_CREDENTIAL_EC, SHIPPING_CREDENTIAL_ES, SHIPPING_CREDENTIAL_GT, SHIPPING_CREDENTIAL_ID, SHIPPING_CREDENTIAL_KR, SHIPPING_CREDENTIAL_MX, SHIPPING_CREDENTIAL_MY, SHIPPING_CREDENTIAL_PE, SHIPPING_CREDENTIAL_PT, SHIPPING_CREDENTIAL_PY, SHIPPING_CREDENTIAL_TR, SHIPPING_CREDENTIAL_TW, SHIPPING_CREDENTIAL_TYPE_CO, TAX_CREDENTIAL_BR, TAX_CREDENTIAL_CL, TAX_CREDENTIAL_CO, TAX_CREDENTIAL_CR, TAX_CREDENTIAL_EC, TAX_CREDENTIAL_ES, TAX_CREDENTIAL_GT, TAX_CREDENTIAL_ID, TAX_CREDENTIAL_IT, TAX_CREDENTIAL_MX, TAX_CREDENTIAL_MY, TAX_CREDENTIAL_PE, TAX_CREDENTIAL_PT, TAX_CREDENTIAL_PY, TAX_CREDENTIAL_TR, TAX_CREDENTIAL_TYPE_CO, TAX_CREDENTIAL_TYPE_MX, TAX_CREDENTIAL_USE_MX, TAX_EMAIL_IT

      ***

      * key

        Localized​Field​Key!

        non-null

        ### Fields

        The key of the localized field.

        * SHIPPING_CREDENTIAL_BR, SHIPPING_CREDENTIAL_CL, SHIPPING_CREDENTIAL_CN, SHIPPING_CREDENTIAL_CO, SHIPPING_CREDENTIAL_CR, SHIPPING_CREDENTIAL_EC, SHIPPING_CREDENTIAL_ES, SHIPPING_CREDENTIAL_GT, SHIPPING_CREDENTIAL_ID, SHIPPING_CREDENTIAL_KR, SHIPPING_CREDENTIAL_MX, SHIPPING_CREDENTIAL_MY, SHIPPING_CREDENTIAL_PE, SHIPPING_CREDENTIAL_PT, SHIPPING_CREDENTIAL_PY, SHIPPING_CREDENTIAL_TR, SHIPPING_CREDENTIAL_TW, SHIPPING_CREDENTIAL_TYPE_CO, TAX_CREDENTIAL_BR, TAX_CREDENTIAL_CL, TAX_CREDENTIAL_CO, TAX_CREDENTIAL_CR, TAX_CREDENTIAL_EC, TAX_CREDENTIAL_ES, TAX_CREDENTIAL_GT, TAX_CREDENTIAL_ID, TAX_CREDENTIAL_IT, TAX_CREDENTIAL_MX, TAX_CREDENTIAL_MY, TAX_CREDENTIAL_PE, TAX_CREDENTIAL_PT, TAX_CREDENTIAL_PY, TAX_CREDENTIAL_TR, TAX_CREDENTIAL_TYPE_CO, TAX_CREDENTIAL_TYPE_MX, TAX_CREDENTIAL_USE_MX, TAX_EMAIL_IT

      * title

        String!

        non-null

        The title of the localized field.

      * value

        String

        The value of the localized field.

    * metafield

      Metafield

      A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

    * po​Number

      String

      A purchase order number associated with the cart, often used for B2B transactions to reference the buyer's internal purchase order.

    * retail​Location

      Location

      The physical location where a retail order is created or completed.

      * address

        Location​Address!

        non-null

        The address of this location.

        * address1

          String

          The first line of the address for the location.

        * address2

          String

          The second line of the address for the location.

        * city

          String

          The city of the location.

        * country

          String

          The country of the location.

        * country​Code

          String

          The country code of the location.

        * formatted

          \[String!]!

          non-null

          A formatted version of the address for the location.

        * latitude

          Float

          The approximate latitude coordinates of the location.

        * longitude

          Float

          The approximate longitude coordinates of the location.

        * phone

          String

          The phone number of the location.

        * province

          String

          The province of the location.

        * province​Code

          String

          The code for the province, state, or district of the address of the location.

        * zip

          String

          The ZIP code of the location.

      * handle

        Handle!

        non-null

        The location handle.

      * id

        ID!

        non-null

        The location id.

      * metafield

        Metafield

        A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

      * name

        String!

        non-null

        The name of the location.

  * discount​Node

    Discount​Node!

    non-null

    A wrapper around the discount that executes the Function. The `discountNode` field enables you to manage [discounts](https://help.shopify.com/manual/discounts), which are applied at checkout or on a cart.

    * metafield

      Metafield

      A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

  * localization

    Localization!

    non-null

    The regional and language settings that determine how the Function handles currency, numbers, dates, and other locale-specific values during discount calculations. These settings are based on the store's configured [localization practices](https://shopify.dev/docs/apps/build/functions/localization-practices-shopify-functions).

    * country

      Country!

      non-null

      The country for which the store is customized, reflecting local preferences and regulations. Localization might influence the language, currency, and product offerings available in a store to enhance the shopping experience for customers in that region.

      * iso​Code

        Country​Code!

        non-null

        The ISO code of the country.

        * AC, AD, AE, AF, AG, AI, AL, AM, AN, AO, AR, AT, AU, AW, AX, AZ, BA, BB, BD, BE, BF, BG, BH, BI, BJ, BL, BM, BN, BO, BQ, BR, BS, BT, BV, BW, BY, BZ, CA, CC, CD, CF, CG, CH, CI, CK, CL, CM, CN, CO, CR, CU, CV, CW, CX, CY, CZ, DE, DJ, DK, DM, DO, DZ, EC, EE, EG, EH, ER, ES, ET, FI, FJ, FK, FO, FR, GA, GB, GD, GE, GF, GG, GH, GI, GL, GM, GN, GP, GQ, GR, GS, GT, GW, GY, HK, HM, HN, HR, HT, HU, ID, IE, IL, IM, IN, IO, IQ, IR, IS, IT, JE, JM, JO, JP, KE, KG, KH, KI, KM, KN, KP, KR, KW, KY, KZ, LA, LB, LC, LI, LK, LR, LS, LT, LU, LV, LY, MA, MC, MD, ME, MF, MG, MK, ML, MM, MN, MO, MQ, MR, MS, MT, MU, MV, MW, MX, MY, MZ, NA, NC, NE, NF, NG, NI, NL, NO, NP, NR, NU, NZ, OM, PA, PE, PF, PG, PH, PK, PL, PM, PN, PS, PT, PY, QA, RE, RO, RS, RU, RW, SA, SB, SC, SD, SE, SG, SH, SI, SJ, SK, SL, SM, SN, SO, SR, SS, ST, SV, SX, SY, SZ, TA, TC, TD, TF, TG, TH, TJ, TK, TL, TM, TN, TO, TR, TT, TV, TW, TZ, UA, UG, UM, US, UY, UZ, VA, VC, VE, VG, VN, VU, WF, WS, XK, YE, YT, ZA, ZM, ZW, ZZ

    * language

      Language!

      non-null

      The language for which the store is customized, ensuring content is tailored to local customers. This includes product descriptions and customer communications that resonate with the target audience.

      * iso​Code

        Language​Code!

        non-null

        The ISO code.

    * market

      Market!

      non-nullDeprecated

  * presentment​Currency​Rate

    Decimal!

    non-null

    The exchange rate used to convert discounts between the shop's default currency and the currency that displays to the customer during checkout. For example, if a store operates in USD but a customer is viewing discounts in EUR, then the presentment currency rate handles this conversion for accurate pricing.

  * shop

    Shop!

    non-null

    Information about the shop where the Function is running, including the shop's timezone setting and associated [metafields](https://shopify.dev/docs/apps/build/custom-data).

    * local​Time

      Local​Time!

      non-null

      The current time based on the [store's timezone setting](https://help.shopify.com/manual/intro-to-shopify/initial-setup/setup-business-settings).

      * date

        Date!

        non-null

        The current date relative to the parent object.

      * date​Time​After

        Boolean!

        non-null

        Returns true if the current date and time is at or past the given date and time, and false otherwise.

      * date​Time​Before

        Boolean!

        non-null

        Returns true if the current date and time is before the given date and time, and false otherwise.

      * date​Time​Between

        Boolean!

        non-null

        Returns true if the current date and time is between the two given date and times, and false otherwise.

      * time​After

        Boolean!

        non-null

        Returns true if the current time is at or past the given time, and false otherwise.

      * time​Before

        Boolean!

        non-null

        Returns true if the current time is at or past the given time, and false otherwise.

      * time​Between

        Boolean!

        non-null

        Returns true if the current time is between the two given times, and false otherwise.

    * metafield

      Metafield

      A [custom field](https://shopify.dev/docs/apps/build/custom-data) that stores additional information about a Shopify resource, such as products, orders, and [many more](https://shopify.dev/docs/api/admin-graphql/latest/enums/MetafieldOwnerType). Using [metafields with Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/metafields-for-input-queries) enables you to customize the checkout experience.

    * metaobject

      Metaobject

      Fetch a specific Metaobject by one of its unique identifiers. Only app-owned metaobjects with the $app reserved prefix are accessible to functions.

      * handle

        Metaobject​Handle​Input

        ### Arguments

        The handle and type of the metaobject.

        * handle

          String!

          non-null

          The handle of the metaobject to retrieve.

        * type

          String!

          non-null

          The type of the metaobject. Must match an existing metaobject definition type.

      * id

        ID

        The ID of the metaobject.

      ***

      * field

        Metaobject​Field

        ### Fields

        The field for an object key, or null if the key has no field definition.

        * key

          String!

          required

          ### Arguments

          The metaobject key to access.

        ***

        * json​Value

          JSON

          ### Fields

          The assigned field value in JSON format.

        * key

          String!

          non-null

          The object key of this field.

        * type

          String!

          non-null

          The type of the field.

        * value

          String

          The assigned field value, always stored as a string regardless of the field type.

      * handle

        String!

        non-null

        The unique handle of the metaobject, useful as a custom ID.

      * type

        String!

        non-null

        The type of the metaobject.

#### Run function

The logic that processes the input data. The function generates a list of discounts and strategies to apply to cart items.

The list of discounts and strategies specifies the applicable discount types, target items, and conditions that need to be met to apply the discount. Shopify processes your response to determine how to calculate discounts on products in a cart.

This return must follow the schema defined in the `FunctionRunResult` object.

* Function​Run​Result

  OBJECT

  The `FunctionRunResult` object is the output of the function run target. The object contains the list of discounts and strategies to apply to each item in a cart.

  * discount​Application​Strategy

    Discount​Application​Strategy!

    non-null

    The approach that determines how multiple discounts are evaluated and applied to a cart. You can apply all discounts with conditions that are met, apply a discount only to the first line item in a cart that meets conditions, or apply only the discount that offers a maximum price reduction.

    * ALL, FIRST, MAXIMUM

  * discounts

    \[Discount!]!

    non-null

    The list of discounts that are applied to product variants or line items in a cart. It includes data such as the discount value and the message associated with the discount.

    * message

      String

      A notification on the **Cart** page informs customers about available discounts. If an automatic discount applies, the notification displays this message, such as "Save 20% on all t-shirts." If a discount code is entered, the notification displays the code instead.

    * targets

      \[Target!]!

      non-null

      The method for applying the discount to products. This argument accepts a collection of either `ProductVariantTarget` or `CartLineTarget`, but not both.

      The `ProductVariantTarget` is used to target a specific product variant. A product variant is a specific version of a product that comes in more than one option, such as size or color. For example, if a merchant sells t-shirts with options for size and color, then a small, blue t-shirt would be one product variant and a large, blue t-shirt would be another.

      The `CartLineTarget` is used to target a specific line item in the cart. A cart line is an entry in the customer's cart that represents a single unit of a product variant. For example, if a customer adds two different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line.

      * cart​Line

        Cart​Line​Target

        A method for applying a discount to a specific line item in the cart. A cart line is an entry in the customer's cart that represents a single unit of a product variant. For example, if a customer adds two different sizes of the same t-shirt to their cart, then each size is represented as a separate cart line.

        * id

          ID!

          non-null

          The ID of the targeted cart line.

        * quantity

          Int

          The number of line items that are being discounted. The default value is `null`, which represents the quantity of the matching line items.

          The value is validated against: > 0.

      * product​Variant

        Product​Variant​Target

        A method for applying a discount to a [product variant](https://help.shopify.com/manual/products/variants). Product variants are the different versions of a product that can be purchased. For example, if a customer orders a t-shirt in a specific size and color, the t-shirt is a product variant. The discount can be applied to all product variants in the order, or to specific product variants that meet certain criteria.

        * id

          ID!

          non-null

          The ID of the targeted product variant.

        * quantity

          Int

          The maximum number of line item units to be discounted. The default value is `null`, which represents the total quantity of the matching line items.

          The value is validated against: > 0.

    * value

      Value!

      non-null

      The value of the discount. The value can be a fixed amount, like $5 (5.0), or a percentage, such as 10% (0.1).

Examples

* ### Apply a discount to the first cart line

  This example implements a Shopify function that gives a 20% off the first line in the cart.

  #### Entrypoint (Rust)

  ```rust
  use shopify_function::prelude::*;
  use std::process;

  pub mod run;

  #[typegen("./schema.graphql")]
  pub mod schema {
      #[query("src/run.graphql")]
      pub mod run {}
  }

  fn main() {
      log!("Please invoke a named export.");
      process::abort();
  }
  ```

  #### purchase.product-discount.run

  ##### Input Query (Rust)

  ```graphql
  query Input {
    cart {
      lines {
        id
      }
    }
  }
  ```

  ##### Input Query (JavaScript)

  ```graphql
  query RunInput {
    cart {
      lines {
        id
      }
    }
  }
  ```

  ##### Input Object (Rust)

  ```json
  {
    "cart": {
      "lines": [
        {
          "id": "gid://shopify/CartLine/1"
        }
      ]
    }
  }
  ```

  ##### Input Object (JavaScript)

  ```json
  {
    "cart": {
      "lines": [
        {
          "id": "gid://shopify/CartLine/1"
        }
      ]
    }
  }
  ```

  ##### Function Code (Rust)

  ```rust
  use crate::schema;
  use shopify_function::prelude::*;
  use shopify_function::Result;

  #[shopify_function]
  fn run(input: schema::run::Input) -> Result<schema::FunctionRunResult> {
      let mut discounts = vec![];
      let percentage = 20.0;

      // Check if there are any lines in the cart
      if let Some(first_line) = input.cart().lines().first() {
          discounts.push(schema::Discount {
              value: schema::Value::Percentage(schema::Percentage {
                  value: Decimal(percentage),
              }),
              targets: vec![schema::Target::CartLine(schema::CartLineTarget {
                  id: first_line.id().clone(),
                  quantity: None,
              })],
              message: Some(format!("{}% off first item", percentage)),
          });
      }

      Ok(schema::FunctionRunResult {
          discounts,
          discount_application_strategy: schema::DiscountApplicationStrategy::First,
      })
  }
  ```

  ##### Performance Cost (Rust)

  15564 instructions

  ##### Function Code (JavaScript)

  ```javascript
  // @ts-check
  import { DiscountApplicationStrategy } from "../generated/api";

  /**
   * @typedef {import("../generated/api").RunInput} RunInput
   * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult
   */

  /**
   * @param {RunInput} input
   * @returns {FunctionRunResult}
   */
  export function run(input) {
    const discounts = [];
    const percentage = 20;

    // Early return if no cart lines
    if (!input.cart.lines.length) {
      return {
        discounts,
        discountApplicationStrategy: DiscountApplicationStrategy.First,
      };
    }

    discounts.push({
      value: {
        percentage: {
          value: String(percentage.toFixed(1)),
        },
      },
      targets: [{
        cartLine: {
          id: input.cart.lines[0].id,
        },
      }],
      message: percentage + "% off first item",
    });

    return {
      discounts,
      discountApplicationStrategy: DiscountApplicationStrategy.First,
    };
  } 
  ```

  ##### Performance Cost (JavaScript)

  155591 instructions

  ##### Output JSON (Rust)

  ```json
  {
    "discountApplicationStrategy": "FIRST",
    "discounts": [
      {
        "message": "20% off first item",
        "targets": [
          {
            "cartLine": {
              "id": "gid://shopify/CartLine/1"
            }
          }
        ],
        "value": {
          "percentage": {
            "value": "20.0"
          }
        }
      }
    ]
  }
  ```

  ##### Output JSON (JavaScript)

  ```json
  {
    "discountApplicationStrategy": "FIRST",
    "discounts": [
      {
        "message": "20% off first item",
        "targets": [
          {
            "cartLine": {
              "id": "gid://shopify/CartLine/1"
            }
          }
        ],
        "value": {
          "percentage": {
            "value": "20.0"
          }
        }
      }
    ]
  }
  ```

* ### Apply an amount-off discount to specific products

  This example implements a Shopify function that gives a configurable amount of discount off a number of product variants. The configuration is stored in an app owned metafield.

  #### Entrypoint (Rust)

  ```rust
  use shopify_function::prelude::*;
  use std::process;

  pub mod run;

  #[typegen("./schema.graphql")]
  pub mod schema {
      #[query("src/run.graphql", custom_scalar_overrides = {"Input.discountNode.metafield.jsonValue" => super::run::Configuration})]
      pub mod run {}
  }

  fn main() {
      log!("Please invoke a named export.");
      process::abort();
  }
  ```

  #### purchase.product-discount.run

  ##### Input Query (Rust)

  ```graphql
  query Input {
    cart {
      lines {
        id
        quantity
        merchandise {
          __typename
          ... on ProductVariant {
            id
            title
          }
        }
      }
    }
    discountNode {
      metafield(namespace: "$app", key: "function-configuration") {
        jsonValue
      }
    }
  }
  ```

  ##### Input Query (JavaScript)

  ```graphql
  query RunInput {
    cart {
      lines {
        id
        quantity
        merchandise {
          __typename
          ... on ProductVariant {
            id
            title
          }
        }
      }
    }
    discountNode {
      metafield(namespace: "$app", key: "function-configuration") {
        jsonValue
      }
    }
  }
  ```

  ##### Input Object (Rust)

  ```json
  {
    "cart": {
      "lines": [
        {
          "id": "gid://shopify/CartLine/1",
          "quantity": 2,
          "merchandise": {
            "__typename": "ProductVariant",
            "id": "gid://shopify/ProductVariant/1234567890",
            "title": "Small / Black"
          }
        },
        {
          "id": "gid://shopify/CartLine/2",
          "quantity": 1,
          "merchandise": {
            "__typename": "ProductVariant",
            "id": "gid://shopify/ProductVariant/9876543210",
            "title": "Medium / Blue"
          }
        }
      ]
    },
    "discountNode": {
      "metafield": {
        "jsonValue": {
          "percentage": 15,
          "targetVariantIds": [
            "gid://shopify/ProductVariant/1234567890",
            "gid://shopify/ProductVariant/9876543210"
          ]
        }
      }
    }
  }
  ```

  ##### Input Object (JavaScript)

  ```json
  {
    "cart": {
      "lines": [
        {
          "id": "gid://shopify/CartLine/1",
          "quantity": 2,
          "merchandise": {
            "__typename": "ProductVariant",
            "id": "gid://shopify/ProductVariant/1234567890",
            "title": "Small / Black"
          }
        },
        {
          "id": "gid://shopify/CartLine/2",
          "quantity": 1,
          "merchandise": {
            "__typename": "ProductVariant",
            "id": "gid://shopify/ProductVariant/9876543210",
            "title": "Medium / Blue"
          }
        }
      ]
    },
    "discountNode": {
      "metafield": {
        "jsonValue": {
          "percentage": 15,
          "targetVariantIds": [
            "gid://shopify/ProductVariant/1234567890",
            "gid://shopify/ProductVariant/9876543210"
          ]
        }
      }
    }
  }
  ```

  ##### Function Code (Rust)

  ```rust
  use crate::schema;
  use shopify_function::prelude::*;
  use shopify_function::Result;

  #[derive(Deserialize, Default, PartialEq)]
  #[shopify_function(rename_all = "camelCase")]
  pub struct Configuration {
      percentage: f64,
      target_variant_ids: Vec<String>,
  }

  #[shopify_function]
  fn run(input: schema::run::Input) -> Result<schema::FunctionRunResult> {
      let config: &Configuration = match input.discount_node().metafield() {
          Some(metafield) => metafield.json_value(),
          None => {
              return Ok(schema::FunctionRunResult {
                  discounts: vec![],
                  discount_application_strategy: schema::DiscountApplicationStrategy::First,
              })
          }
      };

      let mut discounts = vec![];

      for line in input.cart().lines().iter() {
          let variant = match &line.merchandise() {
              schema::run::input::cart::lines::Merchandise::ProductVariant(variant) => variant,
              _ => continue,
          };

          if config.target_variant_ids.contains(variant.id()) {
              let message = match &variant.title() {
                  Some(title) => format!("{}% off {}!", config.percentage, title),
                  None => format!("{}% off this product!", config.percentage),
              };

              discounts.push(schema::Discount {
                  value: schema::Value::Percentage(schema::Percentage {
                      value: Decimal::from(config.percentage),
                  }),
                  targets: vec![schema::Target::ProductVariant(
                      schema::ProductVariantTarget {
                          id: variant.id().clone(),
                          quantity: Some(*line.quantity()),
                      },
                  )],
                  message: Some(message),
              });
          }
      }

      Ok(schema::FunctionRunResult {
          discounts,
          discount_application_strategy: schema::DiscountApplicationStrategy::First,
      })
  }
  ```

  ##### Performance Cost (Rust)

  54941 instructions

  ##### Function Code (JavaScript)

  ```javascript
  // @ts-check
  import { DiscountApplicationStrategy } from "../generated/api";

  /**
   * @typedef {import("../generated/api").RunInput} RunInput
   * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult
   */

  /**
   * @type {FunctionRunResult}
   */
  const EMPTY_DISCOUNT = {
    discountApplicationStrategy: DiscountApplicationStrategy.First,
    discounts: [],
  };

  /**
   * @param {RunInput} input
   * @returns {FunctionRunResult}
   */
  export function run(input) {
    // Parse configuration from metafield
    const configuration = input?.discountNode?.metafield?.jsonValue ?? {};
    
    // Return empty discount if no configuration
    if (!configuration) {
      return EMPTY_DISCOUNT;
    }

    const discounts = [];

    // Return empty discount if no cart or lines
    if (!input.cart.lines) {
      return EMPTY_DISCOUNT;
    }

    // Process each cart line
    for (const line of input.cart.lines) {
      // Skip if not a product variant
      if (line.merchandise.__typename !== "ProductVariant") {
        continue;
      }

      // Check if variant is in target list
      if (configuration.targetVariantIds.includes(line.merchandise.id)) {
        const message = line.merchandise.title
          ? `${configuration.percentage}% off ${line.merchandise.title}!`
          : `${configuration.percentage}% off this product!`;

        discounts.push({
          value: {
            percentage: {
              value: configuration.percentage.toFixed(1).toString()
            }
          },
          targets: [
            {
              productVariant: {
                id: line.merchandise.id,
                quantity: line.quantity
              }
            }
          ],
          message
        });
      }
    }

    return {
      discountApplicationStrategy: DiscountApplicationStrategy.First,
      discounts
    };
  } 
  ```

  ##### Performance Cost (JavaScript)

  330217 instructions

  ##### Output JSON (Rust)

  ```json
  {
    "discountApplicationStrategy": "FIRST",
    "discounts": [
      {
        "message": "15% off Small / Black!",
        "targets": [
          {
            "productVariant": {
              "id": "gid://shopify/ProductVariant/1234567890",
              "quantity": 2
            }
          }
        ],
        "value": {
          "percentage": {
            "value": "15.0"
          }
        }
      },
      {
        "message": "15% off Medium / Blue!",
        "targets": [
          {
            "productVariant": {
              "id": "gid://shopify/ProductVariant/9876543210",
              "quantity": 1
            }
          }
        ],
        "value": {
          "percentage": {
            "value": "15.0"
          }
        }
      }
    ]
  }
  ```

  ##### Output JSON (JavaScript)

  ```json
  {
    "discountApplicationStrategy": "FIRST",
    "discounts": [
      {
        "message": "15% off Small / Black!",
        "targets": [
          {
            "productVariant": {
              "id": "gid://shopify/ProductVariant/1234567890",
              "quantity": 2
            }
          }
        ],
        "value": {
          "percentage": {
            "value": "15.0"
          }
        }
      },
      {
        "message": "15% off Medium / Blue!",
        "targets": [
          {
            "productVariant": {
              "id": "gid://shopify/ProductVariant/9876543210",
              "quantity": 1
            }
          }
        ],
        "value": {
          "percentage": {
            "value": "15.0"
          }
        }
      }
    ]
  }
  ```

* ### Apply a fixed amount discount to a product

  This example implements a Shopify function that gives a configurable amount of discount off an item. The configuration is stored in an app owned metafield.

  #### Entrypoint (Rust)

  ```rust
  use shopify_function::prelude::*;
  use std::process;

  pub mod run;

  #[typegen("./schema.graphql")]
  pub mod schema {
      #[query("src/run.graphql", custom_scalar_overrides = {"Input.discountNode.metafield.jsonValue" => super::run::Configuration})]
      pub mod run {}
  }

  fn main() {
      log!("Please invoke a named export.");
      process::abort();
  }
  ```

  #### purchase.product-discount.run

  ##### Input Query (Rust)

  ```graphql
  query Input {
    cart {
      lines {
        id
        quantity
        merchandise {
          __typename
          ... on ProductVariant {
            id
            product {
              id
            }
          }
        }
      }
    }
    discountNode {
      metafield(namespace: "$app", key: "function-configuration") {
        jsonValue
      }
    }
  }
  ```

  ##### Input Query (JavaScript)

  ```graphql
  query RunInput {
    cart {
      lines {
        id
        quantity
        merchandise {
          __typename
          ... on ProductVariant {
            id
            product {
              id
            }
          }
        }
      }
    }
    discountNode {
      metafield(namespace: "$app", key: "function-configuration") {
        jsonValue
      }
    }
  }
  ```

  ##### Input Object (Rust)

  ```json
  {
    "cart": {
      "lines": [
        {
          "id": "gid://shopify/CartLine/1",
          "quantity": 3,
          "merchandise": {
            "__typename": "ProductVariant",
            "id": "gid://shopify/ProductVariant/1",
            "product": {
              "id": "gid://shopify/Product/1"
            }
          }
        }
      ]
    },
    "discountNode": {
      "metafield": {
        "jsonValue": {
          "discountAmount": 10.0,
          "maxQuantity": 2,
          "productId": "gid://shopify/Product/1"
        }
      }
    }
  }
  ```

  ##### Input Object (JavaScript)

  ```json
  {
    "cart": {
      "lines": [
        {
          "id": "gid://shopify/CartLine/1",
          "quantity": 3,
          "merchandise": {
            "__typename": "ProductVariant",
            "id": "gid://shopify/ProductVariant/1",
            "product": {
              "id": "gid://shopify/Product/1"
            }
          }
        }
      ]
    },
    "discountNode": {
      "metafield": {
        "jsonValue": {
          "discountAmount": 10.0,
          "maxQuantity": 2,
          "productId": "gid://shopify/Product/1"
        }
      }
    }
  }
  ```

  ##### Function Code (Rust)

  ```rust
  use crate::schema;
  use shopify_function::prelude::*;
  use shopify_function::Result;

  #[derive(Deserialize, Default, PartialEq)]
  #[shopify_function(rename_all = "camelCase")]
  pub struct Configuration {
      discount_amount: f64,
      max_quantity: i32,
      product_id: String,
  }

  #[shopify_function]
  fn run(input: schema::run::Input) -> Result<schema::FunctionRunResult> {
      let config: &Configuration = match input.discount_node().metafield() {
          Some(metafield) => metafield.json_value(),
          None => {
              return Ok(schema::FunctionRunResult {
                  discounts: vec![],
                  discount_application_strategy: schema::DiscountApplicationStrategy::First,
              })
          }
      };

      let mut discounts = vec![];
      let mut remaining_quantity = config.max_quantity;

      for line in input.cart().lines().iter() {
          let variant = match &line.merchandise() {
              schema::run::input::cart::lines::Merchandise::ProductVariant(variant) => variant,
              _ => continue,
          };

          if *variant.product().id() == config.product_id && remaining_quantity > 0 {
              let line_quantity = line.quantity();
              let discount_quantity = remaining_quantity.min(*line_quantity);
              remaining_quantity -= discount_quantity;

              discounts.push(schema::Discount {
                  value: schema::Value::FixedAmount(schema::FixedAmount {
                      amount: config.discount_amount.into(),
                      applies_to_each_item: Some(true),
                  }),
                  targets: vec![schema::Target::ProductVariant(
                      schema::ProductVariantTarget {
                          id: variant.id().clone(),
                          quantity: Some(discount_quantity),
                      },
                  )],
                  message: Some("Discount applied".to_string()),
              });
          }
      }

      Ok(schema::FunctionRunResult {
          discounts,
          discount_application_strategy: schema::DiscountApplicationStrategy::First,
      })
  }
  ```

  ##### Performance Cost (Rust)

  33006 instructions

  ##### Function Code (JavaScript)

  ```javascript
  // @ts-check
  import { DiscountApplicationStrategy } from "../generated/api";

  /**
   * @typedef {import("../generated/api").RunInput} RunInput
   * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult
   * @typedef {{
   *   discount_amount: number,
   *   max_quantity: number,
   *   product_id: string
   * }} Configuration
   */

  /**
   * @type {FunctionRunResult}
   */
  const EMPTY_DISCOUNT = {
    discountApplicationStrategy: DiscountApplicationStrategy.First,
    discounts: [],
  };

  /**
   * @param {RunInput} input
   * @returns {FunctionRunResult}
   */
  export function run(input) {
    // Parse configuration from metafield
    /** @type {Configuration} */
    const configuration = input.discountNode.metafield?.jsonValue ?? "{}"

    
    if (!configuration.discountAmount || !configuration.maxQuantity || !configuration.productId) {
      return EMPTY_DISCOUNT;
    }

    const discounts = [];
    let remainingQuantity = configuration.maxQuantity;

    // Iterate through cart lines
    for (const line of input.cart.lines) {
      if (line.merchandise.__typename !== "ProductVariant") {
        continue;
      }

      if (line.merchandise.product.id === configuration.productId && remainingQuantity > 0) {
        const lineQuantity = line.quantity;
        const discountQuantity = Math.min(remainingQuantity, lineQuantity);
        remainingQuantity -= discountQuantity;

        discounts.push({
          value: {
            fixedAmount: {
              amount: configuration.discountAmount.toFixed(1).toString(),
              appliesToEachItem: true
            }
          },
          targets: [{
            productVariant: {
              id: line.merchandise.id,
              quantity: discountQuantity
            }
          }],
          message: "Discount applied"
        });
      }
    }

    return {
      discountApplicationStrategy: DiscountApplicationStrategy.First,
      discounts
    };
  }
  ```

  ##### Performance Cost (JavaScript)

  246890 instructions

  ##### Output JSON (Rust)

  ```json
  {
    "discountApplicationStrategy": "FIRST",
    "discounts": [
      {
        "message": "Discount applied",
        "targets": [
          {
            "productVariant": {
              "id": "gid://shopify/ProductVariant/1",
              "quantity": 2
            }
          }
        ],
        "value": {
          "fixedAmount": {
            "amount": "10.0",
            "appliesToEachItem": true
          }
        }
      }
    ]
  }
  ```

  ##### Output JSON (JavaScript)

  ```json
  {
    "discountApplicationStrategy": "FIRST",
    "discounts": [
      {
        "message": "Discount applied",
        "targets": [
          {
            "productVariant": {
              "id": "gid://shopify/ProductVariant/1",
              "quantity": 2
            }
          }
        ],
        "value": {
          "fixedAmount": {
            "amount": "10.0",
            "appliesToEachItem": true
          }
        }
      }
    ]
  }
  ```

* ### Apply a fixed amount discount with quantity limits

  This example implements a Shopify function that gives a configurable fixed amount discount off an cart line with a maximum quantity limit.

  #### Entrypoint (Rust)

  ```rust
  use shopify_function::prelude::*;
  use std::process;

  pub mod run;

  #[typegen("./schema.graphql")]
  pub mod schema {
      #[query("src/run.graphql", custom_scalar_overrides = {"Input.discountNode.metafield.jsonValue" => super::run::Configuration})]
      pub mod run {}
  }

  fn main() {
      log!("Please invoke a named export.");
      process::abort();
  }
  ```

  #### purchase.product-discount.run

  ##### Input Query (Rust)

  ```graphql
  query Input {
    cart {
      lines {
        id
        quantity
        merchandise {
          __typename
          ... on ProductVariant {
            id
            product {
              id
            }
          }
        }
      }
    }
    discountNode {
      metafield(namespace: "$app", key: "function-configuration") {
        jsonValue
      }
    }
  }
  ```

  ##### Input Query (JavaScript)

  ```graphql
  query RunInput {
    cart {
      lines {
        id
        quantity
        merchandise {
          __typename
          ... on ProductVariant {
            id
            product {
              id
            }
          }
        }
      }
    }
    discountNode {
      metafield(namespace: "$app", key: "function-configuration") {
        jsonValue
      }
    }
  }
  ```

  ##### Input Object (Rust)

  ```json
  {
    "cart": {
      "lines": [
        {
          "id": "gid://shopify/CartLine/1",
          "quantity": 2,
          "merchandise": {
            "__typename": "ProductVariant",
            "id": "gid://shopify/ProductVariant/1234567890",
            "product": {
              "id": "gid://shopify/Product/123"
            }
          }
        },
        {
          "id": "gid://shopify/CartLine/2",
          "quantity": 1,
          "merchandise": {
            "__typename": "ProductVariant",
            "id": "gid://shopify/ProductVariant/9876543210",
            "product": {
              "id": "gid://shopify/Product/456"
            }
          }
        }
      ]
    },
    "discountNode": {
      "metafield": {
        "jsonValue": {
          "discountAmount": 10.0,
          "maxQuantity": 1,
          "productId": "gid://shopify/Product/123"
        }
      }
    }
  }
  ```

  ##### Input Object (JavaScript)

  ```json
  {
    "cart": {
      "lines": [
        {
          "id": "gid://shopify/CartLine/1",
          "quantity": 2,
          "merchandise": {
            "__typename": "ProductVariant",
            "id": "gid://shopify/ProductVariant/1234567890",
            "product": {
              "id": "gid://shopify/Product/123"
            }
          }
        },
        {
          "id": "gid://shopify/CartLine/2",
          "quantity": 1,
          "merchandise": {
            "__typename": "ProductVariant",
            "id": "gid://shopify/ProductVariant/9876543210",
            "product": {
              "id": "gid://shopify/Product/456"
            }
          }
        }
      ]
    },
    "discountNode": {
      "metafield": {
        "jsonValue": {
          "discountAmount": 10.0,
          "maxQuantity": 1,
          "productId": "gid://shopify/Product/123"
        }
      }
    }
  }
  ```

  ##### Function Code (Rust)

  ```rust
  use crate::schema;
  use shopify_function::prelude::*;
  use shopify_function::Result;

  #[derive(Deserialize)]
  #[shopify_function(rename_all = "camelCase")]
  pub struct Configuration {
      discount_amount: f64,
      max_quantity: i32,
      product_id: String,
  }

  #[shopify_function]
  fn run(input: schema::run::Input) -> Result<schema::FunctionRunResult> {
      // Extract configuration from metafield
      let config = match input.discount_node().metafield() {
          Some(metafield) => metafield.json_value(),
          None => return Ok(empty_discount()),
      };

      let mut discounts = Vec::new();
      let mut remaining_quantity = config.max_quantity;

      // Process each cart line
      for line in input.cart().lines() {
          if let schema::run::input::cart::lines::Merchandise::ProductVariant(variant) =
              line.merchandise()
          {
              if *variant.product().id() == config.product_id && remaining_quantity > 0 {
                  let discount_quantity = std::cmp::min(remaining_quantity, *line.quantity());
                  remaining_quantity -= discount_quantity;

                  discounts.push(schema::Discount {
                      value: schema::Value::FixedAmount(schema::FixedAmount {
                          amount: Decimal::from(config.discount_amount),
                          applies_to_each_item: Some(true),
                      }),
                      targets: vec![schema::Target::CartLine(schema::CartLineTarget {
                          id: line.id().to_string(),
                          quantity: Some(discount_quantity),
                      })],
                      message: Some("Discount applied".to_string()),
                  });
              }
          }
      }

      Ok(schema::FunctionRunResult {
          discounts,
          discount_application_strategy: schema::DiscountApplicationStrategy::First,
      })
  }

  fn empty_discount() -> schema::FunctionRunResult {
      schema::FunctionRunResult {
          discounts: Vec::new(),
          discount_application_strategy: schema::DiscountApplicationStrategy::First,
      }
  }
  ```

  ##### Performance Cost (Rust)

  42601 instructions

  ##### Function Code (JavaScript)

  ```javascript
  // @ts-check
  import { DiscountApplicationStrategy } from "../generated/api";

  /**
   * @typedef {import("../generated/api").RunInput} RunInput
   * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult
   */

  /**
   * @type {FunctionRunResult}
   */
  const EMPTY_DISCOUNT = {
    discountApplicationStrategy: DiscountApplicationStrategy.First,
    discounts: [],
  };

  /**
   * @param {RunInput} input
   * @returns {FunctionRunResult}
   */
  export function run(input) {
    const configuration = input.discountNode.metafield?.jsonValue ?? {};
    
    if (!configuration.discountAmount || !configuration.maxQuantity || !configuration.productId) {
      return EMPTY_DISCOUNT;
    }

    const discounts = [];
    let remainingQuantity = configuration.maxQuantity;

    for (const line of input.cart.lines) {
      if (line.merchandise.__typename !== "ProductVariant") {
        continue;
      }

      if (line.merchandise.product.id === configuration.productId && remainingQuantity > 0) {
        const discountQuantity = Math.min(remainingQuantity, line.quantity);
        remainingQuantity -= discountQuantity;

        discounts.push({
          value: {
            fixedAmount: {
              amount: configuration.discountAmount.toFixed(1).toString(),
              appliesToEachItem: true,
            },
          },
          targets: [
            {
              cartLine: {
                id: line.id,
                quantity: discountQuantity,
              }
            },
          ],
          message: "Discount applied",
        });
      }
    }

    return {
      discounts,
      discountApplicationStrategy: DiscountApplicationStrategy.First,
    };
  }
  ```

  ##### Performance Cost (JavaScript)

  273742 instructions

  ##### Output JSON (Rust)

  ```json
  {
    "discountApplicationStrategy": "FIRST",
    "discounts": [
      {
        "message": "Discount applied",
        "targets": [
          {
            "cartLine": {
              "id": "gid://shopify/CartLine/1",
              "quantity": 1
            }
          }
        ],
        "value": {
          "fixedAmount": {
            "amount": "10.0",
            "appliesToEachItem": true
          }
        }
      }
    ]
  }
  ```

  ##### Output JSON (JavaScript)

  ```json
  {
    "discountApplicationStrategy": "FIRST",
    "discounts": [
      {
        "message": "Discount applied",
        "targets": [
          {
            "cartLine": {
              "id": "gid://shopify/CartLine/1",
              "quantity": 1
            }
          }
        ],
        "value": {
          "fixedAmount": {
            "amount": "10.0",
            "appliesToEachItem": true
          }
        }
      }
    ]
  }
  ```

* ### Apply percentage-off discounts to products with specific SKUs

  This example implements a Shopify function that gives a configurable discount to any cart line whose product variant has one of the specified SKUs. The SKUs and discount percentage are stored in an app-owned metafield.

  #### Entrypoint (Rust)

  ```rust
  use shopify_function::prelude::*;
  use std::process;

  pub mod run;

  #[typegen("./schema.graphql")]
  pub mod schema {
      #[query("src/run.graphql", custom_scalar_overrides = {"Input.discountNode.metafield.jsonValue" => super::run::Configuration})]
      pub mod run {}
  }

  fn main() {
      log!("Please invoke a named export.");
      process::abort();
  }
  ```

  #### purchase.product-discount.run

  ##### Input Query (Rust)

  ```graphql
  query Input {
    cart {
      lines {
        id
        quantity
        merchandise {
          __typename
          ... on ProductVariant {
            id
            sku
          }
        }
      }
    }
    discountNode {
      metafield(namespace: "$app", key: "function-configuration") {
        jsonValue
      }
    }
  }
  ```

  ##### Input Query (JavaScript)

  ```graphql
  query RunInput {
    cart {
      lines {
        id
        quantity
        merchandise {
          __typename
          ... on ProductVariant {
            id
            sku
          }
        }
      }
    }
    discountNode {
      metafield(namespace: "$app", key: "function-configuration") {
        jsonValue
      }
    }
  }
  ```

  ##### Input Object (Rust)

  ```json
  {
    "cart": {
      "lines": [
        {
          "id": "gid://shopify/CartLine/1",
          "quantity": 2,
          "merchandise": {
            "__typename": "ProductVariant",
            "id": "gid://shopify/ProductVariant/1",
            "sku": "DISC-SKU1"
          }
        }
      ]
    },
    "discountNode": {
      "metafield": {
        "jsonValue": {
          "percentage": 15.0,
          "targetSkus": [
            "DISC-SKU1",
            "DISC-SKU2",
            "SALE-SKU"
          ]
        }
      }
    }
  }
  ```

  ##### Input Object (JavaScript)

  ```json
  {
    "cart": {
      "lines": [
        {
          "id": "gid://shopify/CartLine/1",
          "quantity": 2,
          "merchandise": {
            "__typename": "ProductVariant",
            "id": "gid://shopify/ProductVariant/1",
            "sku": "DISC-SKU1"
          }
        }
      ]
    },
    "discountNode": {
      "metafield": {
        "jsonValue": {
          "percentage": 15.0,
          "targetSkus": [
            "DISC-SKU1",
            "DISC-SKU2",
            "SALE-SKU"
          ]
        }
      }
    }
  }
  ```

  ##### Function Code (Rust)

  ```rust
  use crate::schema;
  use shopify_function::prelude::*;
  use shopify_function::Result;

  #[derive(Deserialize, Default, PartialEq)]
  #[shopify_function(rename_all = "camelCase")]
  pub struct Configuration {
      percentage: f64,
      target_skus: Vec<String>,
  }

  #[shopify_function]
  fn run(input: schema::run::Input) -> Result<schema::FunctionRunResult> {
      let config: &Configuration = match input.discount_node().metafield() {
          Some(metafield) => metafield.json_value(),
          None => {
              return Ok(schema::FunctionRunResult {
                  discounts: vec![],
                  discount_application_strategy: schema::DiscountApplicationStrategy::First,
              })
          }
      };

      let mut discounts = vec![];

      for line in input.cart().lines() {
          let variant = match &line.merchandise() {
              schema::run::input::cart::lines::Merchandise::ProductVariant(variant) => variant,
              _ => continue,
          };

          // Check if the variant has a SKU and if it's in our target list
          if let Some(sku) = variant.sku() {
              if config.target_skus.contains(sku) {
                  discounts.push(schema::Discount {
                      value: schema::Value::Percentage(schema::Percentage {
                          value: Decimal(config.percentage),
                      }),
                      targets: vec![schema::Target::CartLine(schema::CartLineTarget {
                          id: line.id().to_string(),
                          quantity: Some(*line.quantity()),
                      })],
                      message: Some(format!("{}% off items with SKU {}", config.percentage, sku)),
                  });
              }
          }
      }

      Ok(schema::FunctionRunResult {
          discounts,
          discount_application_strategy: schema::DiscountApplicationStrategy::First,
      })
  }
  ```

  ##### Performance Cost (Rust)

  33904 instructions

  ##### Function Code (JavaScript)

  ```javascript
  // @ts-check
  import { DiscountApplicationStrategy } from "../generated/api";

  /**
   * @typedef {import("../generated/api").RunInput} RunInput
   * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult
   */

  /**
   * @type {FunctionRunResult}
   */
  const EMPTY_DISCOUNT = {
    discountApplicationStrategy: DiscountApplicationStrategy.First,
    discounts: [],
  };

  /**
   * @param {RunInput} input
   * @returns {FunctionRunResult}
   */
  export function run(input) {
    // Parse configuration from metafield
    const configuration = input.discountNode.metafield?.jsonValue ?? "{}";

    // If no configuration exists, return empty discount
    if (!configuration.percentage || !configuration.targetSkus) {
      return EMPTY_DISCOUNT;
    }

    const discounts = [];

    // Iterate through cart lines
    for (const line of input.cart.lines) {
      // Skip if not a product variant
      if (line.merchandise.__typename !== "ProductVariant") {
        continue;
      }

      // Check if the variant has a SKU and if it's in our target list
      const sku = line.merchandise.sku;
      if (sku && configuration.targetSkus.includes(sku)) {
        discounts.push({
          value: {
            percentage: {
              value: configuration.percentage.toFixed(1).toString()
            }
          },
          targets: [{
            cartLine: {
              id: line.id,
              quantity: line.quantity
            }
          }],
          message: `${configuration.percentage}% off items with SKU ${sku}`
        });
      }
    }

    return {
      discountApplicationStrategy: DiscountApplicationStrategy.First,
      discounts
    };
  }
  ```

  ##### Performance Cost (JavaScript)

  239712 instructions

  ##### Output JSON (Rust)

  ```json
  {
    "discountApplicationStrategy": "FIRST",
    "discounts": [
      {
        "message": "15% off items with SKU DISC-SKU1",
        "targets": [
          {
            "cartLine": {
              "id": "gid://shopify/CartLine/1",
              "quantity": 2
            }
          }
        ],
        "value": {
          "percentage": {
            "value": "15.0"
          }
        }
      }
    ]
  }
  ```

  ##### Output JSON (JavaScript)

  ```json
  {
    "discountApplicationStrategy": "FIRST",
    "discounts": [
      {
        "message": "15% off items with SKU DISC-SKU1",
        "targets": [
          {
            "cartLine": {
              "id": "gid://shopify/CartLine/1",
              "quantity": 2
            }
          }
        ],
        "value": {
          "percentage": {
            "value": "15.0"
          }
        }
      }
    ]
  }
  ```

* ### Apply additional discounts to products with compare-at prices

  This example implements a Shopify function that gives a configurable discount to any cart line whose product variant has a compare-at price higher than its current price. The discount percentage is stored in an app-owned metafield.

  #### Entrypoint (Rust)

  ```rust
  use shopify_function::prelude::*;
  use std::process;

  pub mod run;

  #[typegen("./schema.graphql")]
  pub mod schema {
      #[query("src/run.graphql", custom_scalar_overrides = {"Input.discountNode.metafield.jsonValue" => super::run::Configuration})]
      pub mod run {}
  }

  fn main() {
      log!("Please invoke a named export.");
      process::abort();
  }
  ```

  #### purchase.product-discount.run

  ##### Input Query (Rust)

  ```graphql
  query Input {
    cart {
      lines {
        id
        quantity
        cost {
          amountPerQuantity {
            amount
          }
          compareAtAmountPerQuantity {
            amount
          }
        }
      }
    }
    discountNode {
      metafield(namespace: "$app", key: "function-configuration") {
        jsonValue
      }
    }
  }
  ```

  ##### Input Query (JavaScript)

  ```graphql
  query RunInput {
    cart {
      lines {
        id
        quantity
        cost {
          amountPerQuantity {
            amount
          }
          compareAtAmountPerQuantity {
            amount
          }
        }
      }
    }
    discountNode {
      metafield(namespace: "$app", key: "function-configuration") {
        jsonValue
      }
    }
  }
  ```

  ##### Input Object (Rust)

  ```json
  {
    "cart": {
      "lines": [
        {
          "id": "gid://shopify/CartLine/1",
          "quantity": 1,
          "cost": {
            "amountPerQuantity": {
              "amount": "80.00"
            },
            "compareAtAmountPerQuantity": {
              "amount": "100.00"
            }
          }
        }
      ]
    },
    "discountNode": {
      "metafield": {
        "jsonValue": {
          "percentage": 10.0
        }
      }
    }
  }
  ```

  ##### Input Object (JavaScript)

  ```json
  {
    "cart": {
      "lines": [
        {
          "id": "gid://shopify/CartLine/1",
          "quantity": 1,
          "cost": {
            "amountPerQuantity": {
              "amount": "80.00"
            },
            "compareAtAmountPerQuantity": {
              "amount": "100.00"
            }
          }
        }
      ]
    },
    "discountNode": {
      "metafield": {
        "jsonValue": {
          "percentage": 10.0
        }
      }
    }
  }
  ```

  ##### Function Code (Rust)

  ```rust
  use crate::schema;
  use shopify_function::prelude::*;
  use shopify_function::Result;

  #[derive(Deserialize, Default, PartialEq)]
  #[shopify_function(rename_all = "camelCase")]
  pub struct Configuration {
      percentage: f64,
  }

  #[shopify_function]
  fn run(input: schema::run::Input) -> Result<schema::FunctionRunResult> {
      let config: &Configuration = match input.discount_node().metafield() {
          Some(metafield) => metafield.json_value(),
          None => {
              return Ok(schema::FunctionRunResult {
                  discounts: vec![],
                  discount_application_strategy: schema::DiscountApplicationStrategy::First,
              })
          }
      };

      let mut discounts = vec![];

      for line in input.cart().lines() {
          // Check if there's a compare-at price and if it's higher than the current price
          if let Some(compare_at_amount) = &line.cost().compare_at_amount_per_quantity() {
              let current_price = line.cost().amount_per_quantity().amount().0;
              let compare_at_price = compare_at_amount.amount().0;

              if compare_at_price > current_price {
                  discounts.push(schema::Discount {
                      value: schema::Value::Percentage(schema::Percentage {
                          value: Decimal(config.percentage),
                      }),
                      targets: vec![schema::Target::CartLine(schema::CartLineTarget {
                          id: line.id().to_string(),
                          quantity: Some(*line.quantity()),
                      })],
                      message: Some(format!(
                          "{}% off already discounted items",
                          config.percentage
                      )),
                  });
              }
          }
      }

      Ok(schema::FunctionRunResult {
          discounts,
          discount_application_strategy: schema::DiscountApplicationStrategy::First,
      })
  }
  ```

  ##### Performance Cost (Rust)

  31159 instructions

  ##### Function Code (JavaScript)

  ```javascript
  // @ts-check
  import { DiscountApplicationStrategy } from "../generated/api";

  /**
   * @typedef {import("../generated/api").RunInput} RunInput
   * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult
   */

  /**
   * @type {FunctionRunResult}
   */
  const EMPTY_DISCOUNT = {
    discountApplicationStrategy: DiscountApplicationStrategy.First,
    discounts: [],
  };

  /**
   * @param {RunInput} input
   * @returns {FunctionRunResult}
   */
  export function run(input) {
    // Parse configuration or return empty discount if no configuration exists
    const configuration = input.discountNode.metafield?.jsonValue ?? "{}"
    
    if (!configuration.percentage) {
      return EMPTY_DISCOUNT;
    }

    const discounts = [];

    // Iterate through cart lines
    for (const line of input.cart.lines) {
      const currentPrice = parseFloat(line.cost.amountPerQuantity.amount);
      const compareAtAmount = line.cost.compareAtAmountPerQuantity?.amount;

      // Check if there's a compare-at price and if it's higher than the current price
      if (compareAtAmount) {
        const compareAtPrice = parseFloat(compareAtAmount);
        
        if (compareAtPrice > currentPrice) {
          discounts.push({
            value: {
              percentage: {
                value: configuration.percentage.toFixed(1).toString()
              }
            },
            targets: [{
              cartLine: {
                id: line.id,
                quantity: line.quantity
              }
            }],
            message: `${configuration.percentage}% off already discounted items`
          });
        }
      }
    }

    return {
      discountApplicationStrategy: DiscountApplicationStrategy.First,
      discounts
    };
  }
  ```

  ##### Performance Cost (JavaScript)

  237919 instructions

  ##### Output JSON (Rust)

  ```json
  {
    "discountApplicationStrategy": "FIRST",
    "discounts": [
      {
        "message": "10% off already discounted items",
        "targets": [
          {
            "cartLine": {
              "id": "gid://shopify/CartLine/1",
              "quantity": 1
            }
          }
        ],
        "value": {
          "percentage": {
            "value": "10.0"
          }
        }
      }
    ]
  }
  ```

  ##### Output JSON (JavaScript)

  ```json
  {
    "discountApplicationStrategy": "FIRST",
    "discounts": [
      {
        "message": "10% off already discounted items",
        "targets": [
          {
            "cartLine": {
              "id": "gid://shopify/CartLine/1",
              "quantity": 1
            }
          }
        ],
        "value": {
          "percentage": {
            "value": "10.0"
          }
        }
      }
    ]
  }
  ```

* ### Apply percentage discounts for VIP customers

  This example implements a Shopify function that gives a configurable discount to customers with a "VIP" tag. The discount percentage is stored in an app-owned metafield and the tags are stored in a function-owned metafield.

  #### Entrypoint (Rust)

  ```rust
  use shopify_function::prelude::*;
  use std::process;

  pub mod run;

  #[typegen("./schema.graphql")]
  pub mod schema {
      #[query("src/run.graphql", custom_scalar_overrides = {"Input.discountNode.metafield.jsonValue" => super::run::Configuration})]
      pub mod run {}
  }

  fn main() {
      log!("Please invoke a named export.");
      process::abort();
  }
  ```

  #### purchase.product-discount.run

  ##### Input Query (Rust)

  ```graphql
  query Input($customer_tag: String! = "VIP") {
    cart {
      lines {
        id
        quantity
      }
      buyerIdentity {
        customer {
          hasTags(tags: [$customer_tag]) {
            tag
            hasTag
          }
        }
      }
    }
    discountNode {
      metafield(namespace: "$app", key: "function-configuration") {
        jsonValue
      }
    }
  }
  ```

  ##### Input Query (JavaScript)

  ```graphql
  query RunInput($customer_tag: String! = "VIP") {
    cart {
      lines {
        id
        quantity
      }
      buyerIdentity {
        customer {
          hasTags(tags: [$customer_tag]) {
            tag
            hasTag
          }
        }
      }
    }
    discountNode {
      metafield(namespace: "$app", key: "function-configuration") {
        jsonValue
      }
    }
  }
  ```

  ##### Input Object (Rust)

  ```json
  {
    "cart": {
      "lines": [
        {
          "id": "gid://shopify/CartLine/1",
          "quantity": 2
        }
      ],
      "buyerIdentity": {
        "customer": {
          "hasTags": [
            {
              "tag": "VIP",
              "hasTag": true
            }
          ]
        }
      }
    },
    "discountNode": {
      "metafield": {
        "jsonValue": {
          "percentage": 10.0
        }
      }
    }
  }
  ```

  ##### Input Object (JavaScript)

  ```json
  {
    "cart": {
      "lines": [
        {
          "id": "gid://shopify/CartLine/1",
          "quantity": 2
        }
      ],
      "buyerIdentity": {
        "customer": {
          "hasTags": [
            {
              "tag": "VIP",
              "hasTag": true
            }
          ]
        }
      }
    },
    "discountNode": {
      "metafield": {
        "jsonValue": {
          "percentage": 10.0
        }
      }
    }
  }
  ```

  ##### Function Code (Rust)

  ```rust
  use crate::schema;
  use shopify_function::prelude::*;
  use shopify_function::Result;

  #[derive(Deserialize, Default, PartialEq)]
  #[shopify_function(rename_all = "camelCase")]
  pub struct Configuration {
      percentage: f64,
  }

  #[shopify_function]
  fn run(input: schema::run::Input) -> Result<schema::FunctionRunResult> {
      // Get configuration or return early if no metafield is set
      let config: &Configuration = match input.discount_node().metafield() {
          Some(metafield) => metafield.json_value(),
          None => {
              return Ok(schema::FunctionRunResult {
                  discounts: vec![],
                  discount_application_strategy: schema::DiscountApplicationStrategy::First,
              })
          }
      };

      // Check if customer exists and has the VIP tag
      let is_vip = input
          .cart()
          .buyer_identity()
          .as_ref()
          .and_then(|identity| identity.customer())
          .map(|customer| {
              customer
                  .has_tags()
                  .iter()
                  .any(|tag_info| *tag_info.has_tag())
          })
          .unwrap_or(false);

      if !is_vip {
          return Ok(schema::FunctionRunResult {
              discounts: vec![],
              discount_application_strategy: schema::DiscountApplicationStrategy::First,
          });
      }

      // Create discount for all cart lines
      let discounts = input
          .cart()
          .lines()
          .iter()
          .map(|line| schema::Discount {
              value: schema::Value::Percentage(schema::Percentage {
                  value: Decimal(config.percentage),
              }),
              targets: vec![schema::Target::CartLine(schema::CartLineTarget {
                  id: line.id().clone(),
                  quantity: Some(*line.quantity()),
              })],
              message: Some(format!("{}% VIP customer discount", config.percentage)),
          })
          .collect();

      Ok(schema::FunctionRunResult {
          discounts,
          discount_application_strategy: schema::DiscountApplicationStrategy::First,
      })
  }
  ```

  ##### Performance Cost (Rust)

  29675 instructions

  ##### Function Code (JavaScript)

  ```javascript
  // @ts-check
  import { DiscountApplicationStrategy } from "../generated/api";

  /**
   * @typedef {import("../generated/api").RunInput} RunInput
   * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult
   * @typedef {import("../generated/api").Target} Target
   */

  /**
   * @type {FunctionRunResult}
   */
  const EMPTY_DISCOUNT = {
    discountApplicationStrategy: DiscountApplicationStrategy.First,
    discounts: [],
  };

  /**
   * @param {RunInput} input
   * @returns {FunctionRunResult}
   */
  export function run(input) {
    // Get configuration or return empty discount if no metafield is set
    const configuration = input.discountNode.metafield?.jsonValue ?? "{}";
    
    if (!configuration.percentage) {
      return EMPTY_DISCOUNT;
    }

    // Check if customer exists and has the VIP tag
    const isVip = input.cart.buyerIdentity?.customer?.hasTags
      ?.some(tagInfo => tagInfo.hasTag) ?? false;

    if (!isVip) {
      return EMPTY_DISCOUNT;
    }

    // Create discount for all cart lines
    const discounts = input.cart.lines.map(line => ({
      value: {
        percentage: {
          value: configuration.percentage.toFixed(1).toString()
        }
      },
      targets: [{
        cartLine: {
          id: line.id,
          quantity: line.quantity
        }
      }],
      message: `${configuration.percentage}% VIP customer discount`
    }));

    return {
      discountApplicationStrategy: DiscountApplicationStrategy.First,
      discounts
    };
  }
  ```

  ##### Performance Cost (JavaScript)

  238514 instructions

  ##### Output JSON (Rust)

  ```json
  {
    "discountApplicationStrategy": "FIRST",
    "discounts": [
      {
        "message": "10% VIP customer discount",
        "targets": [
          {
            "cartLine": {
              "id": "gid://shopify/CartLine/1",
              "quantity": 2
            }
          }
        ],
        "value": {
          "percentage": {
            "value": "10.0"
          }
        }
      }
    ]
  }
  ```

  ##### Output JSON (JavaScript)

  ```json
  {
    "discountApplicationStrategy": "FIRST",
    "discounts": [
      {
        "message": "10% VIP customer discount",
        "targets": [
          {
            "cartLine": {
              "id": "gid://shopify/CartLine/1",
              "quantity": 2
            }
          }
        ],
        "value": {
          "percentage": {
            "value": "10.0"
          }
        }
      }
    ]
  }
  ```

### Targeting product variants or cart lines

Each `Discount` returned in the output can have a collection of either product variant or cart line targets, but not both. The collection of `Target` objects declare the cart lines to which the `Discount` will be applied.

A `CartLineTarget` specifies a specific cart line, whereas a `ProductVariantTarget` specifies a specific product variant, which could apply to one or more cart lines for that product variant. Additionally, each `Target` has an optional quantity field which, when provided, limits the number of units to which the `Discount` will be applied.

Use a `CartLineTarget` when you want fine-grained control on specifically which cart lines will get discounted. Alternatively, use `ProductVariantTarget` if your discounting strategy is based on product variants, and you aren't concerned which cart lines belonging to those product variants specifically get discounted.

***

## Sales channel support

[Automatic discounts](https://help.shopify.com/manual/discounts/discount-types/automatic-discounts) that are managed by an app using Shopify Functions work for all [Shopify sales channels](https://help.shopify.com/manual/online-sales-channels). This includes the [Online Store](https://help.shopify.com/manual/online-store) and [Shopify Point of Sale (POS)](https://help.shopify.com/manual/sell-in-person).

***
