# Hesap Durumu ve Toplu İşlem

https://dev.wisecp.com/tr/hesap-durumu-ve-toplu-islem

Hesabı engelleyen, hizmetleri toplu askıya alan ya da iptal eden ve ödenmemiş faturaları hatırlatan altı uç.

## Genel Bakış

Bu uçlar bir hesabın ve o hesaba bağlı hizmetlerin durumunu değiştirir: engelleme, toplu askı, toplu iptal ve ödenmemiş faturaların hatırlatılması.

Engelleme iki biçimde vardır. Tek müşteri için `block` ucu nedeni de saklar; bir liste için `bulk` ucu aynı işi neden tutmadan yapar. Panel toplu hizmet işlemlerini ilerleme çubuğu için tek tek işler, API ise **tek çağrıda** tüm seti işler.

## Referans

### Hesabı Engelleme

put/api/v1/admin/clients/{id}/block

`Clients/SetClientBlock` admin bildirim gider

Hesabı engeller ya da engeli kaldırır. Müşteriye bildirim gönderilir.

Gövde 2

blockedboolzorunlu`true` engeller, `false` engeli kaldırır.

reasonstringEngelleme nedeni. Engeli kaldırırken yok sayılır.

Dönen alanlar data — 1

blockedboolİşlem sonrası engel durumu.

Hatalar 3

not_found404Müşteri bulunamadı.

blocked_by_gate422`gate:user.block` kancası işlemi veto etti.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

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

```bash
curl -X PUT 'https://panel.ornek.com/api/v1/admin/clients/42/block' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"blocked":true,"reason":"Payment dispute"}'
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/clients/42/block', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ blocked: true, reason: 'Payment dispute' }),
});

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

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/clients/42/block');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'blocked' => true,
        'reason'  => 'Payment dispute',
    ]),
]);

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

```php
$response = Api::Clients()->SetClientBlock([
    'id'      => 42,
    'blocked' => true,
    'reason'  => 'Payment dispute',
]);

// Kanca veto ederse istek hata doner, engel uygulanmaz.
if (isset($response['error'])) {
    $code = $response['error']['code'];
}
```

### Toplu İşlem Uygulama

post/api/v1/admin/clients/bulk

`Clients/BulkClientActions` admin çok müşteri

Bir listedeki müşterilere aynı işlemi uygular. Üye olmayan hesaplar atlanır.

Gövde 2

actionstringzorunluUygulanacak işlem. `verify` e-posta ve telefonu doğrulanmış sayar, `reactivate` hesabı aktife çeker, `block` engeller.

idsint[]zorunluMüşteri kimlikleri.

Dönen alanlar data — 2

actionstringUygulanan işlem.

processedint[]Gerçekten işlenen kimlikler. Atlanan yönetici hesapları burada olmaz — gönderdiğiniz listeyle karşılaştırın.

Hatalar 3

action_invalid422İşlem üç değerden biri değil.

ids_required422`ids` boş.

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/clients/bulk' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"action":"verify","ids":[80,81]}'
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/clients/bulk', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ action: 'verify', ids: [80, 81] }),
});

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

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/clients/bulk');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'action' => 'verify',
        'ids'    => [80, 81],
    ]),
]);

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

```php
$sent     = [80, 81, 3];
$response = Api::Clients()->BulkClientActions([
    'action' => 'verify',
    'ids'    => $sent,
]);

// Atlananlari gormek icin listeyi karsilastirin (yonetici hesaplari islenmez).
$skipped = array_diff($sent, $response['data']['processed'] ?? []);
```

Yanıt 200 422

```json
{
  "data": {
    "action": "verify",
    "processed": [80, 81]
  }
}
```

```json
{
  "error": {
    "code": "action_invalid",
    "message": "action must be verify/reactivate/block."
  }
}
```

### Tüm Hizmetleri Askıya Alma

post/api/v1/admin/clients/{id}/services/suspend

`Clients/SuspendClientServices` admin gövde yok

Müşterinin aktif hizmetlerinin tümünü askıya alır. Askı nedeni `Account bulk suspended` olarak yazılır.

Gövde —

——Gövde gerekmez. Müşteri adresteki kimlikten belirlenir; kapsam daraltılamaz, aktif hizmetlerin tümü alınır.

Dönen alanlar data — 3

suspendedintAskıya alınan hizmet sayısı.

idsint[]Askıya alınan hizmet kimlikleri.

failedobject[]Başarısız hizmetler. Her eleman `{id, error}` taşır. Boş dizi hepsinin geçtiği anlamına gelir.

Hatalar 2

not_found404Müşteri bulunamadı.

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/clients/42/services/suspend' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/clients/42/services/suspend', {
  method: 'POST',
  headers: { Authorization: `Bearer ${apiKey}` },
});

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

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/clients/42/services/suspend');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

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

```php
$response = Api::Clients()->SuspendClientServices(['id' => 42]);

// Kismi basari mumkundur: bazi hizmetler gecer, bazilari 'failed' icinde doner.
foreach ($response['data']['failed'] ?? [] as $fail) {
    $serviceId = $fail['id'];
    $reason    = $fail['error'];
}
```

### Toplu Askıyı Kaldırma

post/api/v1/admin/clients/{id}/services/unsuspend

`Clients/UnsuspendClientServices` admin yalnız toplu askılar

Toplu olarak askıya alınan hizmetleri geri açar. Başka bir nedenle askıdaki hizmetlere dokunmaz.

Gövde —

——Gövde gerekmez. Müşteri adresteki kimlikten belirlenir; kapsam sabit kalır: toplu askı nedeniyle hâlâ askıda olan hizmetler. Sonradan iptal edilen hizmete dokunulmaz.

Dönen alanlar data — 3

unsuspendedintGeri açılan hizmet sayısı.

idsint[]Etkilenen hizmet kimlikleri.

failedobject[]Başarısız hizmetler. Her eleman `{id, error}` taşır. Boş dizi hepsinin geçtiği anlamına gelir.

Hatalar 2

not_found404Müşteri bulunamadı.

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/clients/42/services/unsuspend' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/clients/42/services/unsuspend', {
  method: 'POST',
  headers: { Authorization: `Bearer ${apiKey}` },
});

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

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/clients/42/services/unsuspend');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

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

```php
$response = Api::Clients()->UnsuspendClientServices(['id' => 42]);
```

### Tüm Hizmetleri İptal Etme

post/api/v1/admin/clients/{id}/services/cancel

`Clients/CancelClientServices` admin geri alınamaz

Müşterinin iptal edilmemiş ve tamamlanmamış tüm hizmetlerini iptal eder.

Gövde —

——Gövde gerekmez. Müşteri adresteki kimlikten belirlenir; tek tek hizmet seçmeye yarayan bir alan yok.

Dönen alanlar data — 3

cancelledintİptal edilen hizmet sayısı.

idsint[]İptal edilen hizmet kimlikleri.

failedobject[]Başarısız hizmetler. Her eleman `{id, error}` taşır. Boş dizi hepsinin geçtiği anlamına gelir.

Hatalar 3

not_found404Müşteri bulunamadı.

blocked_by_gate422`gate:user.services_bulk_cancel` kancası işlemi veto etti.

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/clients/42/services/cancel' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/clients/42/services/cancel', {
  method: 'POST',
  headers: { Authorization: `Bearer ${apiKey}` },
});

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

```php
$ch = curl_init('https://panel.ornek.com/api/v1/admin/clients/42/services/cancel');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

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

```php
$response = Api::Clients()->CancelClientServices(['id' => 42]);
```

### Ödenmemiş Faturaları Hatırlatma

post/api/v1/admin/clients/{id}/remind-invoices

`Clients/RemindClientInvoices` admin fatura başına bildirim

Müşterinin ödenmemiş her faturası için hatırlatma bildirimi gönderir. Hatırlatması müşteriye ulaşamayan fatura listelenir ve kaydedilmez; durum kodu yine 200 olur.

Gövde —

——Gövde gerekmez. Müşteri adresteki kimlikten belirlenir; ödenmemiş her fatura için bildirim gider, tek fatura seçilemez.

Dönen alanlar data — 3

remindedintHatırlatması müşteri tarafına ulaşan fatura sayısı. Yalnız personele giden kopya sayılmaz.

totalintHatırlatma denenen ödenmemiş fatura sayısı.

not_remindedarray not_reminded[]Hatırlatması müşteriye ulaşmayan faturalar. Hepsi ulaştıysa boştur.

invoice_idintFaturanın numarası.

reasonstring`disabled`, `blocked`, `opted_out`, `client_side_off`, `send_failed` ya da `no_recipients`.

messagestring`reason`'ın İngilizce açıklaması.

Hatalar 3

not_found404Müşteri bulunamadı.

no_unpaid_invoices422Müşterinin ödenmemiş faturası yok. Boş yanıt değil, hata döner.

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/clients/42/remind-invoices' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/admin/clients/42/remind-invoices', {
  method: 'POST',
  headers: { Authorization: `Bearer ${apiKey}` },
});

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

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

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

```php
$response = Api::Clients()->RemindClientInvoices(['id' => 42]);

// Odenmemis fatura yoksa bu bir hatadir, bos sonuc degil.
if (($response['error']['code'] ?? '') === 'no_unpaid_invoices') {
    return;
}
```

## Tuzaklar

> **Kısmi başarı sessizdir**
> 
> Toplu hizmet uçları `200` döndüğü hâlde bazı hizmetler başarısız olmuş olabilir; bunlar `failed` dizisinde `{id, error}` olarak gelir. Yalnız durum koduna bakan bir istemci sorunu göremez.

> **Askıyı kaldırma seçicidir**
> 
> Geri açma ucu yalnız **toplu askı** ile durdurulmuş hizmetleri açar. Ödeme gecikmesi ya da elle askıya alınmış bir hizmet olduğu yerde kalır; bu, tek çağrıyla istemeden yeniden başlatmayı önler.

> **Toplu işlem yönetici hesaplarını atlar**
> 
> Gönderdiğiniz listede üye olmayan bir hesap varsa sessizce atlanır ve `processed` içinde yer almaz. Kaçının işlendiğini bilmek için gönderdiğiniz listeyle dönen listeyi karşılaştırın.

> **Panel şifre ister, API kapsam**
> 
> Toplu iptal panelde yönetici şifresi ister. API'de böyle bir ikinci adım yoktur: anahtarın kapsamı yeterlidir. Bu ucu açtığınız anahtarın kimlerde olduğunu bilerek verin.

## İlgili Makaleler

- [Müşteri Uçları](https://dev.wisecp.com/tr/musteri-uclari)
- [Kara Liste ve Mükerrer Hesap](https://dev.wisecp.com/tr/kara-liste-ve-mukerrer-hesap)
