# Kategori, ürün markası ve kupon yazmak

> **Ne yaparsınız:** Kategori, ürün markası ve kupon oluşturur, günceller, arşive alıp geri getirirsiniz.
> **Hangi uçlar:** [Kategori oluştur](https://developer.siparis.app/uc/kategori-olustur), [Kategoriyi güncelle](https://developer.siparis.app/uc/kategoriyi-guncelle), [Ürün markası oluştur](https://developer.siparis.app/uc/urun-markasi-olustur), [Ürün markasını güncelle](https://developer.siparis.app/uc/urun-markasini-guncelle), [Kupon oluştur](https://developer.siparis.app/uc/kupon-olustur), [Kuponları listele](https://developer.siparis.app/uc/kuponlari-listele), [Kuponu güncelle](https://developer.siparis.app/uc/kuponu-guncelle), [Kuponu arşivle](https://developer.siparis.app/uc/kuponu-arsivle), [Kuponu geri getir](https://developer.siparis.app/uc/kuponu-geri-getir)
> **Gereken izin:** Kategori ve ürün markası için `products:write`, kupon için `coupons:write`; arşiv ve geri getirme için ayrıca `archive:write`.

API adresi `https://api.siparis.app/v1`. Okumak için kategori ve ürün markasında `products:read`, kuponda `coupons:read` gerekir; yazma kapsamı (izni) tek başına okuma izni vermez.

Kategori ve ürün markası işletme genelindedir; yalnız bütün markalara yetkili bağlantı bunları değiştirebilir. İki marka kavramını karıştırmayın: ürün markası (`brand`, `brd_`) ürünün üreticisidir, satış markası (`store`, `sto_`) işletmenizin markasıdır. Kupon bir satış markasına aittir. Tek markada veya marka sınırlı anahtarda `store` atlanabilir; çok markada `GET /stores` ile bulduğunuz `sto_` kimliğini kupon oluşturma gövdesine ekleyin.

Anahtarı sunucunuzdaki `SIPARIS_API_KEY` ortam değişkeninde tutun. Örnekler bash ve curl içindir; kimlik yer tutucularını kendi yanıtlarınızdaki değerlerle değiştirin. Her yeni işte yeni `Idempotency-Key` (tekrar anahtarı: aynı isteği güvenle yeniden göndermek için sizin ürettiğiniz benzersiz metin) kullanın. Yanıt kaybolursa aynı gövde ve aynı anahtarla tekrarlayın: işlem ikinci kez uygulanmaz, `Idempotent-Replayed: true` ile kaydın güncel hali döner.

## Kategori ve ürün markası oluşturun

İlk örnek için zorunlu alanlar (POST /v1/categories):

| Alan | Tür | Açıklama | Örnek |
| --- | --- | --- | --- |
| `name` | metin (en çok 500 karakter) | Kategori adı. | `"Mutfak"` |

Bütün alanlar: [Kategori oluştur](https://developer.siparis.app/uc/kategori-olustur).

```bash
curl --fail-with-body --silent --show-error --include \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/categories" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: kategori-20261016-001' \
  --data '{"name":"Mutfak","parent":null,"sort_order":1,"status":"active","description":"Mutfak ürünleri"}'
```

Örnek HTTP 201 yanıtı (uydurma veri):

```json
{
  "archived": false,
  "created_at": "2026-10-16T09:00:00Z",
  "description": "Seramik kupa, 300 ml.",
  "id": "cat_1234567890abcdef1234567890abcdef",
  "image": "https://example.com/kupa.jpg",
  "name": "Mutfak",
  "parent": null,
  "revision": 1,
  "slug": "ornek-kupa",
  "sort_order": 0,
  "status": "active",
  "updated_at": "2026-10-16T09:00:00Z"
}
```



```bash
curl --fail-with-body --silent --show-error --include \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/brands" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: urun-markasi-20261016-001' \
  --data '{"name":"Örnek Üretici","sort_order":1,"status":"active"}'
```

Yanıt `201`, `Location`, `ETag` (sürüm etiketi) ve sırasıyla `cat_` / `brd_` kimliği içerir. `status: "inactive"` vitrinde gizler. Panelde olduğu gibi aynı adla ayrı kayıt açılabilir, adresi otomatik ayrılır; ad benzersiz kimlik değildir.

## Adı, üst kategoriyi, sırayı ve görünürlüğü değiştirin

```bash
curl --fail-with-body --silent --show-error -X PATCH \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/categories/cat_1234567890abcdef1234567890abcdef" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: kategori-duzelt-20261016-001' \
  -H 'If-Match: "1"' \
  --data '{"name":"Mutfak ve Sofra","parent":null,"sort_order":2,"status":"active"}'
```

Üst kategori için `parent: "cat_…"`, ana kategori için `parent: null` gönderin. Kategori kendisinin veya alt kategorisinin altına taşınamaz. Ürün markasını [Ürün markasını güncelle](https://developer.siparis.app/uc/urun-markasini-guncelle) ile aynı biçimde güncelleyin. Atlanan alanlar korunur.

`If-Match` isteğe bağlıdır: en son ayrıntı GET veya yazma yanıtının ETag değerini tırnaklarıyla gönderin; kayıt bu arada değiştiyse yazma yapılmaz. Panel/AI değişiklikleri de `revision` (kaydın sürüm numarası) değerini artırır. `412 revision_mismatch` durumunda kaydı yeniden okuyun, değişikliği değerlendirin ve yeni tekrar anahtarı kullanın.

## Kupon oluşturun ve okuyun

İlk örnek için zorunlu alanlar (POST /v1/coupons):

| Alan | Tür | Açıklama | Örnek |
| --- | --- | --- | --- |
| `code` | metin (en çok 40 karakter) | Müşterinin yazacağı kupon kodu. | `"MERHABA10"` |

Bütün alanlar: [Kupon oluştur](https://developer.siparis.app/uc/kupon-olustur).

```bash
curl --fail-with-body --silent --show-error --include \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/coupons" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: kupon-20261016-001' \
  --data '{"code":"MERHABA10","discount_type":"percentage","discount_value":"10.00","min_order":"100.00","max_uses":100,"max_uses_per_customer":1,"valid_from":"2026-10-16","valid_until":"2026-12-31T23:59","categories":[],"first_order_only":false,"free_shipping":false,"exclude_discounted":true}'
```

Örnek HTTP 201 yanıtı (uydurma veri):

```json
{
  "archived": false,
  "categories": [],
  "category_restricted": false,
  "code": "MERHABA10",
  "created_at": "2026-10-16T09:00:00Z",
  "currency": "TRY",
  "customer_restricted": false,
  "discount_type": "percentage",
  "discount_value": "10.00",
  "exclude_discounted": false,
  "first_order_only": false,
  "free_shipping": false,
  "id": "cpn_1234567890abcdef1234567890abcdef",
  "max_uses": 100,
  "max_uses_per_customer": 1,
  "min_order": "100.00",
  "revision": 1,
  "status": "active",
  "store": "sto_1234567890abcdef1234567890abcdef",
  "updated_at": "2026-10-16T09:00:00Z",
  "used_count": 0,
  "valid_from": "2026-10-16",
  "valid_until": "2026-12-31T23:59"
}
```



İndirim türü, kullanım sınırları ve diğer seçeneklerin anlamı [Kupon oluştur](https://developer.siparis.app/uc/kupon-olustur) sayfasındadır. Kod panelle aynı biçimde normalleştirilir; aynı satış markasında canlı kuponlar arasında tekildir. Eş zamanlı çakışmada da `409 coupon_code_taken` gelir.

Kuponun geçerli olduğu ürünler `categories: ["cat_…"]` ile kategori ve alt kategorileridir; `[]` bütün ürünlere açar. Kuponda tek tek ürün seçimi bulunmaz. Okumada `category_restricted` kategori sınırını belirtir; marka sınırlı bağlantıda görünmeyen kategoriler listeden çıkar, boş görünen liste tek başına bütün ürünler anlamına gelmez. Müşteriye özel kuponların kişisel alanları veya müşteri kimlikleri bu API'den yayımlanmaz; yalnız `customer_restricted` bilgisi gelir.

Tarihler satış markasının yerel takvimine göredir. Yalnız gün yazılırsa günün tamamı, saat yazılırsa son dakika dahil edilir. Saat dilimli ISO zaman markanın saatine çevrilir. `null` başlangıç/bitiş sınırını kaldırır.

```bash
curl --fail-with-body --silent --show-error --get \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/coupons" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  --data-urlencode 'limit=20'
```

Örnek HTTP 200 yanıtı (uydurma veri):

```json
{
  "data": [
    {
      "archived": false,
      "categories": [],
      "category_restricted": false,
      "code": "MERHABA10",
      "created_at": "2026-10-16T09:00:00Z",
      "currency": "TRY",
      "customer_restricted": false,
      "discount_type": "percentage",
      "discount_value": "10.00",
      "exclude_discounted": false,
      "first_order_only": false,
      "free_shipping": false,
      "id": "cpn_1234567890abcdef1234567890abcdef",
      "max_uses": 100,
      "max_uses_per_customer": 1,
      "min_order": "100.00",
      "revision": 1,
      "status": "active",
      "store": "sto_1234567890abcdef1234567890abcdef",
      "updated_at": "2026-10-16T09:00:00Z",
      "used_count": 0,
      "valid_from": "2026-10-16",
      "valid_until": "2026-12-31T23:59"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
```



Sonraki sayfada `next_cursor` değerini (sonraki sayfanın yer imi) `cursor` parametresine gönderin; aynı filtreleri koruyun. İşletme genelindeki bağlantı `store=sto_…` ile süzebilir. Ayrıntı `GET /coupons/{id}`; arşiv dahil okuma `archived=true` ile yapılır. `used_count`, panelle aynı kullanım sayısıdır; iptal ve tam iadeler sayılmaz. Yanıtta kişisel veri yoktur.

## Kuponu güncelleyin

```bash
curl --fail-with-body --silent --show-error -X PATCH \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/coupons/cpn_1234567890abcdef1234567890abcdef" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: kupon-duzelt-20261016-001' \
  -H 'If-Match: "1"' \
  --data '{"discount_value":"15.00","max_uses":200,"valid_until":"2027-01-31"}'
```

Kod, indirim, kapsam, geçerlilik, sınırlar ve `status` güncellenebilir; satış markası değiştirilemez. `status: "inactive"` kuponu kapatır. Atlanan alan korunur; boş güncelleme kabul edilmez.

## Arşivleyin ve geri getirin

```bash
curl --fail-with-body --silent --show-error \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/coupons/cpn_1234567890abcdef1234567890abcdef/archive" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: kupon-arsiv-20261016-001' \
  --data '{}'
```

```bash
curl --fail-with-body --silent --show-error \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/coupons/cpn_1234567890abcdef1234567890abcdef/restore" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: kupon-geri-20261016-001' \
  --data '{}'
```

Kategori ve ürün markası için aynı çağrıları `/categories/{id}/archive|restore` ve `/brands/{id}/archive|restore` yollarına yapın. Güncel ETag ile `If-Match` bu işlemlerde de kullanılabilir. Arşiv kayıt silmez. Arşivli kupon sepette uygulanmaz; arşivli kategori vitrinde görünmez. Ürünlü kategori arşivlenebilir: ürün bağları korunur, alt kategoriler bir üst seviyeye taşınır. Geri getirme panelin aynı kurallarını kullanır; kayıt arşivden önceki görünürlüğünü korur, taşınmamış alt kategoriler yeniden bağlanır. Kupon kodu başka canlı kayıtta kullanılıyorsa geri getirme `coupon_code_taken` ile durur. Vitrin önbelleği panelle aynı yoldan yenilenir.

## Sık hatalar

| Yanıt | Yapılacak işlem |
| --- | --- |
| `403 insufficient_scope` | Kaynağın yazma ve gerekiyorsa arşiv kapsamını ekleyin. |
| `403 business_scope_required` | Kategori/ürün markası için bütün markalara yetkili bağlantı kullanın. |
| `404 not_found` | Kimliği, arşiv durumunu ve işletme/marka sınırını kontrol edin. |
| `409 coupon_code_taken` | O markadaki mevcut kuponu kullanın veya başka kod seçin. |
| `409 taxonomy_name_conflict` | Aynı anda oluşan adres çakışmasını kontrol edip yeni anahtarla deneyin. |
| `409 taxonomy_restore_conflict` / `409 coupon_restore_conflict` | Kaydın arşiv durumunu ve paneldeki engeli kontrol edin. |
| `422 category_cycle` | Üst kategoriyi kendisi veya alt kategorisi dışında seçin. |
| `412 revision_mismatch` | Güncel kaydı ve ETag'i okuyun; yeni tekrar anahtarı kullanın. |
