# Add-on Tanımları

https://dev.wisecp.com/tr/addon-tanimlari

Katalogdaki add-on tanımlarını, seçeneklerini, ikonlarını ve kategorilerini yöneten on bir uç.

## Genel Bakış

Add-on tanımı, bir ürünün yanında satılan seçeneğin **şablonudur**: ek disk, otomatik yedekleme, ek lisans. Müşterinin hizmetine eklenmiş olan add-on bundan farklı bir şeydir; burada katalogdaki tanımı yönetirsiniz.

Bir tanımın içinde **seçenekler** vardır ve asıl fiyat oradadır. Seçenekler dil altında yaşar, çünkü adları çevrilir; fiyat ise para birimi başına ayrı tutulur.

Son dört uç add-on kategorilerini yönetir. Kategori tek başına bir şey yapmaz, add-on kataloğunu düzenler.

## Referans

### Add-on Tanımlarını Listeleme

get/api/v1/admin/products/addons

`Products/GetProductAddons` admin sayfalı

Katalogdaki add-on tanımlarını döndürür.

Sorgu parametreleri 5

groupstringAna grup anahtarına göre süzer.

categoryintAdd-on kategorisine göre süzer.

searchstringAdd-on adında arar.

pageintVarsayılan 1.

limitintVarsayılan 25, en çok 100.

Dönen alanlar data[] — 9

idintAdd-on kimliği.

namestringAdd-on adı, geçerli dilde.

descriptionstringAçıklama.

groupstringAna grup anahtarı.

categoryintAdd-on kategorisinin kimliği.

statusstring`active` ya da `inactive`.

rankintGörüntülenme sırası.

icon_typestring`font` ya da `image`.

iconstringİkon sınıfı.

Meta 4

totalintSüzgece uyan toplam kayıt.

pageintBulunduğunuz sayfa.

limitintSayfa boyutu.

next_pageintSonraki sayfa. Sıfır son sayfada olduğunuz anlamına gelir.

Hatalar 1

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -G 'https://panel.ornek.com/api/v1/admin/products/addons' \
  -H "Authorization: Bearer $API_KEY" \
  -d group=hosting
```

```javascript
const url = new URL('https://panel.ornek.com/api/v1/admin/products/addons');
url.searchParams.set('group', 'hosting');

const res  = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
const body = await res.json();
```

```php
$url = 'https://panel.ornek.com/api/v1/admin/products/addons?' . http_build_query(['group' => 'hosting']);

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
$response = Api::Products()->GetProductAddons([], ['group' => 'hosting']);
```

### Add-on Detayı

get/api/v1/admin/products/addons/{id}

`Products/GetProductAddon` admin seçenekler dil altında

Bir add-on tanımını tüm ayarları, kuralları ve her dildeki seçenekleriyle döndürür.

Dönen alanlar data — 15

idintAdd-on kimliği.

groupstringAna grup anahtarı.

categoryintAdd-on kategorisinin kimliği.

statusstring`active` ya da `inactive`.

rankintGörüntülenme sırası.

override_user_currencyboolMüşterinin para birimini yok sayar mı.

tax_exemptboolVergiden muaf mı.

requirement_idsint[]Bağlı gereksinim kimlikleri.

product_linkobjectBağlı ürün: `{id, type}`.

icon_typestring`font` ya da `image`.

iconstringİkon sınıfı ya da yüklenen görselin adı.

list_templateintListe şablonunun kimliği.

typestringMüşterinin gördüğü girdi biçimi: `select`, `quantity`, `checkbox` ya da `radio`.

propertiesobjectGirdi tipine göre kurallar: zorunluluk, çoklu satın alma, en az ve en çok adet, adım, fiyatın ürün dönemine bağlanması.

langsobject 3 alanDil kodundan içerik nesnesine eşleme.

namestringAdd-on adı.

descriptionstringAçıklama.

optionsobject[] 9 alanBu dildeki seçenekler.

idintSeçenek kimliği.

namestringSeçeneğin o dildeki adı.

periodstring`day`, `month` ya da `year`.

period_timeintDönem çarpanı. Üç ay için dönem ay, çarpan üçtür.

amountfloatFiyat. Tek para birimli şekilde gelir.

cidintPara birimi kimliği. Tek para birimli şekilde gelir.

pricingobjectPara birimi kimliğinden `{enabled, amount}` nesnesine eşleme. Çok para birimli şekilde gelir.

moduleobjectModül adından yapılandırmaya eşleme. Seçenek seçilince modüle geçirilecek değerler.

hiddenboolSeçenek gizli mi.

Hatalar 2

not_found404Add-on bulunamadı.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl 'https://panel.ornek.com/api/v1/admin/products/addons/148' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res  = await fetch('https://panel.ornek.com/api/v1/admin/products/addons/148', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/products/addons/148');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
$response = Api::Products()->GetProductAddon(['id' => 148]);

// Fiyat iki sekilde gelebilir; ikisini de karsilayin.
$option = $response['data']['langs']['en']['options'][0];
$price  = $option['pricing']['1']['amount'] ?? $option['amount'] ?? 0;
```

Yanıt 200

```json
{
  "data": {
    "id": 148,
    "group": "server",
    "category": 296,
    "status": "active",
    "type": "select",
    "properties": { "show_by_pp": 1, "multiple_purchases": 0 },
    "requirement_ids": [],
    "product_link": { "id": 0, "type": "" },
    "langs": {
      "en": {
        "name": "Automated Backups",
        "description": "Keeps daily backups.",
        "options": [
          {
            "id": 0,
            "name": "I want",
            "period": "month",
            "period_time": 1,
            "amount": 2,
            "cid": 5,
            "module": {
              "HetznerCloud": { "configurable": { "backup": 1 } }
            }
          }
        ]
      }
    }
  }
}
```

### Add-on Tanımı Oluşturma

post/api/v1/admin/products/addons

`Products/CreateProductAddon` admin 201

Katalogda yeni bir add-on tanımı açar.

Gövde 21

groupstringzorunluAna grup anahtarı. Grup listesi ucundan alınır.

categoryintzorunluAdd-on kategorisinin kimliği.

nameobjectzorunluDil kodundan ada eşleme. Geçerli dilin adı olmalı.

descriptionobjectDil kodundan açıklamaya eşleme.

statusstring`active` ya da `inactive`.

rankintGörüntülenme sırası.

typestringGirdi biçimi: `select`, `checkbox`, `radio` ya da `quantity`.

compulsoryboolAdd-on'u zorunlu kılar.

min_quantityintEn az adet. Adet girdisinde anlamlı.

max_quantityintEn çok adet.

stepintAdet artış adımı.

multiple_purchasesboolAynı add-on'un birden çok kez alınmasına izin verir.

show_by_product_periodboolFiyatı ürünün dönemine göre gösterir.

override_user_currencyboolMüşterinin para birimini yok sayar.

tax_exemptboolVergiden muaf kılar.

requirement_idsint[]Bağlanacak gereksinim kimlikleri.

product_linkintBağlanacak ürünün kimliği.

icon_typestring`font` ya da `image`.

iconstringİkon sınıfı.

list_templateintListe şablonunun kimliği.

optionsobjectSeçenek anahtarından seçenek nesnesine eşleme. Her seçenek dil başına ad, para birimi başına fiyat, dönem, modül yapılandırması ve gizlilik taşır. Göndermek tüm seti değiştirir.

Dönen alanlar data

dataobjectOluşturulan add-on, `201` ile döner. Detay ucuyla aynı şekildedir.

Hatalar 5

group_required422`group` boş.

category_required422`category` boş.

name_required422Geçerli dilde ad yok.

create_failed422Oluşturma reddedildi.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X POST 'https://panel.ornek.com/api/v1/admin/products/addons' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"group":"hosting","category":12,"type":"select","name":{"en":"Extra Disk"},"options":{"o1":{"name":{"en":"10 GB"},"pricing":{"1":{"enabled":true,"amount":5}},"cycle":"monthly"}}}'
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/products/addons', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    group: 'hosting',
    category: 12,
    type: 'select',
    name: { en: 'Extra Disk' },
    options: {
      o1: {
        name: { en: '10 GB' },
        pricing: { 1: { enabled: true, amount: 5 } },
        cycle: 'monthly',
      },
    },
  }),
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/products/addons');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'group'    => 'hosting',
        'category' => 12,
        'type'     => 'select',
        'name'     => ['en' => 'Extra Disk'],
        'options'  => [
            'o1' => [
                'name'    => ['en' => '10 GB'],
                'pricing' => [1 => ['enabled' => true, 'amount' => 5]],
                'cycle'   => 'monthly',
            ],
        ],
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
$response = Api::Products()->CreateProductAddon([
    'group'    => 'hosting',
    'category' => 12,
    'type'     => 'select',
    'name'     => ['en' => 'Extra Disk'],
    'options'  => [
        'o1' => [
            'name'    => ['en' => '10 GB'],
            'pricing' => [1 => ['enabled' => true, 'amount' => 5]],
            'cycle'   => 'monthly',
        ],
    ],
]);
```

### Add-on Tanımını Güncelleme

patch/api/v1/admin/products/addons/{id}

`Products/UpdateProductAddon` admin seçenekler hep-veya-hiç

Gönderdiğiniz alanları uygular. Seçenekleri gönderirseniz set olduğu gibi değişir. Tüm gövde alanları opsiyoneldir. Aktif, onay bekleyen ya da askıya alınmış hizmetlerin kullandığı seçenek kilitlidir: gönderdiğiniz set onu aynı ödeme dönemiyle içermelidir.

Gövde 21

groupstringAna grup anahtarı. Grup listesi ucundan alınır.

categoryintAdd-on kategorisinin kimliği.

nameobjectDil kodundan ada eşleme. Yalnız gönderdiğiniz dil değişir.

descriptionobjectDil kodundan açıklamaya eşleme.

statusstring`active` ya da `inactive`.

rankintGörüntülenme sırası.

typestringGirdi biçimi: `select`, `checkbox`, `radio` ya da `quantity`.

compulsoryboolAdd-on'u zorunlu kılar.

min_quantityintEn az adet. Adet girdisinde anlamlı.

max_quantityintEn çok adet.

stepintAdet artış adımı.

multiple_purchasesboolAynı add-on'un birden çok kez alınmasına izin verir.

show_by_product_periodboolFiyatı ürünün dönemine göre gösterir.

override_user_currencyboolMüşterinin para birimini yok sayar.

tax_exemptboolVergiden muaf kılar.

requirement_idsint[]Bağlanacak gereksinim kimlikleri.

product_linkintBağlanacak ürünün kimliği.

icon_typestring`font` ya da `image`.

iconstringİkon sınıfı.

list_templateintListe şablonunun kimliği.

optionsobjectSeçenek anahtarından seçenek nesnesine eşleme. Her seçenek dil başına ad, para birimi başına fiyat, dönem, modül yapılandırması ve gizlilik taşır. Göndermek tüm seti değiştirir.

Dönen alanlar data

dataobjectGüncel add-on. Detay ucuyla aynı şekildedir.

Hatalar 3

not_found404Add-on bulunamadı.

option_in_use422Seçenekler, aktif, onay bekleyen ya da askıya alınmış hizmetlerin kullandığı bir seçeneği dışarıda bırakıyor ya da ödeme dönemini değiştiriyor. Ayrıntıda seçenek kimliği ve neden yer alır: `removed` ya da `cycle`. Hiçbir şey yazılmaz.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X PATCH 'https://panel.ornek.com/api/v1/admin/products/addons/131' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"status":"inactive"}'
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/products/addons/131', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ status: 'inactive' }),
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/products/addons/131');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['status' => 'inactive']),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Tek bir secenegin fiyatini degistirmek icin bile TUM seti gonderin.
$addon   = Api::Products()->GetProductAddon(['id' => 131])['data'];
$options = $addon['langs']['en']['options'];

// ... $options uzerinde degisiklik ...

Api::Products()->UpdateProductAddon([
    'id'      => 131,
    'options' => $options,
]);
```

### Add-on Tanımını Silme

delete/api/v1/admin/products/addons/{id}

`Products/DeleteProductAddon` admin geri alınamaz

Add-on tanımını siler. Dil kayıtları da gider.

Dönen alanlar data — 2

deletedboolSilme başarılı mı.

idintSilinen add-on'un kimliği.

Hatalar 3

not_found404Add-on bulunamadı.

blocked_by_gate422`gate:product.addon_delete` kancası işlemi veto etti.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X DELETE 'https://panel.ornek.com/api/v1/admin/products/addons/131' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/products/addons/131', {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/products/addons/131');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
$response = Api::Products()->DeleteProductAddon(['id' => 131]);
```

### Add-on İkonu Yükleme

post/api/v1/admin/products/addons/{id}/icon

`Products/UploadAddonIcon` admin SVG

Add-on ikonunu yükler. Görsel dosyalar ve SVG kabul edilir.

Gövde 1

imagestringzorunluİkon görseli. base64 veri adresi ya da indirilebilir bir bağlantı.

Dönen alanlar data — 1

urlstringİkonun genel adresi.

Hatalar 5

not_found404Add-on bulunamadı.

file_required422Dosya alanı boş.

file_invalid422Dosya çözümlenemedi ya da tipi kabul edilmedi.

file_failed422Dosya saklanamadı.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X POST 'https://panel.ornek.com/api/v1/admin/products/addons/131/icon' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"image":"data:image/png;base64,iVBORw0KGgo..."}'
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/products/addons/131/icon', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ image: 'data:image/png;base64,iVBORw0KGgo...' }),
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/products/addons/131/icon');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'image' => 'data:image/svg+xml;base64,' . base64_encode($svg),
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
$response = Api::Products()->UploadAddonIcon([
    'id'    => 131,
    'image' => 'data:image/svg+xml;base64,' . base64_encode($svg),
]);
```

### Add-on İkonunu Silme

delete/api/v1/admin/products/addons/{id}/icon

`Products/DeleteProductAddonIcon` admin

Yüklenmiş ikon görselini kaldırır.

Dönen alanlar data — 2

deletedboolSilme başarılı mı.

idintAdd-on kimliği.

Hatalar 2

not_found404Add-on bulunamadı.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X DELETE 'https://panel.ornek.com/api/v1/admin/products/addons/131/icon' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/products/addons/131/icon', {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/products/addons/131/icon');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
$response = Api::Products()->DeleteProductAddonIcon(['id' => 131]);
```

### Kategorileri Listeleme

get/api/v1/admin/products/addon-categories

`Products/GetAddonCategories` admin

Add-on kategorilerini döndürür.

Dönen alanlar data[] — 4

idintKategori kimliği.

titlestringKategori başlığı.

parent_idintÜst kategorinin kimliği. Sıfır üst seviye demektir.

rankintGörüntülenme sırası.

Hatalar 1

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl 'https://panel.ornek.com/api/v1/admin/products/addon-categories' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res  = await fetch('https://panel.ornek.com/api/v1/admin/products/addon-categories', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/products/addon-categories');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
$response = Api::Products()->GetAddonCategories();
```

### Kategori Oluşturma

post/api/v1/admin/products/addon-categories

`Products/CreateAddonCategory` admin 201

Add-on kategorisi açar.

Gövde 3

titlestringzorunluKategori başlığı.

parent_idintÜst kategorinin kimliği.

rankintGörüntülenme sırası.

Dönen alanlar data — 2

idintYeni kategorinin kimliği.

titlestringHTML temizliğinden geçmiş başlık. Yanıtta iki alan döner; üst kategori ile sırayı liste ucundan okuyun.

Hatalar 4

title_required422`title` boş.

blocked_by_gate422`gate:product.category_save` kancası işlemi veto etti.

create_failed422Ekleme başarısız oldu.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X POST 'https://panel.ornek.com/api/v1/admin/products/addon-categories' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"title":"Resources","rank":1}'
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/products/addon-categories', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ title: 'Resources', rank: 1 }),
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/products/addon-categories');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['title' => 'Resources', 'rank' => 1]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
$category = Api::Products()->CreateAddonCategory(['title' => 'Resources']);

Api::Products()->CreateProductAddon([
    'group'    => 'hosting',
    'category' => $category['data']['id'],
    'name'     => ['en' => 'Extra Disk'],
]);
```

### Kategoriyi Güncelleme

patch/api/v1/admin/products/addon-categories/{id}

`Products/UpdateAddonCategory` admin

Kategorinin başlığını, üstünü ya da sırasını değiştirir.

Gövde 3

titlestringKategori başlığı. Gönderirseniz boş olamaz.

parent_idintÜst kategorinin kimliği.

rankintGörüntülenme sırası.

Dönen alanlar data — 4

idintKategori kimliği.

titlestringKategori başlığı.

parentintÜst kategorinin kimliği. Sıfır üst seviye demektir. Liste ucunda bu alanın adı `parent_id`.

rankintGörüntülenme sırası. Kayıtlı satır olduğu gibi döner, yanında birkaç iç sütun da gelir.

Hatalar 4

not_found404Kategori bulunamadı.

title_required422Başlık gönderildi ama boştu.

no_changes422Gövdede düzenlenebilir alan yok.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X PATCH 'https://panel.ornek.com/api/v1/admin/products/addon-categories/12' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"title":"System Resources","rank":2}'
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/products/addon-categories/12', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ title: 'System Resources', rank: 2 }),
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/products/addon-categories/12');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['title' => 'System Resources', 'rank' => 2]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Bos govde 'no_changes' ile doner — degisen alan yoksa hic cagirmayin.
$response = Api::Products()->UpdateAddonCategory([
    'id'    => 12,
    'title' => 'System Resources',
]);
```

### Kategoriyi Silme

delete/api/v1/admin/products/addon-categories/{id}

`Products/DeleteAddonCategory` admin

Add-on kategorisini siler.

Dönen alanlar data — 2

deletedboolSilme başarılı mı.

idintSilinen kategorinin kimliği.

Hatalar 2

not_found404Kategori bulunamadı.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X DELETE 'https://panel.ornek.com/api/v1/admin/products/addon-categories/12' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/products/addon-categories/12', {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/products/addon-categories/12');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
$response = Api::Products()->DeleteAddonCategory(['id' => 12]);
```

## Tuzaklar

> **Seçenekleri göndermek seti baştan yazar**
> 
> Güncelleme gövdesinde `options` varsa mevcut seçeneklerin tamamı **her dilde** silinip yerine gönderdiğiniz set yazılır. Tek bir seçeneğin fiyatını değiştirmek için önce detayı okuyun, seti bütün olarak geri gönderin. Alanı hiç göndermemek seçenekleri korur.

> **Fiyat iki farklı şekilde döner**
> 
> Bir seçenek ya düz bir tutar ve para birimi kimliği taşır, ya da para birimi başına `{enabled, amount}` nesnelerinden oluşan bir eşleme. Hangisinin geleceği kaydın nasıl yazıldığına bağlıdır; okuyan kod ikisini de karşılamalıdır.

> **Seçenekler her dilde ayrı durur**
> 
> Seçenekler dil nesnesinin içinde yaşar, yani her dilde ayrı bir kopyası vardır. Bir dile seçenek ekleyip diğerine eklememek, o dili kullanan müşteride seçeneğin görünmemesine yol açar.

> **Boş güncelleme gövdesi hata döner**
> 
> Kategori güncellemesi düzenlenebilir hiçbir alan taşımayan bir gövdeyi kabul etmez ve `no_changes` döndürür. Değişiklik yoksa isteği hiç göndermemek gerekir.

## İlgili Makaleler

- [Ürün Uçları](https://dev.wisecp.com/tr/urun-uclari)
- [Ürün Gereksinimleri](https://dev.wisecp.com/tr/urun-gereksinimleri)
