---
title: "Auto-sync bundle prices on variant price changes"
description: "Automatically recalculate and update Shopify bundle prices when a component variant's price changes using Workflow Trigger Extensions. Step-by-step Flow guide."
canonical: "https://docs.workflow-trigger-extensions.app/auto-sync-bundle-prices"
---

# Auto-sync bundle prices on variant price changes

When you use the [**Shopify Bundles app**](https://apps.shopify.com/shopify-bundles) to create product bundles, changing a component product's variant price does **not** automatically update the bundle product's variant price. The **Product Variant Price Changed** trigger from [**Workflow Trigger Extensions**](https://apps.shopify.com/flow-trigger-extensions) solves this by detecting the price change and automatically recalculating and updating the bundle variant price.

---

We will assume the following scenario to understand how we can use the **Product Variant Price Changed** trigger to keep bundle prices in sync.

## Scenario: Auto-update bundle price when a component variant price changes

Imagine you have a bundle product (e.g. a T-Shirt bundle) created with the Shopify Bundles app. The bundle contains three component products, Black T-Shirt, Grey T-Shirt, and White T-Shirt, each priced at €10.00 per variant. The bundle variant price is €30.00 (the sum of all component prices). When you change a component product's variant price, this flow will automatically update the corresponding bundle variant price.

Enable this trigger from the app settings -> Product Variants -> Variant Price Changes

Product Variant Price Changed

Get the parent bundle product, calculate updated variant prices, and bulk-update the bundle variant prices via the Admin API

## **Video Guide**

You can see the steps visually in this video as well (video has no voice, you can control the speed of the video according to your need)

[Video](https://youtu.be/cerrDrmYeUE)

### **How we will make this flow**

### Understanding the setup
- We have a component product (e.g. Grey T-Shirt) with variants S, M, L, XL, 2XL and each priced at **€10.00**.
- We have a bundle product created with the **Shopify Bundles app**. It contains 3 bundled products (Black T-Shirt, Grey T-Shirt, White T-Shirt), each with 5 variants. The bundle variant price is **€30.00** (sum of component prices: 3 × €10.00).

### You can see the steps followed visually here:
- Enable the Variant Price Change trigger from **Workflow Trigger Extensions** -> **Settings** -> **Product Variants** -> **Variant Price Changes**
- Create a new blank workflow from the Shopify Flow app and select the **Product Variant Price Changed** trigger from the **Workflow Trigger Extensions app**
- Add a **Get product data** action to retrieve the changed product using an advanced query, sorted by **created at** in **ascending** order. This step fetches the product's parent bundle information via the `productParents` field. Query is like this: `id:{{productVariant.product.id | split: "gid://shopify/Product/" | last}}`
- Add a **Run code** step to extract the parent bundle product ID from the `getProductData` result. The code extracts the parent product IDs from `productParents` and builds an `idsCondition` string for querying.

The **Run code** step uses the following GraphQL input, javascript code and outputs to get the parent product IDs:

Run Code step showing the GraphQL input, JavaScript code and the preview output

```
{
  getProductData {
    productParents {
      id
    }
  }
}
```

```
export default function main(input) {
  const productIds = input.getProductData[0]?.productParents?.map(p => p.id) ?? [];
  const productId = productIds[0] ?? null;

  const idsCondition = productIds
    .map(gid => "id:" + gid.split("gid://shopify/Product/").pop())
    .join(" OR ");

  return {
    productId: productId,
    productIds: productIds,
    idsCondition: idsCondition,
  };
}
```

```
type Output {
  productId: String
  productIds: [String!]!
  idsCondition: String!
}
```

- Add a **Condition** step that checks whether the Run code output `productId` is not empty and exists. This ensures we only proceed when the changed product is actually part of a bundle.
- **True** → continue to update the bundle price
- **False** → stop (the product is not a bundle component)
- If the condition is **True**, add another **Get product data (1)** action to fetch the parent bundle product's variant and pricing data using the `idsCondition` from the Run code step.
- Add a second **Run code (1)** step to calculate the new bundle variant prices based on the updated component prices. This step outputs a `variantPrices` array with the new prices for each bundle variant.

This **Run code (1)** step is recalculating the bundle variant prices based on the updated component price. Here's what it does:**First, it grabs two key pieces of info from the trigger:**
- `changedVariantId` the variant that was just changed ( `...158920`)
- `newPrice` the new price for that variant ( `11.00`)**Then it loops through every bundle variant and recalculates its total price.** Each bundle variant has 3 component variants (Black T-Shirt, Gray T-Shirt, White T-Shirt). For each component, it checks: is this the variant that just changed? If yes, use `newPrice`(11.00) instead of the stale price still stored in Shopify (10.00). If no, use the existing `component.productVariant.price`.It sums up the component prices to get the new bundle variant price.**You can see it working in your output data.** Look at variant `...088840` its components include `...158920`(the changed variant). So its price is 11 + 10 + 10 = **31** , while all the other bundle variants still total **30** because none of their components changed.This is the key insight of the step: Shopify hasn't updated the component price in the bundle data yet, so the code can't just sum the existing prices, it has to substitute the new price for the changed variant on the fly. Without this, all variants would still show 30.The output `variantPrices`array then feeds into the **For each loop** which calls `productVariantsBulkUpdate`to actually write these recalculated prices back to the bundle product.

```
{
  productVariant {
    id
  }
  priceChange {
    oldPrice { amount }
    newPrice { amount }
  }
  getProductData1 {
    id
    variants {
      id
      productVariantComponents {
        productVariant {
          id
          price
        }
      }
    }
  }
}
```

```
export default function main(input) {
  const changedVariantId = input.productVariant.id;
  const newPrice = parseFloat(input.priceChange.newPrice.amount);

  const variantPrices = input.getProductData1.flatMap(product =>
    product.variants.map(variant => ({
      productId: product.id,
      id: variant.id,
      price: variant.productVariantComponents.reduce((sum, component) => {
        const p = component.productVariant.id === changedVariantId
          ? newPrice
          : parseFloat(component.productVariant.price);
        return sum + p;
      }, 0)
    }))
  );

  return { variantPrices };
}
```

```
type VariantPrice {
  productId: String!
  id: String!
  price: Float!
}
type Output {
  variantPrices: [VariantPrice!]!
}
```

- Add a **For each loop (iterate)** that iterates over each item in `runCode1.variantPrices`. For each variant price, it performs the **Send Admin API request** action using the **productVariantsBulkUpdate** mutation to update the bundle variant price.
You can use this input for the Mutation:

```
{
  "variants": [
    {
      "id": "{{variantPricesForeachitem.id}}",
      "price": "{{variantPricesForeachitem.price}}"
    }
  ],
  "productId": "{{variantPricesForeachitem.productId}}",
  "allowPartialUpdates": true
}
```

### How it all works together

When a variant price changes on a component product (e.g. you update the Grey T-Shirt S variant from €10.00 to €15.00):
1. The **Product Variant Price Changed** trigger fires
2. The flow fetches the product's parent bundle using `productParents`
3. The Run code step extracts the bundle product ID
4. The condition checks if this product is part of a bundle
5. If yes, it fetches the bundle product data
6. A second Run code step recalculates the bundle variant prices
7. The loop iterates over each variant and updates the bundle price via the **productVariantsBulkUpdate** Admin API mutation

The bundle S variant price would now update from €30.00 to €35.00 (€15.00 + €10.00 + €10.00).
