---
title: "Shopify discount functions, verified November 2026"
description: "What a Shopify discount function's output looks like in a real Storefront cart: where the allocation lands, a line split by a partial discount, and one discount with a product and a shipping class. Verified 3 November 2026 on Shopify's 2026-10 API."
url: https://offersuite.io/shopify/discount-functions
updated: 2026-11-03
---

# Shopify discount functions in a real cart

A discount function is code Shopify runs for an app's discount each time a cart is priced. Shopify's reference says what a function may return. These are the carts a real store returned for one, read through the Storefront API.

Verified 3 November 2026 on Shopify’s 2026-10 API, in carts built on a real store. Each statement marked with a tick is checked against the cart Shopify returned.

## The discount lands on the line the function targets

The function behind these carts belongs to an automatic app discount. It reads a cart attribute to decide what to do; given one, it returns a product discount candidate that targets a cart line.

The cart reports that discount on the line, as an automatic discount allocation that carries the discount's title. The function's candidate set no message of its own.

The operation the function returns for this cart

```
{
  "operations": [
    {
      "productDiscountsAdd": {
        "candidates": [
          {
            "targets": [{ "cartLine": { "id": "gid://shopify/CartLine/…" } }],
            "value": { "percentage": { "value": 25 } }
          }
        ],
        "selectionStrategy": "ALL"
      }
    }
  ]
}
```

**A discount function prices one line** Verified 3 November 2026 · API 2026-10

#### Into the cart

- 1 × Single Bag at $40.00, bought once
- The cart attribute the app discount's function reads

#### What Shopify returned

The cart Shopify returned: A discount function prices one line

| Line | Quantity | Price | Discounts on the line | Line total |
| --- | --- | --- | --- | --- |
| Single Bag | 1 | $40.00 | −$10.00 automatic, “Offer Suite” | $30.00 |
| Discounts on the cart | none |  |  |  |
| Cart total | $30.00 |  |  |  |

#### What that shows

- The $40.00 line cost $30.00.
- The line carried one automatic discount allocation of $10.00, named by the discount's title.
- The cart's own list of discount allocations was empty: a product discount is reported on its line only.

## A function that returns no operations leaves no trace

Without the attribute, the same function returns an empty list of operations. The discount is still active on the store and its function still runs.

Nothing in the cart says so. There is no allocation of zero, no warning and no list of discounts that were considered: a function that chose not to act and a discount that does not exist read the same from the cart.

**A function that returns no operations** Verified 3 November 2026 · API 2026-10

#### Into the cart

- 1 × Single Bag at $40.00, bought once
- No cart attribute, so the app's functions return no operations

#### What Shopify returned

The cart Shopify returned: A function that returns no operations

| Line | Quantity | Price | Discounts on the line | Line total |
| --- | --- | --- | --- | --- |
| Single Bag | 1 | $40.00 | none | $40.00 |
| Discounts on the cart | none |  |  |  |
| Cart total | $40.00 |  |  |  |

#### What that shows

- The line cost its full $40.00.
- No discount allocation appeared anywhere in the cart, and no warning: an active automatic discount whose function returns nothing leaves no trace.

## A discount on part of a line splits the line

A candidate's cart line target may name a quantity. This function discounts one unit, so on a line of two it targets one of them.

Shopify did not return one line with an averaged price. It returned two lines, so code that finds a line by its variant and expects one match finds two.

The candidate, with a quantity on its target

```
{
  "targets": [{ "cartLine": { "id": "gid://shopify/CartLine/…", "quantity": 1 } }],
  "value": { "percentage": { "value": 25 } }
}
```

**A function discounts one unit of a line of two** Verified 3 November 2026 · API 2026-10

#### Into the cart

- 2 × Single Bag at $40.00, bought once
- The cart attribute the app discount's function reads

#### What Shopify returned

The cart Shopify returned: A function discounts one unit of a line of two

| Line | Quantity | Price | Discounts on the line | Line total |
| --- | --- | --- | --- | --- |
| Single Bag | 1 | $40.00 | none | $40.00 |
| Single Bag | 1 | $40.00 | −$10.00 automatic, “Offer Suite” | $30.00 |
| Discounts on the cart | none |  |  |  |
| Cart total | $70.00 |  |  |  |

#### What that shows

- One line of quantity 2 went in; the cart came back with two lines of quantity 1.
- One of them cost $30.00 with the $10.00 allocation, the other $40.00 with none.
- The cart total was $70.00.

## One discount can carry a product class and a shipping class

The discount on this store has both classes, so Shopify runs both of the function's targets: the one for cart lines and the one for delivery options. The delivery target returns a candidate for the cheapest rate, with a message.

The two halves are named differently in the cart. The second cart is the same purchase with no discount, to show what the rate costs.

The delivery target's operation

```
{
  "operations": [
    {
      "deliveryDiscountsAdd": {
        "candidates": [
          {
            "message": "Free shipping",
            "targets": [{ "deliveryOption": { "handle": "…" } }],
            "value": { "percentage": { "value": 100 } }
          }
        ],
        "selectionStrategy": "ALL"
      }
    }
  ]
}
```

**One automatic discount, a product class and a shipping class** Verified 3 November 2026 · API 2026-10

#### Into the cart

- 1 × Single Bag at $40.00, bought once
- The cart attribute the app discount's function reads
- A US delivery address, with the cheapest rate selected

#### What Shopify returned

The cart Shopify returned: One automatic discount, a product class and a shipping class

| Line | Quantity | Price | Discounts on the line | Line total |
| --- | --- | --- | --- | --- |
| Single Bag | 1 | $40.00 | −$10.00 automatic, “Offer Suite” | $30.00 |
| Discounts on the cart | none |  |  |  |
| Delivery: Standard selected Quoted: Standard $8.00, Express $15.00 | −$8.00 automatic, “Free shipping” | $0.00 |  |  |
| Cart total | $30.00 |  |  |  |

#### What that shows

- The line cost $30.00, with a $10.00 allocation named by the discount's title.
- The selected rate, Standard at $8.00, was discounted in full on the delivery group.
- The shipping allocation was named by the message the function gave its candidate, not by the discount's title.
- The same shipping allocation was also in the cart's own list, and the cart total was $30.00.

**The same cart with no discount** Verified 3 November 2026 · API 2026-10

#### Into the cart

- 1 × Single Bag at $40.00, bought once
- No cart attribute, so the app's functions return no operations
- A US delivery address, with the cheapest rate selected

#### What Shopify returned

The cart Shopify returned: The same cart with no discount

| Line | Quantity | Price | Discounts on the line | Line total |
| --- | --- | --- | --- | --- |
| Single Bag | 1 | $40.00 | none | $40.00 |
| Discounts on the cart | none |  |  |  |
| Delivery: Standard selected Quoted: Standard $8.00, Express $15.00 | none | $8.00 |  |  |
| Cart total | $48.00 |  |  |  |

#### What that shows

- The store quoted Standard at $8.00 and Express at $15.00; with Standard selected the cart total was $48.00.

## How this was verified

Every cart on this page was built through the Storefront API on a Shopify Plus development store we keep for this, on API version 2026-10, and read back as Shopify priced it. The store sells one product in these carts: Single Bag, at $40.00, also sold on a selling plan named “Every 30 days” that has no pricing policy. It quotes two delivery rates to a US address.

It has one automatic app discount, titled “Offer Suite”, with a product class and a shipping class, set to combine with product, order and shipping discounts. Its function reads a cart attribute: with it, the function takes 25% off one unit of Single Bag bought once, or $8.00 off the unit on its selling plan, and makes the cheapest delivery rate free. Without it, the function returns no operations.

A suite builds these carts again and reads the discount settings from the store before it does. A statement that no longer matches the cart takes this page down until it is corrected, and no cart stands for more than 90 days without being built again. This is what one store returned on one API version: your store’s plan, markets and other apps can change the result, so build the cart.

Seen something different on your store? Write to [privacy@offersuite.io](mailto:privacy@offersuite.io) with the cart and we’ll run it.

## Related

- [Shopify, verified **Shopify offer mechanics, verified on a real store** How Shopify discounts, discount functions, cart transforms, selling plans, the Storefront cart and their limits behave, shown in real carts built on a Shopify store and built again at least every 90 days.](https://offersuite.io/shopify)
- [Feature **Publish and verify on a real Shopify cart** Publishing writes the offer to Shopify, builds a real cart for every visible option and goes live only if each one charges what the offer promises.](https://offersuite.io/features/publish-and-verify)
- [Shopify, verified **Shopify Storefront cart discounts, verified November 2026** Where a Shopify Storefront API cart reports each kind of discount: product discounts on the line, order discounts on the cart, shipping discounts on the delivery group, and codes it did not apply in warnings. Verified 3 November 2026 on Shopify's 2026-10 API.](https://offersuite.io/shopify/storefront-cart)
- [Shopify, verified **Shopify cart transform function, verified November 2026** What a Shopify cart transform's price looks like in a real Storefront cart: the line's own price changes with no discount allocation, a function that returns nothing leaves no trace, and discount codes are taken from the new price. Verified 3 November 2026 on Shopify's 2026-10 API.](https://offersuite.io/shopify/cart-transform)
- [Shopify, verified **Shopify product and shipping discounts combined, verified November 2026** Real carts with a Shopify product discount and a shipping discount together: one automatic discount carrying both, two codes that allow each other, and a free-shipping code refused in favour of a smaller product discount. Verified 3 November 2026 on Shopify's 2026-10 API.](https://offersuite.io/shopify/discount-combinations/product-and-shipping)
- [Shopify, verified **Shopify automatic discount not working, verified November 2026** A checklist for a Shopify automatic discount that does not show in the cart, each step backed by a real cart: where to look, a function that returned nothing, a code or another automatic discount that displaced it, and a line discounted in part. Verified 3 November 2026 on Shopify's 2026-10 API.](https://offersuite.io/shopify/troubleshooting/automatic-discount-not-working)
