Tedarikçi maliyeti değiştiğinde fiyatı ve karşılaştırma fiyatını otomatik olarak güncelle
Tedarikçiniz bir ürün çeşidinin maliyetini 4,00'dan 5,20'ye yükseltir. Shopify'da hiçbir değişiklik olmaz. Perakende fiyatı olduğu gibi kalır ve planladığınız kâr marjı, haftalar sonra bir envanter sayımı sırasında biri fark edene kadar sessizce ortadan kaybolur.
Shopify Flow bu konuda tek başına bir çözüm sunamaz, çünkü Shopify’da ürün başına maliyet değişikliği için yerleşik bir tetikleyici bulunmamaktadır. Ayrıca, bu değere göre fiyatı yeniden hesaplayan bir eylem de yoktur.
Bu kılavuz, her iki eksikliği de giderir. Herhangi bir varyantta ürün başına maliyet değiştiğinde bir Shopify Flow işlemi başlatılır ve kısa bir işlev, yeni fiyatı ve karşılaştırma fiyatını Shopify’a geri yazar. Kurulumu yaklaşık on dakika sürer ve daha sonra her maliyet değişikliğinde süresiz olarak çalışır.
Ne geliştireceksiniz?
- Workflow Trigger Extensions, fiyat değişikliğini algılar ve varyantı, SKU’sunu ile eski ve yeni fiyatları da içeren bir Shopify Flow başlatır.
- Shopify Flow, bu değerleri JSON biçiminde bir işlevin içine aktarır.
- Workflow Functions, yeni fiyatları hesaplayan ve bunları Admin API aracılığıyla geri yazan birkaç satırlık JavaScript kodunu çalıştırır.
Fiyatlandırma kuralı tek bir yerde, sizin kontrolünüz altındaki kodda bulunur; bu sayede daha sonra bu kuralı değiştirmek, iş akışını yeniden oluşturmak yerine tek bir satırı düzenlemekle yetinir.
1. Adım: Maliyet tetikleyicisini etkinleştirin
Workflow Trigger Extensions'da Tetikleyiciler sayfasını açın, Envanter grubunu bulun ve Ürün Varyantı Maliyetinde Değişiklik seçeneğini etkinleştirin.
Bu tetikleyici, Envanter Verilerine Erişim iznine ihtiyaç duyar; çünkü ürün başına maliyet, varyantın kendisinde değil, envanter ürününde bulunur. Eğer izin henüz verilmemişse, tetikleyiciyi etkinleştirdiğinizde tek bir iletişim kutusu aracılığıyla izin istenecektir. İzin verilene kadar tetikleyici etkin kalır, ancak İzin Gerekiyor uyarısı gösterir ve çalışmaz.
Tetikleyici size ne sağlar?
Shopify Flow'unuz, tetiklendiğinde aşağıdakilere erişebilir:
| Alan | Örnek |
|---|---|
variantCostChange.variantId |
gid://shopify/ProductVariant/54589751394579 |
variantCostChange.variantTitle |
Medium / Black |
variantCostChange.sku |
TSHIRT-M-BLK |
variantCostChange.oldCost.amount |
4.00 |
variantCostChange.newCost.amount |
5.20 |
variantCostChange.newCost.currencyCode |
EUR |
Ürün kendisi de bir ürün referansı olarak dahil edilmiştir; bu sayede, fiyat üzerinde herhangi bir değişiklik yapılmadan önce satıcı, tür, etiketler veya koleksiyona göre Shopify Flow koşulları ekleyebilirsiniz.
2. Adım: İşlevi oluşturun
Workflow Functions'ta yeni bir işlev oluşturun ve aşağıdaki kodu yapıştırın.
Kaydetmeden önce, Shopify verilerine ihtiyaç var” seçeneğini etkinleştirin. Bu ayar, ctx.shopify.graphql(...)yi kodunuza açığa çıkararak mağaza verilerini okumasını ve değiştirmesini sağlar. Ardından, Workflow Functions’daki İzinler sayfasını açın ve “ürünlere yazma” iznini verin; bu, işlevin bir fiyatı değiştirebilmesi için gerekli olan kapsamdır.
Bu anahtar ayarı olmadan ctx.shopify nesnesi kullanılamaz ve işlev, ilk Admin API çağrısında hata verir.
export default async function (input, ctx) {
const toGid = (value, type) => {
if (value === undefined || value === null) return null;
const str = String(value).trim();
if (!str) return null;
if (str.startsWith('gid://')) return str;
if (/^\d+$/.test(str)) return `gid://shopify/${type}/${str}`;
return str;
};
try {
const variantId = toGid(input.variantId || input.variant_id || input.id, 'ProductVariant');
if (!variantId) throw new Error('Missing "variantId" in input.');
const hasPrice = input.price !== undefined && input.price !== null && String(input.price).trim() !== '';
const hasCompareAt = Object.prototype.hasOwnProperty.call(input, 'compareAtPrice') || Object.prototype.hasOwnProperty.call(input, 'compare_at_price');
const rawCompareAt = input.compareAtPrice !== undefined ? input.compareAtPrice : input.compare_at_price;
if (!hasPrice && !hasCompareAt) throw new Error('Nothing to update: provide "price" and/or "compareAtPrice".');
const asMoney = (value) => {
const num = Number(value);
if (!Number.isFinite(num) || num < 0) throw new Error(`Invalid money value: ${JSON.stringify(value)}`);
return num.toFixed(2);
};
let productId = toGid(input.productId || input.product_id, 'Product');
if (!productId) {
const readQuery = `
query VariantForPriceUpdate($id: ID!) {
productVariant(id: $id) { id product { id } }
}`;
const readRes = await ctx.shopify.graphql(readQuery, { id: variantId });
if (readRes.errors) throw new Error('Failed to read variant: ' + JSON.stringify(readRes.errors));
const variant = readRes.data && readRes.data.productVariant;
if (!variant) throw new Error(`Variant not found: ${variantId}`);
productId = variant.product && variant.product.id;
if (!productId) throw new Error('Could not resolve the parent product id for the variant.');
}
const variantInput = { id: variantId };
if (hasPrice) variantInput.price = asMoney(input.price);
if (hasCompareAt) {
variantInput.compareAtPrice = rawCompareAt === null || String(rawCompareAt).trim() === '' ? null : asMoney(rawCompareAt);
}
ctx.log('Updating variant', variantId, 'on product', productId, variantInput);
const mutation = `
mutation UpdateVariantPrice($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {
productVariantsBulkUpdate(productId: $productId, variants: $variants) {
productVariants { id }
userErrors { field message }
}
}`;
const res = await ctx.shopify.graphql(mutation, { productId, variants: [variantInput] });
if (res.errors) throw new Error('GraphQL error updating variant: ' + JSON.stringify(res.errors));
const payload = res.data && res.data.productVariantsBulkUpdate;
if (!payload) throw new Error('Unexpected empty response from productVariantsBulkUpdate.');
if (payload.userErrors && payload.userErrors.length) {
throw new Error('Variant update failed: ' + payload.userErrors.map(e => `${(e.field || []).join('.')}: ${e.message}`).join('; '));
}
return { success: true };
} catch (err) {
ctx.log('Error updating variant price:', err.message);
return { success: false };
}
}Kodla ilgili dikkat çekici birkaç nokta:
- Sadece sayısal bir kimlik numarası ya da tam bir GID kabul eder.
toGidher ikisini de standart hale getirir; bu sayede Shopify Flow’un size hangi biçimde vereceğini dert etmenize gerek kalmaz. - Sadece gerekli olduğunda üst ürünü arar.
productVariantsBulkUpdate, bir ürün kimliği gerektirir; eğer bir kimlik aktarmazsanız, işlev bunu kendisi alır. GirişteproductId'yi aktarmanız, bu gidip gelme işlemini ortadan kaldırır. - Sadece aktarım hatalarını değil,
userErrorsdeğerini de kontrol eder. Bir GraphQL çağrısı HTTP 200 yanıtı verse bile yazma işlemini reddedebilir. Bu, fiyat güncellemesinin başarılı gibi görünmesine rağmen hiçbir şeyin değişmemesinin en yaygın nedenidir. compareAt'ın silinmesi kasıtlıdır.compareAtPrice: nullveya boş bir dize aktarılması, bir hata olarak değerlendirilmez; bunun yerine bu değer silinir.
3. Adım: Bağlantıyı yapmadan önce işlevi test edin
Test sekmesini, mağazanızdaki gerçek bir varyant kimliği ile kullanın. Yönetici panelindeki herhangi bir ürün URL’sinden veya tetikleyicinin olay geçmişinden bir tane seçin.
Yazının başarıyla ulaştığını doğrulayabilmek için, tanıyabileceğiniz bir fiyat belirleyin.
{
"variantId": "gid://shopify/ProductVariant/54589751394579",
"price": "24.99",
"compareAtPrice": "39.99"
}4. Adım: Shopify Flow'u bağlayın
Shopify Flow'da bir iş akışı oluşturun:
- Tetikleyici: Ürün Varyantının Maliyetinde Değişiklik
- Eylem: Workflow Functions bölümünden Fonksiyonu Çalıştır seçeneğini seçin ve az önce oluşturduğunuz fonksiyonu seçin
JSON giriş alanına bunu yapıştırın. Shopify Flow, her çalıştırıldığında Liquid kodunu gerçek değerlerle değiştirir.
{
"variantId": "{{variantCostChange.variantId}}",
"price": "{{variantCostChange.newCost.amount | times: 5}}",
"compareAtPrice": "{{variantCostChange.newCost.amount | times: 7}}"
}Fiyatlandırma kuralı tam olarak şudur: Satış fiyatı maliyetin beş katı, karşılaştırma fiyatı ise maliyetin yedi katıdır; böylece ürün her zaman tutarlı bir indirimle gösterilir.
Bu çarpanlar sadece birer örnektir, tavsiye niteliğinde değildir. times: 5 ifadesini, kategorinizin gerçekte desteklediği değere göre değiştirin. Liquid aritmetik işlemleri kendisi halleder; bu nedenle, çarpan yerine sabit bir artış değeri kullanmak isterseniz plus: 12, yüzde marjı kullanmak isterseniz times: 1.6 ifadesini kullanabilirsiniz.
Birden fazla para biriminde satış yapıyorsanız, newCost.amount'ın mağazanın para biriminde olduğunu unutmayın. Markets, görüntüleme anında dönüştürme işlemini kendisi gerçekleştirir; bu nedenle sizin bunu yapmanıza gerek yoktur.
Uçtan uca çalıştığını doğrulayın
- Shopify yönetici panelinde herhangi bir ürün varyantını açın ve Ürün başına maliyet değerini değiştirin
- Kaydet
- Birkaç saniye içinde fiyat ve karşılaştırma fiyatı kendiliğinden güncellenir
Eğer bir şey olmazsa, bu sırayla ilerleyin; çünkü her adım bir öncekini geçersiz kılar:
| Kontrol et | Nerede |
|---|---|
| Tetik ateşlendi mi? | Workflow Trigger Extensions’da Olay Geçmişi |
| Shopify Flow çalıştı mı? | Shopify Flow'un etkinlik günlüğü |
| İşlev çalıştı mı ve günlüğe ne kaydedildi? | Workflow Functions’ta iş akışı geçmişi |
Bir çalıştırma işleminin hata bildirmesinin en yaygın nedeni, kapsam eksikliğidir. ctx.shopify, yalnızca “Shopify verilerine ihtiyaç var” seçeneği etkin olduğunda kullanılabilir ve yazma işlemi, ürün yazma izni verildikten sonra başarılı olur.
Şimdi nereye gitmeli?
Aynı yöntem, maliyet değişikliğinden etkilenmesi gereken her şey için geçerlidir. İşlev gövdesini değiştirerek, maliyet yüzde 10’dan fazla arttığında bir ürünü incelemeye alın, eski ve yeni kâr marjını Slack’e gönderin ya da raporlama amacıyla değişikliği bir meta alana kaydedin.
Tetikleyici, Shopify’ın size sağlamadığı kısımdır. Bundan sonra gelenler ise sıradan kodlardır.
Workflow Functions belgeleri
- İzinler ve mağaza verilerine erişim - “Shopify verileri gerekli” seçeneğini etkinleştirme ve kapsamlara izin verme
- Fonksiyonunuza değişkenleri aktarma - JSON girdisi ve Liquid nasıl çalışır?
- Shopify Flow'da "İşlevi Çalıştır" eylemini ayarlama
- Çalıştırma geçmişi ve sorun giderme
