> ## Documentation Index
> Fetch the complete documentation index at: https://docs.payven.com.tr/llms.txt
> Use this file to discover all available pages before exploring further.

# Kimlik Doğrulama

> Sanal POS API'sine Bearer access token ile erişim.

Sanal POS API'si Payven'in standart OAuth 2.0 Client Credentials akışını kullanır. Identity'den alınan access token, Sanal POS endpoint'lerine `Authorization: Bearer <access_token>` header'ı ile gönderilir.

<Note>
  **Genel akış, kod örnekleri ve token süreleri** için kanonik [Kimlik Doğrulama](/documentation/concepts/authentication) sayfasına bakın. Bu sayfa Sanal POS'a özgü endpoint URL'lerini ve örneklerini içerir.
</Note>

## Endpoint URL'leri

| Ortam          | Identity (token alma)                    | Sanal POS API                        |
| -------------- | ---------------------------------------- | ------------------------------------ |
| **Production** | `https://identity.payven.com.tr`         | `https://vpos.payven.com.tr`         |
| **Sandbox**    | `https://identity-sandbox.payven.com.tr` | `https://vpos-sandbox.payven.com.tr` |

## Realm seçimi

Payven Identity multi-tenant — token endpoint URL'sinde **realm slug'ı** kullanılır: `POST /api/v1/auth/{slug}/token`. Slug'ınız onboarding sırasında size atanır:

| Slug                 | Kullanım                                     |
| -------------------- | -------------------------------------------- |
| `payven`             | Master realm — Payven platform admin'leri    |
| `tenant-{your-slug}` | Sizin tenant realm'iniz (örn. `tenant-acme`) |

Slug'ınızı **Konsol → Ayarlar → API Erişimi** sekmesinde görebilirsiniz. Token'ın `iss` claim'i realm'e işaret eder; SanalPos backend tüm kabul edilen realm'leri otomatik doğrular — composer'a tek tek tanıtım gerekmez.

## Hızlı başlangıç

Önce [Identity'den access token alın](/documentation/concepts/authentication) — `$PAYVEN_TOKEN` ortam değişkenine yazıp Sanal POS endpoint'lerine gönderin:

```bash theme={null}
curl https://vpos.payven.com.tr/api/v1/payments \
  -H "Authorization: Bearer $PAYVEN_TOKEN" \
  -H "Idempotency-Key: order-1001-payment" \
  -H "Content-Type: application/json" \
  -d @payment.json
```

Tam ödeme isteği örneği için: [Hızlı Başlangıç](/documentation/quickstart#2-i̇lk-odemeyi-gerceklestirin).

## Merchant kimliği

Access token içinde merchant kimliği claim olarak taşınır — tek-merchant tenant'larda ek bir header göndermenize gerek yoktur. Backend bu claim'den okuyup işlemi doğru merchant adına kayıt eder.

**Multi-merchant senaryolar** (bir tenant altında birden çok merchant'a işlem alıyorsanız) için override header'ları:

```http theme={null}
X-Merchant-Id:          3fa85f64-5717-4562-b3fc-2c963f66afa6
```

Veya kendi sisteminizdeki kimlik ile:

```http theme={null}
X-External-Merchant-Id: M-IST-001
```

Her ikisi gönderilirse `X-Merchant-Id` öncelikli olur.

| Header                   | Tip    | Anlam                           | Kaynak                                                  |
| ------------------------ | ------ | ------------------------------- | ------------------------------------------------------- |
| `X-Merchant-Id`          | UUID   | Payven'in atadığı dahili kimlik | Konsoldan kopyalanır (Merchant.id)                      |
| `X-External-Merchant-Id` | string | Sizin sisteminizdeki kimlik     | Onboarding sırasında belirlenir (Merchant.external\_id) |

## Response header'ları

Her response'da Payven aşağıdakileri ekler:

```http theme={null}
X-Correlation-Id:       9f1c8e76-2a3b-4f12-9c8d-12cb24a8a8a8
X-RateLimit-Limit:      200
X-RateLimit-Remaining:  187
X-RateLimit-Reset:      1746450896
```

| Header                | Açıklama                                                                    |
| --------------------- | --------------------------------------------------------------------------- |
| `X-Correlation-Id`    | Bu isteğin Payven log zincirindeki kimliği. Destek talebi açarken paylaşın. |
| `X-RateLimit-*`       | Mevcut kota. [Detay](/documentation/concepts/rate-limiting).                |
| `Retry-After`         | Yalnız `429` yanıtında — kaç saniye sonra tekrar denemeniz gerektiği.       |
| `Idempotent-Replayed` | Yalnız idempotent replay'lerde — yanıt cache'den geldiyse `true`.           |

## Hata response'ları (kimlik doğrulama)

| HTTP  | `code`                 | Anlam                                     | Çözüm                         |
| ----- | ---------------------- | ----------------------------------------- | ----------------------------- |
| `401` | `invalid_token`        | `Authorization` header'ı eksik / geçersiz | Token alın veya refresh edin  |
| `401` | `token_expired`        | Access token süresi doldu                 | Refresh akışı                 |
| `403` | `merchant_inactive`    | Merchant pasif statüde                    | Konsol → Merchants            |
| `403` | `merchant_not_found`   | Belirtilen merchant bulunamadı            | Header'ı doğrulayın           |
| `403` | `product_not_licensed` | Sanal POS modülü planınızda etkin değil   | Plan yükseltme                |
| `429` | `rate_limit_exceeded`  | Limit aşıldı                              | `Retry-After` header'ına uyun |

Tam hata kataloğu için: [Hata Yönetimi](/documentation/concepts/errors).

## Güvenlik kuralları

<Check>**Token cache** — Her API çağrısında token alıp Identity'yi yormayın. Bellek-içi cache + 60sn margin ile auto-refresh kullanın.</Check>
<Check>**Sadece sunucu tarafı** — `client_secret`'ı frontend, mobil veya public repo'ya **asla** koymayın.</Check>
<Check>**HTTPS zorunlu** — HTTP istekleri reddedilir.</Check>
<Check>**Production = ayrı client** — Production ve sandbox için ayrı `client_id`/`client_secret` kullanın.</Check>
<Check>**Loglarda maskele** — `access_token`, `refresh_token`, `client_secret` değerlerini log'lara yazmayın.</Check>
