Paketi bileşenlerine ayırma
Standart bileşen metafield’larını kullanarak sepetteki bir paket ürünü bileşen varyantlarına ayıran Shopify cart transform Function’ı.
- Function API
- Cart Transform
- Hedef (target)
- cart.transform.run
- İşlem (operation)
- lineExpand
- Plan
- Herkese açık uygulamada her plan; özel uygulamada Shopify Plus
- Uygulama yetkisi
- write_cart_transforms
- API sürümü
- 2026-10
- Son kontrol
Kısaca
Bu cart transform Function’ı, sepette ve checkout’ta bir paket varyantını bileşen ürünlerine ayırır; böylece stok ve gönderim gerçek ürünler üzerinden yürür. Bileşenler custom.component_reference ve custom.component_quantities varyant metafield’larından gelir. Cart Transform API’nin cart.transform.run hedefindeki lineExpand işlemini kullanır (2026-10); herkese açık uygulamada her planda çalışır.
Nasıl kullanılır
- custom.component_reference (ürün varyantı listesi) ve custom.component_quantities (tam sayı listesi) varyant metafield tanımlarını oluşturun.
- Her paket varyantında bileşen varyantlarını ve adetlerini aynı sırayla girin.
- Shopify CLI ile bir uygulama oluşturun, uzantıyı ekleyin (shopify app generate extension --template cart_transform) ve dosyalarını aşağıdakilerle değiştirin.
- Testleri shopify app function run ile çalıştırın, deploy edin ve Function’ı cartTransformCreate ile etkinleştirin.
Kod
shopify.extension.tomlapi_version = "2026-10"
[[extensions]]
name = "Expand a bundle into its components"
handle = "expand-bundle-components"
type = "function"
[[extensions.targeting]]
target = "cart.transform.run"
input_query = "src/cart_transform_run.graphql"
export = "cart-transform-run"
[extensions.build]
command = ""
path = "dist/function.wasm"
src/cart_transform_run.graphqlquery CartTransformRunInput {
cart {
lines {
id
merchandise {
__typename
... on ProductVariant {
componentReference: metafield(namespace: "custom", key: "component_reference") {
jsonValue
}
componentQuantities: metafield(namespace: "custom", key: "component_quantities") {
jsonValue
}
}
}
}
}
}
src/cart_transform_run.js// @ts-check
/**
* @typedef {import("../generated/api").CartTransformRunInput} CartTransformRunInput
* @typedef {import("../generated/api").CartTransformRunResult} CartTransformRunResult
*/
/**
* The bundle variant lists its components in two variant metafields, the
* definitions Shopify's bundle guide uses: custom.component_reference (list of
* variants) and custom.component_quantities (list of integers, same order).
* Quantities are for one bundle.
*/
/**
* @param {CartTransformRunInput["cart"]["lines"][number]} line
* @returns {CartTransformRunResult["operations"][number] | null}
*/
function expandOperation(line) {
if (line.merchandise.__typename !== "ProductVariant") return null;
const variantIds = line.merchandise.componentReference?.jsonValue;
const quantities = line.merchandise.componentQuantities?.jsonValue;
if (!Array.isArray(variantIds) || variantIds.length === 0) return null;
// Mismatched lists mean a half-edited bundle; leave the line as it is
// rather than expand it into the wrong items.
if (!Array.isArray(quantities) || quantities.length !== variantIds.length) return null;
// No price on the items: Shopify splits the bundle price across the
// components by their own prices (its weight price algorithm).
return {
lineExpand: {
cartLineId: line.id,
expandedCartItems: variantIds.map((merchandiseId, index) => ({ merchandiseId, quantity: quantities[index] })),
},
};
}
/**
* @param {CartTransformRunInput} input
* @returns {CartTransformRunResult}
*/
export function cartTransformRun(input) {
const operations = input.cart.lines.map(expandOperation).filter((operation) => operation !== null);
return { operations };
}
Test girdisi ve beklenen çıktı
tests/bundle-line.input.json{
"cart": {
"lines": [
{
"id": "gid://shopify/CartLine/1",
"merchandise": {
"__typename": "ProductVariant",
"componentReference": {
"jsonValue": ["gid://shopify/ProductVariant/1111111111", "gid://shopify/ProductVariant/2222222222"]
},
"componentQuantities": { "jsonValue": [2, 1] }
}
},
{
"id": "gid://shopify/CartLine/2",
"merchandise": { "__typename": "ProductVariant", "componentReference": null, "componentQuantities": null }
}
]
}
}
tests/bundle-line.output.json{
"operations": [
{
"lineExpand": {
"cartLineId": "gid://shopify/CartLine/1",
"expandedCartItems": [
{ "merchandiseId": "gid://shopify/ProductVariant/1111111111", "quantity": 2 },
{ "merchandiseId": "gid://shopify/ProductVariant/2222222222", "quantity": 1 }
]
}
}
]
}
tests/mismatched-lists.input.json{
"cart": {
"lines": [
{
"id": "gid://shopify/CartLine/1",
"merchandise": {
"__typename": "ProductVariant",
"componentReference": {
"jsonValue": ["gid://shopify/ProductVariant/1111111111", "gid://shopify/ProductVariant/2222222222"]
},
"componentQuantities": { "jsonValue": [2] }
}
}
]
}
}
tests/mismatched-lists.output.json{ "operations": [] }
tests/no-bundles.input.json{
"cart": {
"lines": [
{ "id": "gid://shopify/CartLine/1", "merchandise": { "__typename": "ProductVariant", "componentReference": null, "componentQuantities": null } }
]
}
}
tests/no-bundles.output.json{ "operations": [] }
Lintel tarafından yazıldı. MIT lisansı: kendi mağazanızda da müşteri işlerinizde de ücretsiz kullanabilirsiniz.
Sınırlar ve özel durumlar
- Bileşen fiyatı gönderilmediği için Shopify paket fiyatını bileşenlere kendi fiyatları oranında dağıtır.
- Satırda bir satış planı (abonelik, ön sipariş) varsa Shopify cart transform işlemlerini reddeder.
- Ayrılan bir satır en fazla 150 bileşene sahip olabilir.
- Mağaza başına uygulama başına bir cart transform Function’ı olur; iki işlem aynı satırı hedeflerse lineExpand kazanır.
Sık sorulan sorular
- Ürün paketleri Shopify Functions ile nasıl çalışır?
- Bir cart transform Function’ı sepet satırlarının nasıl sunulacağını değiştirir: lineExpand bir paket satırını bileşenlere ayırır, linesMerge bileşenleri tek bir paket satırında birleştirir. Siparişler, paket ana ürününe referansla bileşen satırlarını tutar.
- Paketler için Shopify Plus gerekir mi?
- Herkese açık bir uygulamada lineExpand ve linesMerge için gerekmez. Yalnızca lineUpdate (bir satırın fiyatını, adını ya da görselini değiştirme) Shopify Plus ya da geliştirme mağazası ister.
- Cart transform neden etkinleşmiyor?
- cartTransformCreate, write_cart_transforms yetkisi ister ve mağazanın Checkout Extensibility’ye geçmiş olması gerekir.
Shopify belgeleri
- Function API sürümü 2026-10 için yazıldı ve gösterilen tarihte Shopify’ın başvuru belgeleriyle karşılaştırıldı. Shopify her çeyrekte yeni bir sürüm yayımlar.
- Function içeren özel (custom) uygulamalar yalnızca Shopify Plus mağazalarında çalışır. Aynı Function herkese açık bir uygulamada, sayfada aksi yazmıyorsa her planda çalışır.
- Her örnek test verileriyle gelir ve yayımlamadan önce bu testleri çalıştırırız. Kodu değiştirdikten sonra testleri tekrar çalıştırın: shopify app function run.
- MIT lisansı. Kodu kendi mağazanızda da müşteri işlerinizde de kullanabilirsiniz.
Mağazanız için kurulmasını, test edilmesini ve bakımını isterseniz: Shopify Functions geliştirme.
