Hi Team,
We are implementing an Extended Warranty feature in Shopify Plus Checkout and would like assistance confirming that our setup is correct.
Goal
When a customer selects a checkbox in checkout, the app should automatically add a 10% warranty fee based on the cart subtotal.
What We Have Built
-
Checkout UI Extension
-
Displays a checkbox labeled “Add Extended 2-Year Warranty.”
-
When checked, it sets a cart attribute:
extended_warranty = "true".
-
-
Shopify Function (Cart Transform)
-
Reads the cart attribute.
-
Adds a warranty product variant with a dynamic price equal to 10% of the cart subtotal.
-
If the warranty line already exists, it updates the price.
-
If the box is unchecked, the function returns no operations, effectively removing the line.
-
-
Warranty Product Variant
-
Variant ID:
50217606316336 -
Base price set to $0. Dynamic price applied by the function.
-
-
All required files are configured, including:
-
shopify.ui.extension.toml -
shopify.function.extension.toml -
package.jsonfiles -
GraphQL schema
-
Complete UI extension and function code
-
What We Need From the Shopify Team
Kindly review our setup and confirm:
-
Whether this architecture is correct for the intended functionality
-
If any adjustments are needed in the Cart Transform Function
-
Whether any additional configuration is required in the Checkout Editor, App setup, or Cart Transform settings
We would like to finalize this feature for production and want to ensure everything follows best practices.
Thank you.
- extensions/checkout-warranty-ui/src/Checkout.jsx
// Checkout.jsx
import {
reactExtension,
Checkbox,
BlockStack,
Text,
useCartLines,
useApplyAttributeChange,
useAttributeValues,
} from ‘@shopify/ui-extensions-react/checkout’;
export default reactExtension(
‘purchase.checkout.block.render’,
() =>
);
function Extension() {
const cartLines = useCartLines();
const applyAttributeChange = useApplyAttributeChange();
const attributeValues = useAttributeValues([‘extended_warranty’]);
const isWarrantySelected = attributeValues[0] === ‘true’;
const cartSubtotal = cartLines.reduce((total, line) => {
const amount = parseFloat(line.cost.totalAmount.amount);
return total + amount;
}, 0);
const warrantyFee = (cartSubtotal * 0.10).toFixed(2);
const handleCheckboxChange = async (checked) => {
await applyAttributeChange({
type: ‘updateAttribute’,
key: ‘extended_warranty’,
value: checked.toString(),
});
};
return (
Add Extended 2-Year Warranty
10% of cart total (${warrantyFee})
);
}
2. extensions/checkout-warranty-ui/package.json
{
“name”: “checkout-warranty-ui”,
“version”: “1.0.0”,
“type”: “module”,
“scripts”: {
“build”: “shopify app build”
},
“dependencies”: {
“@shopify/ui-extensions”: “^2024.10.0”,
“@shopify/ui-extensions-react”: “^2024.10.0”,
“react”: “^18.2.0”
},
“devDependencies”: {
“@shopify/cli”: “^3.60.0”
}
}
3. extensions/checkout-warranty-ui/shopify.ui.extension.toml
api_version = “2024-10”
[[extensions]]
name = “checkout-warranty-ui”
handle = “checkout-warranty-ui”
type = “ui_extension”
[[extensions.targeting]]
target = “purchase.checkout.block.render”
module = “./src/Checkout.jsx”
[extensions.capabilities]
network_access = true
api_access = true
4. extensions/warranty-fee-function/src/index.js
// index.js
const NO_CHANGES = { operations: };
export function run(input) {
const warrantyAttr = input.cart.attributes.find(
(attr) => attr.key === ‘extended_warranty’ && attr.value === ‘true’
);
if (!warrantyAttr) return NO_CHANGES;
const cartSubtotal = parseFloat(input.cart.cost.subtotalAmount.amount);
const warrantyFee = (cartSubtotal * 0.10).toFixed(2);
const warrantyProductVariantId =
‘gid://shopify/ProductVariant/50217606316336’;
const warrantyLine = input.cart.lines.find(
(line) =>
line.merchandise.__typename === ‘ProductVariant’ &&
line.merchandise.id === warrantyProductVariantId
);
if (warrantyLine) {
return {
operations: [
{
update: {
cartLineId: warrantyLine.id,
price: {
adjustment: {
fixedPricePerUnit: { amount: warrantyFee }
}
}
}
}
]
};
}
return {
operations: [
{
add: {
variantId: warrantyProductVariantId,
quantity: 1,
price: {
adjustment: {
fixedPricePerUnit: { amount: warrantyFee }
}
}
}
}
]
};
}
5. extensions/warranty-fee-function/src/run.graphql
query RunInput {
cart {
lines {
id
quantity
merchandise {
__typename
… on ProductVariant {
id
}
}
}
cost {
subtotalAmount {
amount
}
}
attributes {
key
value
}
}
}
6. extensions/warranty-fee-function/package.json
{
“name”: “warranty-fee-function”,
“version”: “1.0.0”,
“type”: “module”,
“scripts”: {
“build”: “shopify app function build”
},
“dependencies”: {
“@shopify/shopify_function”: “^0.1.0”
},
“devDependencies”: {
“@shopify/cli”: “^3.60.0”
}
}
7. extensions/warranty-fee-function/shopify.function.extension.toml
api_version = “2024-10”
[[extensions]]
name = “warranty-fee-function”
handle = “warranty-fee-function”
type = “function”
description = “Adds 10% warranty fee based on cart attribute”
[extensions.build]
command = “npm run build”
path = “dist/function.wasm”
[[extensions.targeting]]
target = “purchase.cart-transform.run”