Alışverişe hediye ürün
Sepetin geri kalanı bir eşiğe ulaşınca bir hediye ürünü bedava yapan Shopify indirim Function’ı. Hediye ürün sepette olmalıdır.
- Function API
- Discount
- Hedef (target)
- cart.lines.discounts.generate.run
- İndirim sınıfı
- PRODUCT
- Plan
- Herkese açık uygulamada her plan; özel uygulamada Shopify Plus
- Uygulama yetkisi
- write_discounts
- API sürümü
- 2026-10
- Son kontrol
Kısaca
Bu indirim Function’ı, sepetin geri kalanı bir eşiğe (varsayılan olarak mağaza para biriminde 75) ulaşınca hediye ürünün bir adedini bedava yapar. Hediyeyi sepete ekleyemez: indirim Function’ı yalnızca sepette olan satırlara indirim uygular; ekleme işini tema, Storefront API ya da bir cart transform yapmalıdır. cart.lines.discounts.generate.run hedefini kullanır, Discount Function API 2026-10.
Nasıl kullanılır
- Hediyeyi bir ürün varyantı olarak oluşturun ve koleksiyonlarınızın dışında tutun.
- Shopify CLI ile bir uygulama oluşturun, uzantıyı ekleyin (shopify app generate extension --template discount) ve dosyalarını aşağıdakilerle değiştirin.
- Testleri shopify app function run --input tests/threshold-met.input.json ile çalıştırın, ardından deploy edin.
- discountAutomaticAppCreate ile discountClasses: [PRODUCT] olan otomatik bir indirim oluşturun ve metafield’ına {"giftVariantId": "gid://shopify/ProductVariant/1234567890", "minimumAmount": 75} yazın.
- Eşik aşıldığında hediyeyi temadan sepete ekleyin (örneğin /cart/add.js ile), sepet eşiğin altına düşünce çıkarın.
Kod
shopify.extension.tomlapi_version = "2026-10"
[[extensions]]
name = "Free gift with purchase"
handle = "free-gift-with-purchase"
type = "function"
[[extensions.targeting]]
target = "cart.lines.discounts.generate.run"
input_query = "src/cart_lines_discounts_generate_run.graphql"
export = "cart-lines-discounts-generate-run"
[extensions.build]
command = ""
path = "dist/function.wasm"
src/cart_lines_discounts_generate_run.graphqlquery CartLinesDiscountsGenerateRunInput {
cart {
lines {
id
cost {
subtotalAmount {
amount
}
}
merchandise {
__typename
... on ProductVariant {
id
}
}
}
}
presentmentCurrencyRate
discount {
discountClasses
metafield(namespace: "$app", key: "function-configuration") {
jsonValue
}
}
}
src/cart_lines_discounts_generate_run.js// @ts-check
/**
* @typedef {import("../generated/api").CartLinesDiscountsGenerateRunInput} CartLinesDiscountsGenerateRunInput
* @typedef {import("../generated/api").CartLinesDiscountsGenerateRunResult} CartLinesDiscountsGenerateRunResult
*/
/**
* Settings stored as JSON in the discount's metafield. A discount Function
* can't add lines to the cart: the gift has to be added by the theme, the
* Storefront API or a cart transform. This Function only makes it free.
*/
const DEFAULT_CONFIG = {
giftVariantId: /** @type {string | null} */ (null),
// Spend on other products, in the store's currency, that unlocks the gift.
minimumAmount: 75,
message: "Free gift",
};
/** @type {CartLinesDiscountsGenerateRunResult} */
const NO_DISCOUNT = { operations: [] };
/**
* @param {CartLinesDiscountsGenerateRunInput} input
* @returns {CartLinesDiscountsGenerateRunResult}
*/
export function cartLinesDiscountsGenerateRun(input) {
// A Function may only return operations for the classes the discount was created with.
if (!input.discount.discountClasses.includes("PRODUCT")) return NO_DISCOUNT;
const config = { ...DEFAULT_CONFIG, ...input.discount.metafield?.jsonValue };
if (!config.giftVariantId) return NO_DISCOUNT;
/** @param {(typeof input.cart.lines)[number]} line */
const isGift = (line) => line.merchandise.__typename === "ProductVariant" && line.merchandise.id === config.giftVariantId;
const giftLine = input.cart.lines.find(isGift);
if (!giftLine) return NO_DISCOUNT;
// The gift itself doesn't count towards the threshold.
const spend = input.cart.lines
.filter((line) => !isGift(line))
.reduce((sum, line) => sum + Number(line.cost.subtotalAmount.amount), 0);
if (spend < config.minimumAmount * Number(input.presentmentCurrencyRate)) return NO_DISCOUNT;
// Only one unit is free; extra units of the gift are charged normally.
return {
operations: [
{
productDiscountsAdd: {
candidates: [
{
message: config.message,
targets: [{ cartLine: { id: giftLine.id, quantity: 1 } }],
value: { percentage: { value: "100" } },
},
],
selectionStrategy: "FIRST",
},
},
],
};
}
Test girdisi ve beklenen çıktı
tests/below-threshold.input.json{
"cart": {
"lines": [
{ "id": "gid://shopify/CartLine/1", "cost": { "subtotalAmount": { "amount": "60.0" } }, "merchandise": { "__typename": "ProductVariant", "id": "gid://shopify/ProductVariant/1111111111" } },
{ "id": "gid://shopify/CartLine/2", "cost": { "subtotalAmount": { "amount": "15.0" } }, "merchandise": { "__typename": "ProductVariant", "id": "gid://shopify/ProductVariant/1234567890" } }
]
},
"presentmentCurrencyRate": "1.0",
"discount": {
"discountClasses": ["PRODUCT"],
"metafield": { "jsonValue": { "giftVariantId": "gid://shopify/ProductVariant/1234567890", "minimumAmount": 75, "message": "Free tote bag" } }
}
}
tests/below-threshold.output.json{ "operations": [] }
tests/gift-not-in-cart.input.json{
"cart": {
"lines": [
{ "id": "gid://shopify/CartLine/1", "cost": { "subtotalAmount": { "amount": "120.0" } }, "merchandise": { "__typename": "ProductVariant", "id": "gid://shopify/ProductVariant/1111111111" } }
]
},
"presentmentCurrencyRate": "1.0",
"discount": {
"discountClasses": ["PRODUCT"],
"metafield": { "jsonValue": { "giftVariantId": "gid://shopify/ProductVariant/1234567890", "minimumAmount": 75, "message": "Free tote bag" } }
}
}
tests/gift-not-in-cart.output.json{ "operations": [] }
tests/threshold-met.input.json{
"cart": {
"lines": [
{ "id": "gid://shopify/CartLine/1", "cost": { "subtotalAmount": { "amount": "80.0" } }, "merchandise": { "__typename": "ProductVariant", "id": "gid://shopify/ProductVariant/1111111111" } },
{ "id": "gid://shopify/CartLine/2", "cost": { "subtotalAmount": { "amount": "15.0" } }, "merchandise": { "__typename": "ProductVariant", "id": "gid://shopify/ProductVariant/1234567890" } }
]
},
"presentmentCurrencyRate": "1.0",
"discount": {
"discountClasses": ["PRODUCT"],
"metafield": { "jsonValue": { "giftVariantId": "gid://shopify/ProductVariant/1234567890", "minimumAmount": 75, "message": "Free tote bag" } }
}
}
tests/threshold-met.output.json{
"operations": [
{
"productDiscountsAdd": {
"candidates": [
{
"message": "Free tote bag",
"targets": [{ "cartLine": { "id": "gid://shopify/CartLine/2", "quantity": 1 } }],
"value": { "percentage": { "value": "100" } }
}
],
"selectionStrategy": "FIRST"
}
}
]
}
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
- İndirim Function’ları sepet satırı oluşturamaz. Hediyeyi ekleyen bir tema ya da uygulama adımı yoksa hiçbir şey olmaz.
- Yalnızca bir adet bedavadır; hediyenin fazladan adetleri normal fiyattan ücretlendirilir.
- Hediyenin kendisi eşiğe sayılmaz; yani hediye, kampanyayı kendi tutarıyla tetikleyemez.
Sık sorulan sorular
- Bir Shopify Function sepete bedava ürün ekleyebilir mi?
- İndirim Function’ı ekleyemez; yalnızca mevcut satırlara indirim uygular. Bir cart transform, satın alınan ürünü ek bileşen satırlarına açabilir; tema ya da Storefront API de hediyeyi ayrı bir satır olarak ekleyebilir.
- Hediye eklendikten sonra müşteri ürün çıkarırsa ne olur?
- Function yeniden çalışır ve hediyedeki indirimi kaldırır; hediye ücretlendirilir. Sürpriz olmasın diye temada hediyeyi çıkarın ya da müşteriye haber verin.
- Hediyeyi sipariş başına bir adetle sınırlayabilir miyim?
- Evet, bu kod zaten bir adede indirim verir. Fazladan adetleri engellemek için temada da adedi sınırlayın.
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.
