Posta kutusu adreslerini engelleme

Teslimat adresi posta kutusu olduğunda checkout’u durduran ve adres alanında mesaj gösteren Shopify sepet ve ödeme doğrulama Function’ı.

Function API
Cart and Checkout Validation
Hedef (target)
cart.validations.generate.run
Plan
Herkese açık uygulamada her plan; özel uygulamada Shopify Plus
Uygulama yetkisi
write_validations
API sürümü
2026-10
Son kontrol

Kısaca

Bu doğrulama Function’ı, teslimat adresi posta kutusuysa checkout’u durdurur ve mesajınızı adres satırı alanında gösterir. “PO Box”, “P.O. Box” ve “Post Office Box” gibi yaygın yazımları tanır. Cart and Checkout Validation API’nin cart.validations.generate.run hedefini kullanır (sürüm 2026-10) ve herkese açık bir uygulamada her planda çalışır.

Nasıl kullanılır

  1. Shopify CLI ile bir uygulama oluşturun ve uzantıyı ekleyin: shopify app generate extension --template cart_checkout_validation, dil olarak JavaScript.
  2. Oluşturulan shopify.extension.toml dosyasını ve src/ içindeki iki dosyayı aşağıdakilerle değiştirin.
  3. Testleri çalıştırın: shopify app function run --input tests/po-box-in-address1.input.json.
  4. shopify app deploy ile deploy edin ve doğrulamayı validationCreate ile etkinleştirin.
  5. İsterseniz kendi mesajınızı doğrulamanın $app:function-configuration metafield’ına yazın: {"message": "…"}.

Kod

shopify.extension.toml
api_version = "2026-10"

[[extensions]]
name = "Block PO box addresses"
handle = "block-po-box-addresses"
type = "function"

  [[extensions.targeting]]
  target = "cart.validations.generate.run"
  input_query = "src/cart_validations_generate_run.graphql"
  export = "cart-validations-generate-run"

  [extensions.build]
  command = ""
  path = "dist/function.wasm"
src/cart_validations_generate_run.graphql
query CartValidationsGenerateRunInput {
  cart {
    deliveryGroups {
      deliveryAddress {
        address1
        address2
      }
    }
  }
  validation {
    metafield(namespace: "$app", key: "function-configuration") {
      jsonValue
    }
  }
}
src/cart_validations_generate_run.js
// @ts-check

/**
 * @typedef {import("../generated/api").CartValidationsGenerateRunInput} CartValidationsGenerateRunInput
 * @typedef {import("../generated/api").CartValidationsGenerateRunResult} CartValidationsGenerateRunResult
 */

/** Settings stored as JSON in the validation's metafield. */
const DEFAULT_CONFIG = {
  message: "We can't ship to PO boxes. Please enter a street address.",
};

/**
 * Checkout can point an error at the first delivery group's address only, so
 * a PO box in any group is reported on that field.
 */
const ADDRESS1_TARGET = "$.cart.deliveryGroups[0].deliveryAddress.address1";

/**
 * "PO box" spellings anywhere in the line, after a space or punctuation:
 * "P.O. Box", "PO Box", "Post Office Box", "Postfach", Turkish "Posta Kutusu"
 * and "PK" followed by a number ("Kadıköy PK 34"). The leading boundary keeps
 * words such as "Spk" or "Park" from matching.
 */
const PO_BOX =
  /(?:^|[^\p{L}\p{N}])(?:p\.?\s*o\.?\s*box|post\s*office\s*box|post\s*box|postfach|posta\s*kutusu|p\.?\s*k\.?\s*\d)/iu;

/** @param {string | null | undefined} line */
const isPoBox = (line) => PO_BOX.test(line ?? "");

/** @type {CartValidationsGenerateRunResult} */
const NO_ERRORS = { operations: [] };

/**
 * @param {CartValidationsGenerateRunInput} input
 * @returns {CartValidationsGenerateRunResult}
 */
export function cartValidationsGenerateRun(input) {
  const config = { ...DEFAULT_CONFIG, ...input.validation?.metafield?.jsonValue };
  const hasPoBox = input.cart.deliveryGroups.some(
    (group) => isPoBox(group.deliveryAddress?.address1) || isPoBox(group.deliveryAddress?.address2),
  );
  if (!hasPoBox) return NO_ERRORS;

  return {
    operations: [{ validationAdd: { errors: [{ message: config.message, target: ADDRESS1_TARGET }] } }],
  };
}
Test girdisi ve beklenen çıktı
tests/po-box-after-district.input.json
{
  "cart": {
    "deliveryGroups": [
      {
        "deliveryAddress": {
          "address1": "Kadıköy PK 34",
          "address2": null
        }
      }
    ]
  },
  "validation": {
    "metafield": null
  }
}
tests/po-box-after-district.output.json
{
  "operations": [
    {
      "validationAdd": {
        "errors": [
          {
            "message": "We can't ship to PO boxes. Please enter a street address.",
            "target": "$.cart.deliveryGroups[0].deliveryAddress.address1"
          }
        ]
      }
    }
  ]
}
tests/po-box-in-address1.input.json
{
  "cart": { "deliveryGroups": [{ "deliveryAddress": { "address1": "PO Box 88", "address2": null } }] },
  "validation": { "metafield": null }
}
tests/po-box-in-address1.output.json
{
  "operations": [
    {
      "validationAdd": {
        "errors": [
          {
            "message": "We can't ship to PO boxes. Please enter a street address.",
            "target": "$.cart.deliveryGroups[0].deliveryAddress.address1"
          }
        ]
      }
    }
  ]
}
tests/post-office-box-in-address2.input.json
{
  "cart": {
    "deliveryGroups": [{ "deliveryAddress": { "address1": "Main Post Office", "address2": "Post Office Box 1207" } }]
  },
  "validation": { "metafield": null }
}
tests/post-office-box-in-address2.output.json
{
  "operations": [
    {
      "validationAdd": {
        "errors": [
          {
            "message": "We can't ship to PO boxes. Please enter a street address.",
            "target": "$.cart.deliveryGroups[0].deliveryAddress.address1"
          }
        ]
      }
    }
  ]
}
tests/street-address.input.json
{
  "cart": { "deliveryGroups": [{ "deliveryAddress": { "address1": "45 Harbor Street", "address2": "Unit 3" } }] },
  "validation": { "metafield": null }
}
tests/street-address.output.json
{ "operations": [] }
tests/street-names-like-pk.input.json
{
  "cart": {
    "deliveryGroups": [
      {
        "deliveryAddress": {
          "address1": "Spk Sokak No 5",
          "address2": "Park Apt 3"
        }
      }
    ]
  },
  "validation": {
    "metafield": null
  }
}
tests/street-names-like-pk.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

  • Checkout bir hatayı yalnızca ilk teslimat grubunun adresine bağlayabilir; ikinci gönderideki posta kutusu da aynı alanda gösterilir.
  • Tespit bir metin kontrolüdür; yaratıcı yazımları kaçırabilir, nadiren bir sokak adını da yakalayabilir. Müşterilerinizin gerçek adresleriyle test edin.
  • Bir mağazada en fazla 25 doğrulama Function’ı etkin olabilir.
  • Yalnızca posta kutusunda kurye fiyatlarını kapatmak istiyorsanız bunun yerine teslimat özelleştirmesiyle o seçenekleri gizleyin.

Sık sorulan sorular

Shopify’da müşterilerin posta kutusuna gönderim yapmasını nasıl engellerim?
Bunun için bir ayar yok. Bu örnekteki gibi bir sepet ve ödeme doğrulama Function’ı adres satırlarını kontrol edip checkout’u bir mesajla engelleyebilir.
Hata adres alanında görünüyor mu?
Evet. Hata $.cart.deliveryGroups[0].deliveryAddress.address1 hedefine yazılır; checkout onu ilk adres satırının altında gösterir.
Shop Pay ya da Apple Pay gibi hızlı ödemeleri de engeller mi?
Shopify’ın referansına göre doğrulama Function’ları hızlı ödemelerde de çalışır; aynı kural orada da geçerli olur.
  • 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.

Geliştirmek istediğiniz bir şey mi var? Gelin, birlikte konuşalım.

Aynı anda sınırlı sayıda proje alıyoruz.

Gencer KarakayaShopify mühendisi

Proje özetinizi bir mühendis okur; size e-postayla yanıt veririz.