Ön siparişleri ayrı gönderide tutma
Etiketli ön sipariş ürünlerini ayrı bir ön sipariş lokasyonundan, stoktaki ürünleri diğer lokasyonlardan gönderen Shopify gönderim kısıtı Function’ı.
- Function API
- Fulfillment Constraints
- Hedef (target)
- cart.fulfillment-constraints.generate.run
- Plan
- Herkese açık uygulamada her plan; özel uygulamada Shopify Plus
- Uygulama yetkisi
- write_fulfillment_constraint_rules
- API sürümü
- 2026-10
- Son kontrol
Kısaca
Bu gönderim kısıtı (fulfillment constraints) Function’ı, ön sipariş ürünlerini stoktaki ürünlerden ayırır: ön sipariş etiketli ürünler ayrı bir lokasyondan, diğer her şey öteki lokasyonlarınızdan gönderilir; böylece aynı pakette beklemezler. Fulfillment Constraints API’nin cart.fulfillment-constraints.generate.run hedefini kullanır (sürüm 2026-10) ve herkese açık uygulamada her planda çalışır.
Nasıl kullanılır
- Ön sipariş stoku için bir lokasyon oluşturun ve ön sipariş ürünlerini etiketleyin, örneğin pre-order.
- Shopify CLI 4.9.0 ya da üstüyle bir uygulama oluşturun, uzantıyı ekleyin (shopify app generate extension --template fulfillment_constraints) ve dosyalarını aşağıdakilerle değiştirin.
- Testleri shopify app function run --input tests/mixed-cart.input.json ile çalıştırın, ardından deploy edin.
- fulfillmentConstraintRuleCreate ile deliveryMethodTypes: [SHIPPING] vererek etkinleştirin ve metafields içinde {"preorderTags": ["pre-order"], "preorderLocationId": "gid://shopify/Location/1234567890"} gönderin.
Kod
shopify.extension.tomlapi_version = "2026-10"
[[extensions]]
name = "Keep pre-orders in a separate shipment"
handle = "pre-orders-separate-shipment"
type = "function"
[[extensions.targeting]]
target = "cart.fulfillment-constraints.generate.run"
input_query = "src/cart_fulfillment_constraints_generate_run.graphql"
input_variables = { namespace = "$app", key = "function-configuration" }
export = "cart-fulfillment-constraints-generate-run"
[extensions.build]
command = ""
path = "dist/function.wasm"
src/cart_fulfillment_constraints_generate_run.graphqlquery CartFulfillmentConstraintsGenerateRunInput($preorderTags: [String!]) {
cart {
deliverableLines {
id
merchandise {
__typename
... on ProductVariant {
product {
hasAnyTag(tags: $preorderTags)
}
}
}
}
}
locations {
id
}
fulfillmentConstraintRule {
metafield(namespace: "$app", key: "function-configuration") {
jsonValue
}
}
}
src/cart_fulfillment_constraints_generate_run.js// @ts-check
/**
* @typedef {import("../generated/api").CartFulfillmentConstraintsGenerateRunInput} CartFulfillmentConstraintsGenerateRunInput
* @typedef {import("../generated/api").CartFulfillmentConstraintsGenerateRunResult} CartFulfillmentConstraintsGenerateRunResult
*/
/**
* Settings stored as JSON in the rule's metafield. `preorderTags` in the same
* JSON feeds the query variable (see input_variables in the toml), e.g.
* { "preorderTags": ["pre-order"], "preorderLocationId": "gid://shopify/Location/1234567890" }.
*/
const DEFAULT_CONFIG = {
// The location that holds (or will receive) pre-order stock.
preorderLocationId: /** @type {string | null} */ (null),
};
/** @type {CartFulfillmentConstraintsGenerateRunResult} */
const NO_CONSTRAINTS = { operations: [] };
/**
* @param {CartFulfillmentConstraintsGenerateRunInput} input
* @returns {CartFulfillmentConstraintsGenerateRunResult}
*/
export function cartFulfillmentConstraintsGenerateRun(input) {
const config = { ...DEFAULT_CONFIG, ...input.fulfillmentConstraintRule?.metafield?.jsonValue };
const preorderLocationId = config.preorderLocationId;
if (!preorderLocationId) return NO_CONSTRAINTS;
const isPreorder = (/** @type {(typeof input.cart.deliverableLines)[number]} */ line) =>
line.merchandise.__typename === "ProductVariant" && line.merchandise.product.hasAnyTag;
const preorderLineIds = input.cart.deliverableLines.filter(isPreorder).map((line) => line.id);
const inStockLineIds = input.cart.deliverableLines.filter((line) => !isPreorder(line)).map((line) => line.id);
if (preorderLineIds.length === 0) return NO_CONSTRAINTS;
const operations = [
{ deliverableLinesMustFulfillFromAdd: { deliverableLineIds: preorderLineIds, locationIds: [preorderLocationId] } },
];
// Keeping the in-stock items away from the pre-order location is what
// splits the order: they can no longer wait in the same package.
const otherLocationIds = input.locations.map((location) => location.id).filter((id) => id !== preorderLocationId);
if (inStockLineIds.length > 0 && otherLocationIds.length > 0) {
operations.push({
deliverableLinesMustFulfillFromAdd: { deliverableLineIds: inStockLineIds, locationIds: otherLocationIds },
});
}
return { operations };
}
Test girdisi ve beklenen çıktı
tests/mixed-cart.input.json{
"cart": {
"deliverableLines": [
{ "id": "gid://shopify/DeliverableCartLine/1", "merchandise": { "__typename": "ProductVariant", "product": { "hasAnyTag": false } } },
{ "id": "gid://shopify/DeliverableCartLine/2", "merchandise": { "__typename": "ProductVariant", "product": { "hasAnyTag": true } } }
]
},
"locations": [
{ "id": "gid://shopify/Location/1111111111" },
{ "id": "gid://shopify/Location/2222222222" },
{ "id": "gid://shopify/Location/3333333333" }
],
"fulfillmentConstraintRule": {
"metafield": {
"jsonValue": { "preorderTags": ["pre-order"], "preorderLocationId": "gid://shopify/Location/3333333333" }
}
}
}
tests/mixed-cart.output.json{
"operations": [
{
"deliverableLinesMustFulfillFromAdd": {
"deliverableLineIds": ["gid://shopify/DeliverableCartLine/2"],
"locationIds": ["gid://shopify/Location/3333333333"]
}
},
{
"deliverableLinesMustFulfillFromAdd": {
"deliverableLineIds": ["gid://shopify/DeliverableCartLine/1"],
"locationIds": ["gid://shopify/Location/1111111111", "gid://shopify/Location/2222222222"]
}
}
]
}
tests/no-location-configured.input.json{
"cart": {
"deliverableLines": [
{ "id": "gid://shopify/DeliverableCartLine/1", "merchandise": { "__typename": "ProductVariant", "product": { "hasAnyTag": true } } }
]
},
"locations": [{ "id": "gid://shopify/Location/1111111111" }],
"fulfillmentConstraintRule": { "metafield": null }
}
tests/no-location-configured.output.json{ "operations": [] }
tests/only-in-stock-items.input.json{
"cart": {
"deliverableLines": [
{ "id": "gid://shopify/DeliverableCartLine/1", "merchandise": { "__typename": "ProductVariant", "product": { "hasAnyTag": false } } }
]
},
"locations": [
{ "id": "gid://shopify/Location/1111111111" },
{ "id": "gid://shopify/Location/2222222222" },
{ "id": "gid://shopify/Location/3333333333" }
],
"fulfillmentConstraintRule": {
"metafield": {
"jsonValue": { "preorderTags": ["pre-order"], "preorderLocationId": "gid://shopify/Location/3333333333" }
}
}
}
tests/only-in-stock-items.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
- Kısıtlı bir ürün izin verilen lokasyonlarda stokta değilse checkout kargo seçeneği göstermez ve tamamlanamaz. Ön sipariş stokunu ön sipariş lokasyonunda tutun.
- Birbirini dışlayan kısıtlar da tüm kargo seçeneklerini kaldırır; her ürün tipini içeren sepetlerle test edin.
- Kural, Function’ın adı ve açıklamasıyla Ayarlar › Kargo ve teslimat › Sipariş yönlendirme (Order routing) altında görünür.
- Bir mağazada en fazla 25 gönderim kısıtı Function’ı etkin olabilir.
Sık sorulan sorular
- Shopify’da ön siparişleri stoktaki ürünlerden ayrı nasıl gönderirim?
- Ön sipariş stokunu ayrı bir lokasyonda tutun ve bu örnekteki gibi ön sipariş satırlarını o lokasyona, diğer satırları geri kalan lokasyonlara bağlayan bir gönderim kısıtı Function’ı kullanın.
- Mağazadan teslim siparişlerine de uygulanır mı?
- Yalnızca fulfillmentConstraintRuleCreate’e verdiğiniz teslimat yöntemi tiplerine uygulanır. Bu örnek SHIPPING kullanır; mağazadan teslim siparişleri kısıtlanmaz.
- Ön siparişleri etiket olmadan tespit edebilir miyim?
- Teslim edilebilir satırlar (deliverable lines) satış planını göstermediği için bu örnek ürün etiketi kullanır. İsterseniz bir varyant metafield’ı da işinizi görür.
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.
