About the Cart Transform Function API
The Cart Transform API enables you to write functions that modify the pricing and merchandising of cart line items. You can expand a single cart line item to form a bundle of components or add-on products, merge multiple cart lines into a single line that represents a bundle, and update line items to override the price, title, or image.
The API includes the RunInput
object, which represents the cart, and the FunctionRunResult
object, which represents the operations to perform on the cart.
The RunInput
object is the complete schema that your function can receive as input.
For a list of fields that the Cart Transform API's RunInput
object accepts, refer to RunInput.
Use the RunInput
GraphQL query to specify the data that's required to inform the logic in your cart transform function. It is common to use cart line attributes or metafields to pass custom data in to the function using the RunInput
query.
Example RunInput
Anchor link to section titled "Example RunInput"For example, you can write a cart transform function that adds an add-on extended warranty to a product when a customer opts-in by adding the product to the cart.
Use the cart line attribute (also known as a cart line property) that's created by the storefront when the cart line is added to determine whether or not to include the following:
- The warranty
- A
metafield
on the product to store the cost of the warranty as a percentage of the original product price - A
metafield
that's stored on the cart transform itself, to store the ID of the product variant that represents the warranty product
The following example shows the resulting input to the query:
FunctionRunResult
Anchor link to section titled "FunctionRunResult"The FunctionRunResult
object is the shape of the function's output.
The output returns a list of cart operations, where each element can have one of the following values:
ExpandOperation
: Specifies the components of an item and applies a price adjustment. For example,Skin care kit
is expanded into2x Face mask
and1x Cream
.MergeOperation
: Enables merging items together into a bundle by specifying the bundle's product parent. For example, the items1x Burger
,1x Drink
, and2x Fries
can be combined into theMeal Kit
product, resulting in one item (Meal Kit
) with three components.UpdateOperation
: Enables overrides of item properties by specifying a new title, price, or image. This operation is only available to shops on a Plus plan or a Development store plan.
In the case where the function returns multiple operations and there's a collision, Shopify executes a subset of the operations using the following criteria:
Multiple expand operations targeting the same cart line: The first expand operation in the list is executed, and all other expand operations for the same cart line are discarded.
Multiple merge operations targeting the same cart line: The first merge operation in the list is executed, and all other merge operations for the same cart line are discarded.
Expand and merge operations targeting the same cart line: The expand operation is executed, and the merge operation is discarded.
Multiple update operations targeting the same cart line: The first update operation in the list is executed, and all other update operations for the same cart line are discarded.
Expand, merge, and update operations targeting the same cart line: The expand operation will be executed while the merge and update operations will be discarded.
Fixed expand and customized expand operations targeting the same cart line: The fixed expand operation will be executed and the customized expand operation will be discarded.
Creating a cartTransform object using GraphQL Admin API
Anchor link to section titled "Creating a cartTransform object using GraphQL Admin API"To activate your function, create a cartTransform
object on the store where you installed your app using the cartTransformCreate
mutation.
Install the Shopify GraphiQL app on your store and select the
write_cart_transforms
andwrite_products
access scopes.In the GraphiQL app, select the Admin API and the 2024-01 API version.
Find the ID of your function by executing the following query:
The result contains a node with your function's ID:
Run the following mutation with the ID of your function:
You should receive a GraphQL response that includes the ID of the new
cartTransform
object.
Example update operation
Anchor link to section titled "Example update operation"The following example demonstrates how you can use an update
operation to provide a new title, image, and price for the cart line.
Additional update examples
Anchor link to section titled "Additional update examples"Example expand operation
Anchor link to section titled "Example expand operation"The following example demonstrates how you can use an expand
operation to add an extended warranty.
You can update the title to show that the warranty is included, and add two cart items, one for the TV, and one for the warranty, each with their own fixed price.
This displays in the checkout as a bundle with the title "Awesome TV with Warranty" for $1150.00 with two child components, the TV and the warranty.
Additional expand examples
Anchor link to section titled "Additional expand examples"Example merge operation
Anchor link to section titled "Example merge operation"The following example demonstrates how you can use a merge
operation to combine multiple food items into a bundled meal with a price adjustment.
Merge and expand pricing
Anchor link to section titled "Merge and expand pricing"The Cart Transform API supports adjustments that decrease the price percentage as part of merge
and expand
operations.
The bundle base price varies depending on the operation:
merge
: The adjustment is based off of the components' price sum.expand
: The adjustment is based off of the bundle product price.
This distinction enables the right price to display for expand
on the product details page and in Liquid.
For example, to arrive at the final bundle price, you can employ a range of post-processing steps:
merge
: The price is the sum of the components' price, plus the adjustment, if present.expand
: The price is the sum of the components'fixedPricePerUnit
, or the bundle product price, plus the adjustment, if present.
Price per component
Anchor link to section titled "Price per component"Expand
operations allow adjustments to the price of each individual component in the bundle.
This can be done by providing a price on the expandedCartItems
in the ExpandOperation
.
Weight price algorithm
Anchor link to section titled "Weight price algorithm"When not providing a fixed price per unit on Expand
operations, the weight price algorithm allocates the bundle price to its component lines based on the weight of each component line. The weight of a component is the unit price multiplied by quantity, as unit price * quantity
.
The algorithm considers the item's price as if the item was bought individually and the quantity inside the bundle. For example, if a bundle has 10 t-shirts and 1 pair of shorts, and the shorts and t-shirt cost $5 if they were bought individually, then Shopify allocates more weight to the t-shirt.
The total weight of all component lines is then used to calculate the weight of each component line.
Amount to be allocated: $100
Component lines:
unit_price
: $10,quantity
: 1,id
: 1 # weight 10unit_price
: $20,quantity
: 2,id
: 2 # weight 40unit_price
: $30,quantity
: 3,id
: 3 # weight 90
Total weight: 140
Result:
- Component 1: $7.14 -> (10 / 140) * $100 = 7.14
- Component 2: $28.57 -> (40 / 140) * $100 = 28.57
- Component 3: $64.29 -> (90 / 140) * $100 = 64.29
Showing overrides
Anchor link to section titled "Showing overrides"Title and image overrides are visible on different surfaces, such as cart, checkout, email, and order notification emails.
To see title
overrides that Cart Transform functions make on a cart, cart notifications, or order notification emails, you need to make changes to your themes. Use item.title
for cart or line.title
for order notification emails to show the new title.
Invalid operations
Anchor link to section titled "Invalid operations"The following scenarios are considered as invalid:
expand
operations:
- One of the component quantities is less than 0.
- The line to be expanded doesn't exist.
- One of the component variant IDs doesn't exist.
- Both
ExpandedItem.Price
andPriceAdjustment
are returned in the operation. - One of the components is given a price less than 0.
- Some of the components have a customized price and others don't.
merge
operations:
- The merge operation contains an invalid quantity for the children (less than 0 or the quantity to merge is bigger than the line's quantity).
- The parent variant ID doesn't exist.
- One of the lines to be merged doesn't exist.
update
operations:
- The operation includes a price < 0.
- The line to be updated doesn't exist.
- The operation targets a line that is going to be expanded or merged.
- The shop is not on a Plus plan or a Development store plan.
List of errors
Anchor link to section titled "List of errors"The following tables provide a complete list of errors that can occur when running your function.
Error codes for expand operations
Anchor link to section titled "Error codes for expand operations"Error code | Message |
---|---|
cannot_combine_price_adjustment_and_price_per_component |
Cannot combine both an overall price adjustment and individual prices for components. |
component_merchandise_not_found |
One or more of the expanded cart items have a merchandise id that does not exist. |
exceeded_maximum_number_of_supported_expanded_cart_items |
Exceeded the maximum number of supported expanded cart items (50). |
expanded_items_missing_prices |
One or more expanded cart items are missing prices. Either all must have a price, or none. |
image_feature_not_available |
The feature to update the image is not accessible for the given shop. |
image_not_found |
Image not found for the shop. |
invalid_cart_line_id |
The cart line id is invalid. |
invalid_component_merchandise_id |
One or more of the expanded cart items have an invalid merchandise id. |
invalid_component_quantity |
One or more of the expanded cart items have an invalid quantity. |
invalid_component_price |
One or more of the expanded cart items have an invalid price. |
invalid_image_url |
The base image URL must be any of the following: https://cdn.shopify.com, https://cdn. |
invalid_price_adjustment_percentage_decrease |
The percentage decrease value must be less than or equal to 100. |
price_per_component_feature_not_available |
The feature to price an expanded cart item is not accessible for the given shop. |
title_feature_not_available |
The feature to update the title is not accessible for the given shop. |
Error codes for merge operations
Anchor link to section titled "Error codes for merge operations"Error code | Message |
---|---|
exceeded_maximum_number_of_supported_merged_cart_items |
Exceeded the maximum number of supported merged cart items. |
image_not_found |
Image not found for the shop. |
insufficient_component_quantity_to_merge |
There are not enough items in the cart to satisfy one or more the component quantities. |
invalid_component_cart_line_id |
One or more of the cart lines have an invalid cart line id. |
invalid_component_quantity |
One or more of the cart lines have an invalid quantity. |
invalid_image_url |
The base image URL must be any of the following: https://cdn.shopify.com, https://cdn.shopifycdn.net. |
invalid_parent_variant_id |
The parent variant id is not valid. |
invalid_price_adjustment_percentage_decrease |
The percentage decrease value must be less than or equal to 100. |
parent_variant_not_found |
The parent variant does not exist. |
Error codes for update operations
Anchor link to section titled "Error codes for update operations"Error code | Message |
---|---|
fixed_price_adjustment_cannot_be_negative |
Fixed price adjustments cannot be negative. |
image_not_found |
Image not found for the shop. |
invalid_cart_line_id |
The cart line id is invalid. |
invalid_image_url |
The base image URL must be any of the following: https://cdn.shopify.com, https://cdn.shopifycdn.net. |
update_feature_not_available |
The update operation feature is not accessible for the given shop. |