# PHP SDK

**Paket:** `wisecp/whost-php-sdk` 0.1.1 — bu siteden indirilir
**İndirme:** [`whost-php-sdk.zip`](https://whost.wisecp.com/developer/downloads/whost-php-sdk.zip)
· SHA-256: [`whost-php-sdk.zip.sha256`](https://whost.wisecp.com/developer/downloads/whost-php-sdk.zip.sha256)
**Gereksinim:** `curl` ve `json` eklentileriyle PHP 7.4 veya üstü

SDK, WHost yönetici API'si için bir PHP istemcisidir. Tek bir faturalama
sistemine bağlı değildir: WISECP, WHMCS, Blesta ve kendi kodunuz aynı paketi
kullanır. Her isteği imzalar, her yazma çağrısında idempotency anahtarı
sunar, istenirse yeniden dener, hata yanıtlarını tipli istisnalara çevirir
ve gelen webhook'ları doğrular.

Paket Packagist'te ya da GitHub'da yayımlı değildir; edinmenin yolu bu
sitedeki arşivdir.

---

## İndirme ve kurulum

```bash
curl -O https://whost.wisecp.com/developer/downloads/whost-php-sdk.zip
curl -O https://whost.wisecp.com/developer/downloads/whost-php-sdk.zip.sha256
sha256sum -c whost-php-sdk.zip.sha256
unzip whost-php-sdk.zip
```

Arşivde tek bir klasör vardır, `whost-php-sdk/`: SDK (`src/`), dört örnek,
README, CHANGELOG, LICENSE ve SDK'nın bağımlılıklarını taşıyan bir `vendor/`
klasörü (Guzzle 7 ve PSR HTTP arayüzleri; PHP 7.4 ve üstünde çalışacak
sürümler seçilmiştir).

**Lisans.** LICENSE, SDK'yı örnekleri dahil kullanmanıza, kopyalamanıza,
değiştirmenize ve WHost'a bağlanan kendi entegrasyonunuzun parçası olarak
(ör. bir fatura sistemi modülü) dağıtmanıza izin verir; SDK tek başına
dağıtılamaz. Her kopyada LICENSE dosyası ve telif notları kalır; bunun
dışındaki her kullanım WISECP LLC'nin yazılı iznini gerektirir.

**Composer olmadan** — paketle gelen autoloader'ı yükleyin:

```php
require __DIR__ . '/whost-php-sdk/vendor/autoload.php';
```

**Composer ile** — projenizin zaten kendi `vendor/` klasörü varsa paketle
gelen `whost-php-sdk/vendor/` klasörünü silin, açtığınız klasörü bir path
deposu olarak gösterin ve paketi isteyin; bağımlılıkları Composer kendisi
kurar:

```json
{
  "repositories": [
    { "type": "path", "url": "./whost-php-sdk", "options": { "symlink": false } }
  ],
  "require": {
    "wisecp/whost-php-sdk": "^0.1"
  }
}
```

Ardından `composer update wisecp/whost-php-sdk` çalıştırın. Path deposu
olmadan `composer require wisecp/whost-php-sdk` paketi bulamaz.

---

## API anahtarı

WHost yönetici panelinde **Ayarlar → API Erişimi** altında bir anahtar
oluşturun ve entegrasyonunuzun istek göndereceği adreslerle sınırlayın.
Gizli değer yalnız bir kez, anahtar oluşturulurken gösterilir; kodun
dışında saklayın (ortam değişkeni ya da bir sır deposu).

Orada oluşturulan anahtar sunucu genelinde geçerlidir ve SDK'nın çağırdığı
yönetici API'sine erişir. Bir bayinin ya da müşterinin müşteri panelinde
oluşturduğu anahtar o hesaba bağlıdır ve yalnız müşteri API'sine
(`/api/v1/client/...`) erişir; SDK'nın kaynakları böyle bir anahtara
`403 SCOPE_DENIED` döner.

---

## Hızlı başlangıç

```php
<?php
require __DIR__ . '/whost-php-sdk/vendor/autoload.php';

use WHost\WHostClient;
use WHost\Exceptions\WHostException;

$whost = new WHostClient(
    (string) getenv('WHOST_API_KEY'),
    (string) getenv('WHOST_API_SECRET'),
    'https://panel.example.com',   // WHost panelini açtığınız adres
    ['timeout' => 30.0]
);

try {
    $page = $whost->accounts->list(['limit' => 25]);
    foreach ($page['accounts'] as $account) {
        echo $account['username'], "\t", $account['domain'], PHP_EOL;
    }

    $account = $whost->accounts->create([
        'username' => 'demo01',
        'domain'   => 'demo01.example.com',
        'email'    => 'owner@example.com',
        'password' => $password,   // TLS üzerinden düz metin; ajan kendisi hash'ler
        'plan_id'  => $planId,     // $whost->plans->list() içindeki bir planın "id"si
    ], 'order-12345');             // idempotency anahtarı, aşağıya bakın

    echo 'Oluşturuldu: ', $account['username'], PHP_EOL;
} catch (WHostException $e) {
    fwrite(STDERR, sprintf(
        "[%d %s] %s\n",
        $e->getHttpStatus(),
        $e->getErrorCode(),
        $e->getMessage()
    ));
    exit(1);
}
```

- **Taban adres:** panelin adresidir; istemci `/api/v1`'i kendisi ekler.
  WHost ajanı yalnız sunucunun loopback arayüzünde dinler, istekler ona
  panelin web sunucusu üzerinden ulaşır.
- **TLS:** sertifika doğrulaması varsayılan olarak açıktır (`verify_ssl`);
  yalnız kendinden imzalı sertifikalı bir test sunucusunda kapatın.
- **Yanıtlar:** her metot ajan yanıtının `data` alanını dizi olarak döndürür.

---

## SDK neyi kapsar

Yönetici API'sinin her alanı için bir erişimci, toplam 38: hesaplar, alan
adları, DNS, SSL, e-posta, veritabanları, FTP, dosyalar, cron, yedekler,
PHP, planlar, Python ve Node.js uygulamaları, güvenlik duvarı, Fail2Ban,
WAF, spam filtresi, posta kuyruğu ve gönderilen postalar, günlükler,
metrikler, sistem ve servisler, güncellemeler, lisans, taşıma, eklentiler,
bayi yetkileri ve beyaz etiket. Her erişimcinin metot listesi arşivdeki
`src/Resources/` altındadır; IDE otomatik tamamlamayı oradan yapar.

**Bunlara API anahtarı değil, yalnız oturum açmış panel erişir:** API
anahtarı yönetimi (`apiKeys`), yöneticinin kendi profili (`profile`),
yöneticinin bildirim merkezi (`notifications`), panel giriş çağrıları
(`auth`) ve beyaz etiket ayarları. API anahtarıyla `401 AUTH_FAILED`
dönerler. Bir hesabın parolasını (`accounts->changePassword()`) ya da
sunucunun root parolasını değiştirmek de API anahtarına kapalıdır
(`403 HMAC_FORBIDDEN_FOR_CREDENTIAL_MUTATION`); parolayı hesap sahibi
panelden değiştirir.

**Henüz yardımcı metodu olmayanlar:** webhook uç noktası yönetimi
(`/api/v1/system/webhooks/...`), müşteri API'si (`/api/v1/client/...`) ve
bazı yeni yönetici uçları. Bunları `/api/v1`'den sonraki yolla alt düzey
istemci üzerinden çağırın:

```php
$events = $whost->http()->request('GET', '/system/webhooks/events');
// request(string $method, string $path, ?array $body = null,
//         array $query = [], ?string $idempotencyKey = null)
```

Tüm uçlar [uç kataloğunda](api-summary.md) listelenir.

---

## Idempotency

Yazma metotları son argüman olarak isteğe bağlı bir idempotency anahtarı
alır: `create($data, $key)` için ikinci, bir veri dizisi de alan metotlarda
üçüncü argümandır; örneğin `suspend($username, $data, $key)`. Anahtar
harf, rakam, `-` ve `_`'den oluşan 8–64 karakterdir; her iş olayı için bir
anahtar kullanın, örneğin 12345 numaralı siparişin kurulumu için
`order-12345`.

Ajan yanıtı o anahtar altında 24 saat saklar:

| İstek | Yanıt |
|-------|-------|
| Aynı anahtar, aynı metot, yol ve gövde | Saklanan yanıt, `X-Idempotent-Replay: true` başlığıyla; işlem yeniden çalışmaz. Bir kez gösterilen gizli değer (API anahtarı ya da webhook sırrı, 2FA bilgisi, tek kullanımlık giriş bağlantısı, OAuth belirteci) `"***"` olarak döner |
| Aynı anahtar, farklı metot, yol ya da gövde | `409 IDEMPOTENCY_KEY_REUSED` |
| Aynı anahtar başka bir API anahtarından | Yeni istek; yanıtlar API anahtarı başına saklanır |
| Biçimi bozuk anahtar | `400 IDEMPOTENCY_KEY_INVALID` |
| Önceki deneme sunucu hatasıyla (5xx) bitti | Saklanmaz — yeniden deneme işlemi çalıştırır |

---

## Yeniden deneme

```php
$whost = $whost->withRetry(3);
```

bir isteği `429`, `5xx` ve bağlantı hatalarında 1 sn, 2 sn ve 5 sn
bekleyerek en çok üç kez daha dener. Yeniden denediğiniz her yazma
çağrısında idempotency anahtarı gönderin.

---

## Hatalar

| Sınıf | Ne zaman |
|-------|----------|
| `AuthException` | HTTP 401 ya da 403, veya `AUTH_` ile başlayan bir `error_code` |
| `NotFoundException` | HTTP 404 |
| `RateLimitException` | HTTP 429 ya da `RATE_LIMIT_EXCEEDED`; ajan bekleme süresi gönderdiyse `getRetryAfter()` saniye olarak verir |
| `ValidationException` | HTTP 400 ya da 422, veya `VALIDATION_ERROR`; `getFieldErrors()` alanları listeler |
| `WHostException` | Geri kalan her şey: diğer 4xx ve 5xx yanıtları ve bağlantı hataları (`TRANSPORT_ERROR`) |

Hepsi `WHost\Exceptions\WHostException` alt sınıfıdır ve
`getHttpStatus()`, `getErrorCode()`, `getDetails()` ile `getRawBody()`
taşır. Her hata kodunun anlamı [hata kodu kataloğundadır](api-reference.md#ek-a-hata-kodlar).

---

## İstek imzalama

SDK her isteği HMAC-SHA256 ile imzalar ve `X-WHost-Key`,
`X-WHost-Timestamp`, `X-WHost-Nonce` ile `X-WHost-Signature` başlıklarını
gönderir. İmzalanan metin

```
METHOD\nPATH\nTIMESTAMP\nNONCE\nBODY
```

biçimindedir; `PATH`, `/api/v1` ve sorgu dizesi dahil tam istek yoludur.
Ajan kendi saatinden 300 saniyeden fazla sapan zaman damgasını reddeder;
isteği gönderen sunucunun saatini eşitli tutun (NTP).

---

## Webhook doğrulama

```php
use WHost\Http\WebhookVerifier;
use WHost\Exceptions\WHostException;

try {
    $event = WebhookVerifier::parse(
        file_get_contents('php://input'),
        $_SERVER['HTTP_X_WHOST_WEBHOOK_SIGNATURE'] ?? '',
        $_SERVER['HTTP_X_WHOST_WEBHOOK_TIMESTAMP'] ?? '',
        $endpointSecret
    );
} catch (WHostException $e) {
    http_response_code(401);   // WEBHOOK_SIGNATURE_INVALID, WEBHOOK_TIMESTAMP_OUT_OF_RANGE, ...
    exit;
}

switch ($event['event']) {
    case 'account.created':   /* ... */ break;
    case 'account.suspended': /* ... */ break;
    case 'ssl.failed':        /* ... */ break;
}
```

Doğrulayıcı `X-WHost-Webhook-Signature` değerini (`"{zaman damgası}.{ham
gövde}"` üzerinden `sha256=<hex>`) ham istek gövdesine karşı denetler ve
300 saniyeden eski teslimi reddeder. Ajan bir teslim için en çok beş deneme
yapar ve 2xx dışındaki her yanıtta yeniden dener; tekrarları
`X-WHost-Webhook-Event-Id` ile ayıklayın. Olaylar ve yük yapısı:
[Webhook'lar](webhooks.md).

---

## Arşivdeki örnekler

| Dosya | Gösterdiği |
|-------|------------|
| `examples/01-quickstart.php` | Hesapları listeleme, bir hesap açma, geri okuma |
| `examples/02-account-lifecycle.php` | Açma → askıya alma → askıyı kaldırma → silme |
| `examples/03-billing-integration-pattern.php` | Bir faturalama sisteminin sipariş kancaları: etkinleştirme, askıya alma, sürdürme, sonlandırma, plan değişikliği |
| `examples/04-webhook-receiver.php` | İmza denetimi ve tekrar filtresi olan bir webhook uç noktası |

Örnekleri açtığınız klasörden `WHOST_API_KEY`, `WHOST_API_SECRET` ve
`WHOST_BASE_URL` tanımlıyken çalıştırın. Gösterdikleri sunucuda hesap
açarlar; bir test sunucusu kullanın.

---

## Neden WHMCS, Blesta ya da WISECP modülü yok?

SDK bilerek faturalama bağımsızdır: faturalama sistemine bağlayan kod
faturalama tarafında yaşar. `examples/03-billing-integration-pattern.php`
böyle bir modülün ihtiyaç duyduğu kancaları gösterir. Bu SDK'yı kullanan
bir modülün bakımını yapıyorsanız `hello@wisecp.com` adresinden bize
bildirin.

---

## Sürümler ve durum

SDK'nın WHost sürümünden bağımsız kendi sürüm numarası vardır. `0.x`
olduğu sürece bir ara sürüm davranış değiştirebilir; ne değiştiğini
arşivdeki `CHANGELOG.md` söyler. SDK, WHost betasının parçasıdır; sorunları
wisecp.com müşteri panelinizden bir destek talebiyle (açamadığınızda
`hello@wisecp.com` adresine) bildirin.
