# Apply discounts in Shopify

> In this tutorial, we'll show you how to apply discounts at checkout using Shopify and Talon.One.

> For the complete documentation index, see [llms.txt](https://docs.talon.one/llms.txt).

Let's imagine you want to create a 20% discount in Shopify that applies to all orders over
$100 in your store. You can do this by creating a discount function in Shopify and a rule
in Talon.One. When a customer checks out, the discount is applied to their order.

## Talon.One requirements

- You are an [admin](/docs/product/account/account-settings/manage-roles.md#admin-role)
  user.
- You have set up an [Application](/docs/product/applications/create-and-manage-applications.md).
- You have created a [campaign](/docs/product/campaigns/create-and-manage-campaigns.md).
- (To discount individual items) You have created a [cart item catalog](/docs/product/account/dev-tools/manage-cart-item-catalogs.md)
  and connected it to your Application.

## Shopify requirements

:::important
- Discount effects require [network access for Shopify Functions](https://shopify.dev/docs/apps/build/functions/input-output/network-access),
  which is available with [Shopify for enterprise](https://www.shopify.com/enterprise).
  Shopify [support](https://help.shopify.com/en/) must explicitly enable network access for Shopify Functions.
- Discounts are applied via the [Storefront API](https://shopify.dev/docs/api/storefront)
  using the [`@defer` directive](https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/defer).
  If a store uses the [Ajax API](https://shopify.dev/docs/api/ajax) to manage the cart, discounts won't be visible until the customer reaches checkout.
- Discounts are managed in Talon.One and not synchronized to Shopify. They are
  applied and displayed in the storefront, but won't appear in the **Discounts** section of the Shopify admin.
- The Shopify integration only supports case insensitive coupons. In the Application
  settings, ensure the **Case Insensitive, stored in uppercase (recommended)**
  [option](/docs/product/applications/manage-general-settings#code-case-sensitivity) is
  selected.
- You cannot apply multiple coupons offering the same type of discount to the same order.
  For example, you cannot apply two coupons that both offer shipping discounts to the same order.
- If you are using both shipping and order/item discounts, ensure your
  [campaign evaluation order](/docs/product/applications/manage-campaign-evaluation)
  is set up so that shipping discounts are evaluated after order/item discounts.
:::

- You are an [administrator](https://help.shopify.com/en/manual/your-account/users/roles/roles-managed-by-shopify/administrator-roles)
  user.
- You have completed the [basic setup](set-up-shopify-app.md) of the
  Talon.One Shopify app.
- (To discount individual items) You have [synced](/docs/dev/technology-partners/shopify/sync-inventory-shopify.md)
  the cart item catalog with your product inventory in Shopify.

## Set up the integration

<StepsContainer>

### Configure your Shopify store

<Tabs>
<TabItem value="theme" label="Theme-based stores" default>
For [theme-based](https://shopify.dev/docs/storefronts/themes) stores, you don't need to
modify the template of your store. Just ensure the [app embed](set-up-shopify-app.md#enable-the-app-embed)
is enabled.

On every cart update, the app embed calls the [Create or update customer session](/shopify-integration-api#tag/Session/operation/upsertSession)
endpoint of the Shopify Integration API.

The call includes the Shopify cart ID, which is used as the customer session ID in
Talon.One, and a list of line items in the Shopify cart.
</TabItem>
<TabItem value="hydrogen" label="Hydrogen headless stores">
For [Hydrogen](https://hydrogen.shopify.dev/) headless stores, you must modify the
template of your store. In your code, implement the following steps:

1. Add a cart attribute named `talon_one_session_id` and set its value to the Shopify cart
   ID.
1. On every cart update, call the [Create or update customer session](/shopify-integration-api#tag/Session/operation/upsertSession)
   endpoint of the Shopify Integration API. The call must include the Shopify cart ID,
   which is used as the customer session ID in Talon.One, and a list of line items in the
   Shopify cart.

This involves modifying components in the `/app/routes` directory, specifically in the
`cart.jsx` file. These components are responsible for fetching the data required for a
specific page.

For more information, see the [Hydrogen documentation](https://shopify.dev/docs/storefronts/headless/hydrogen/data-fetching/third-party)
and a [code sample on GitHub](https://gist.github.com/talononebot/043f587670cc4b1209f07a23e8152ecd).
</TabItem>
<TabItem value="headless" label="Other headless stores">
For non-Hydrogen [headless](https://shopify.dev/docs/storefronts/headless/getting-started)
stores, you must modify the template of your store. In your code, implement the following
steps:

1. Create a cart using the [cartCreate](https://shopify.dev/docs/api/storefront/latest/mutations/cartcreate)
   mutation of the Storefront API.
1. On every cart update:
    - Invoke the [cartAttributesUpdate](https://shopify.dev/docs/api/storefront/latest/mutations/cartattributesupdate)
      mutation, adding a `talon_one_session_id` attribute to the cart and setting its
      value to the Shopify cart ID. See the example code below.
    - Call the [Create or update customer
      session](/shopify-integration-api#tag/Session/operation/upsertSession) endpoint of
      the Shopify Integration API. The call must include the Shopify cart ID, which is
      used as the customer session ID in Talon.One, and a list of line items in the
      Shopify cart.

**Example code**

```graphql
mutation cartAttributesUpdate($attributes: [AttributeInput!]!, $cartId: ID!) {
  cartAttributesUpdate(attributes: $attributes, cartId: $cartId) {
    cart {
      attributes {
        key
        value
      }
    }
    userErrors {
      field
      message
    }
  }
}

{
  "attributes": [
    {
      "key": "talon_one_session_id",
      "value": "<cart-ID>"
    }
  ],
  "cartId": "gid://shopify/Cart/<cart-ID>"
}
```

</TabItem>
</Tabs>

If you need further help, contact your Customer Success Manager.

### Create the discount function in Shopify

Create a discount function to enable the data flow between Shopify and Talon.One. We
recommend using only one discount function for all Talon.One discounts in your store.

1. In Shopify, open **Discounts**.
1. Click **Create a discount**.
1. In the **Talon.One** section, select **Talon.One discounts**.
1. Configure the discount function:
   - **Discount title**: Type a descriptive title, such as `Talon.One discounts`.
   - (Optional) **Start and end dates**: Ensure the start date aligns with your launch or
     testing needs, and leave the end date disabled.
     :::note
     These dates determine when Talon.One is contacted for discounts, not when individual
     discounts become active. To schedule discounts, use Talon.One's features, for
     example, [campaign scheduling](/docs/product/campaigns/settings/manage-campaign-schedule.md)
     or [coupon scheduling](/docs/product/campaigns/coupons/create-coupons.md).
     :::
   - **Discount applies to**: Select which type of discounts you want to use with
     Talon.One (product, order, or shipping discounts). If you are unsure, select all
     three options.
1. Click **Create discount**.

The **Discounts** page now shows the discount function you created.

### Create an additional cost

To allow shipping discounts, create an [additional cost](/docs/product/account/dev-tools/manage-additional-costs.md#create-an-additional-cost)
in Talon.One with the following properties:

- **Scope**: **Cart (Session)**
- **API name**: `shipping`

### Create a rule in Talon.One

1. Open a campaign in the Application that is connected to your Shopify store.
1. Depending on where you want to apply the discount, do one of the following:
   - To create an **order** discount, create a [rule](/docs/product/rules/create-and-manage-rules.md)
     with the [Discount session total](/docs/product/rules/effects/use-effects.md#discount-session-total)
     effect.
   - To create a **product** discount, create a rule with the [Discount individual items](/docs/product/rules/effects/use-effects.md#discount-individual-items)
     effect.
   - To create a **shipping** discount, create a rule with the [Discount additional cost](/docs/product/rules/effects/use-effects.md#discount-additional-costs)
     effect.

    :::note
    The title of the rule will be used as the discount title in Shopify.
    :::

    For this tutorial, we'll create a rule that applies a 20% discount to orders over
    $100:

    | What           | Name                   | Properties                                                                                                                             |
    | -------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
    | **Conditions** | Check attribute value  | <Attribute name="Cart Items Total (Current Session)" type="builtin" /> **is greater than** `100`                              |
    | **Effects**    | Discount session total | **Discount name**: `20% off`**Discount value**: <Attribute name="[Session.Total]" type="builtin" /> `* 20%` |
1. Save the rule.
1. [Activate](/docs/product/campaigns/create-and-manage-campaigns.md#activate-a-campaign) the
   campaign.

### Test the integration

1. Add a product to your cart in Shopify and ensure that the cart total is over $100.
1. Proceed to checkout.
1. Verify that the discount is applied to your order.

</StepsContainer>
