# İndirim kodları

Bir sepet en fazla bir indirim kodu taşır. Kod olduğu gibi saklanır ve her sepet okumasında tembel (lazy) olarak değerlendirilir: kullanılamayan bir kod eklemek request'i başarısız kılmaz. Bunun yerine her sepet response'u sonucu iki alan üzerinden bildirir:

- `discount_code_error`: Kod uygulanabildiğinde (veya kod ayarlanmadığında) null, aksi halde aşağıdaki değerlerden biri.
- `discounts[]`: Sepete şu anda uygulanan indirimlerin listesi; her biri `{id, name, code, kind, amount}` şeklindedir, `kind` şunlardan biridir: `order`, `products`, `shipping`, `bogo` ve `amount` minör birim cinsinden bir tamsayıdır. Otomatik (kodsuz) indirimler de burada görünür.

| `discount_code_error` | Anlamı |
| --- | --- |
| `invalid` | Bu koda sahip bir indirim yok (veya pasif). |
| `expired` | İndirimin geçerlilik penceresi geçmiş veya henüz başlamamış. |
| `min_order` | Sepet toplamı, indirimin minimum sipariş tutarının altında. |
| `not_eligible` | Sepet veya müşteri, indirimin koşullarıyla eşleşmiyor. |
| `usage_limit` | İndirimin kullanım limiti tükenmiş. |

Değerlendirme tembel olduğu için, bugün geçerli olan bir kod daha sonra `expired` veya `usage_limit` haline gelebilir; güncel durumu almak için sepeti yeniden okuyun. Kullanım limitleri ayrıca checkout sırasında bir kilit altında yeniden kontrol edilir: ekleme ile checkout arasında tükenen bir kod, `discount_unavailable` girdisi içeren bir 409 sepet çakışmasına yol açar (Checkout sayfasına bakın).

Her iki endpoint de `commerce:write` ve `active` bir sepet gerektirir ve sepet sahipliği kontrolünden geçer. İkisi de `GET /v1/api/commerce/carts/{id}` ile aynı şekle sahip tam sepet zarfını döndürür.

## PUT /v1/api/commerce/carts/{id}/discount-code

Sepete bir indirim kodu ekler ve önceden eklenmiş kodu değiştirir. Request, biçimsel olarak geçerli her kod için başarılı olur; uygulanıp uygulanmadığını görmek için response'taki `discount_code_error` ve `discounts[]` alanlarını kontrol edin.

### Parametreler

**Path**

| Ad | Tür | Zorunlu | Açıklama |
| --- | --- | --- | --- |
| `id` | string (UUID) | evet | Sepet id'si. `active` bir sepet olmalıdır. |

**Body**

| Ad | Tür | Zorunlu | Açıklama |
| --- | --- | --- | --- |
| `code` | string | evet | En fazla 100 karakter, baştaki ve sondaki boşluklar kırpıldıktan sonra boş olmamalıdır. |

```bash title="Request"
curl -X PUT https://api.borkol.com/v1/api/commerce/carts/9d3f2a10-6b7c-4e6d-9f21-8a54c1d2e3f4/discount-code \
  -H "Authorization: Bearer {api_key}" \
  -H "Content-Type: application/json" \
  -d '{"code": "WELCOME10"}'
```

```javascript title="Request (JS)"
const res = await fetch(
  `https://api.borkol.com/v1/api/commerce/carts/${cartId}/discount-code`,
  {
    method: "PUT",
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ code: "WELCOME10" }),
  }
);
const { data: cart } = await res.json();
if (cart.discount_code_error) {
  // show why the code did not apply: invalid | expired | min_order | not_eligible | usage_limit
}
```

```json title="Response"
{
  "data": {
    "id": "9d3f2a10-6b7c-4e6d-9f21-8a54c1d2e3f4",
    "discount_code": "WELCOME10",
    "discount_code_error": null,
    "discounts": [
      {
        "id": "71c9e0aa-2f4b-4d31-9a77-0b1c2d3e4f5a",
        "name": "Welcome 10%",
        "code": "WELCOME10",
        "kind": "order",
        "amount": 450
      }
    ],
    "...": "same cart shape as GET /v1/api/commerce/carts/{id}"
  }
}
```

Kod uygulanamadığında response yine 200'dür; örneğin `"discount_code": "SUMMER24", "discount_code_error": "expired", "discounts": []` ile döner.

### Hatalar

| Durum | Gövde | Ne zaman |
| --- | --- | --- |
| 422 | `{"message": "...", "errors": {"code": ["..."]}}` | Kod eksik, kırpma sonrası boş veya 100 karakterden uzun. |
| 404 | `{"message": "..."}` | Sepet bilinmiyor, süresi dolmuş veya `active` değil. |
| 403 | sahiplik, scope, modül veya askıya alma gövdesi | Sepetler sayfasına bakın. |
| 429 | `{"message": "Too Many Attempts."}` | Rate limit aşıldı. |

## DELETE /v1/api/commerce/carts/{id}/discount-code

Sepetten indirim kodunu kaldırır. Otomatik (kodsuz) indirimler etkilenmez ve `discounts[]` içinde görünmeye devam edebilir.

### Parametreler

**Path**

| Ad | Tür | Zorunlu | Açıklama |
| --- | --- | --- | --- |
| `id` | string (UUID) | evet | Sepet id'si. `active` bir sepet olmalıdır. |

Body yok.

```bash title="Request"
curl -X DELETE https://api.borkol.com/v1/api/commerce/carts/9d3f2a10-6b7c-4e6d-9f21-8a54c1d2e3f4/discount-code \
  -H "Authorization: Bearer {api_key}"
```

```json title="Response"
{
  "data": {
    "id": "9d3f2a10-6b7c-4e6d-9f21-8a54c1d2e3f4",
    "discount_code": null,
    "discount_code_error": null,
    "...": "same cart shape as GET /v1/api/commerce/carts/{id}"
  }
}
```

### Hatalar

| Durum | Gövde | Ne zaman |
| --- | --- | --- |
| 404 | `{"message": "..."}` | Sepet bilinmiyor, süresi dolmuş veya `active` değil. |
| 403 | sahiplik, scope, modül veya askıya alma gövdesi | Sepetler sayfasına bakın. |
| 429 | `{"message": "Too Many Attempts."}` | Rate limit aşıldı. |
