
# Alt Hesap Otomatik Yükleme (Özel Ödeme Sağlayıcısı)

Alt hesap kredi ödemelerini Stripe yerine kendi sağlayıcınız (banka havaleleri, yerel ödeme ağ geçitleri, özel faturalandırma sistemleri) aracılığıyla yönetmeyi tercih ederseniz, platform tam şarj etme ve tanımlama döngüsünü kendiniz yürütmeniz için bir webhook + API çifti sunar. Teknik olmayan genel bakış [Ajans Hesapları](agency-accounts.md#option-2-custom-payment-provider) sayfasında yer almaktadır; bu sayfa, tam webhook yükünü ve sonrasında kredi tanımlamak için yapacağınız API çağrısını kapsar.

Webhook, otomatik yüklemelerin ödenmesini sağlayan yollardan yalnızca biridir. SaaS Modunda [Stripe](agency-accounts.md#option-1-connect-stripe) veya [PayPal](agency-accounts.md#option-3-connect-paypal) bağladıysanız, platform müşterinin kayıtlı kartından veya PayPal hesabından otomatik olarak ödeme alır ve kredileri tanımlar; bu nedenle bu sayfada sizin oluşturmanız gereken bir şey yoktur. Ödemeyi kendiniz yönetmek istiyorsanız okumaya devam edin.

***

## Akışa genel bakış

1. Bir alt hesabın kredi bakiyesi, otomatik yükleme eşiğinin altına düşer.
2. Platform, alt hesap detayları ve ihtiyaç duydukları kredi miktarı ile **webhook URL**'nizi çağırır.
3. Sunucunuz, kullandığınız sağlayıcı aracılığıyla müşteriden ödeme alır.
4. Sunucunuz, o alt hesaba kredi eklemek için **Kredi Tanımlama API**'sini çağırır.
5. Sunucunuz, webhook'u onaylamak için `200` yanıtını verir.

***

## 1. Webhook: `agency_sub_account_auto_recharge`

Ana kenar çubuğunda **SaaS Modu**'na tıklayarak, **Bunun Yerine Özel Bir Ödeme Sağlayıcısı Kullan**'ı seçerek (veya yapılandırıldıktan sonra **Özel Ödeme Sağlayıcısı** kartını açarak) ve **Otomatik Yükleme Webhook'u** alanını doldurarak webhook URL'sini yapılandırın.

### Ne zaman tetiklenir

Bir alt hesabın kredi bakiyesi, yapılandırılmış otomatik yükleme eşiğinin altına düştüğünde tetiklenir.

### Yük (Payload)

```json
{
  "event": "agency_sub_account_auto_recharge",
  "sub_account_id": "<sub-account-id>",
  "sub_account_email": "customer@example.com",
  "sub_account_name": "John Doe",
  "agency_id": "<agency-id>",
  "credits_requested": 500,
  "current_balance": 42,
  "threshold": 100,
  "price_per_credit_cents": 10,
  "price_per_credit_currency": "usd",
  "total_amount_cents": 5000,
  "timestamp": "2026-04-13T12:00:00.000Z",
  "idempotency_key": "auto_recharge_abc123_1681387200000"
}
```

| Alan | Açıklama |
|---|---|
| `event` | Bu webhook için her zaman `agency_sub_account_auto_recharge` değerindedir. |
| `sub_account_id` | Krediye ihtiyaç duyan alt hesabın benzersiz kimliği. |
| `sub_account_email` | Alt hesabın e-posta adresi. |
| `sub_account_name` | Alt hesabın görünen adı. |
| `agency_id` | Ajans hesabınızın benzersiz kimliği. |
| `credits_requested` | Tanımlanacak kredi miktarı. Bu, yapılandırdığınız yükleme miktarıdır, ancak bakiye eşiğin altına bu miktarın karşılayabileceğinden daha fazla düşerse, bakiyeyi tek seferde eşiğin üzerine çıkarmak için gereken miktara otomatik olarak yükseltilir. Her zaman yükteki `credits_requested` değeri için ücret alın (ve tanımlayın) — yükleme miktarınızı sabit kodlamayın. |
| `current_balance` | Webhook gönderildiği sırada alt hesabın kredi bakiyesi. |
| `threshold` | Yüklemeyi tetikleyen bakiye eşiği. |
| `price_per_credit_cents` | Yapılandırdığınız kredi başına fiyat (sent cinsinden). |
| `price_per_credit_currency` | Fiyatın para birimi (örneğin, `usd`). |
| `total_amount_cents` | Tahsil edilecek toplam tutar (sent cinsinden) (`credits_requested` × `price_per_credit_cents`). |
| `timestamp` | Webhook'un gönderildiği zaman (ISO 8601 formatı). |
| `idempotency_key` | Bu özel yükleme isteği için benzersiz bir anahtar. Sunucunuz aynı webhook'u birden fazla kez alırsa kredilerin iki kez tanımlanmasını önlemek için bunu kullanın. |

### Önemli notlar

- **5 dakikalık bekleme süresi** — Bir alt hesap için yükleme denemesinden sonra, platform, bakiyeleri daha da düşse bile en az 5 dakika boyunca o alt hesap için başka bir webhook göndermeyecektir. İşlem sırasında mükerrer ücretlendirmeleri önler.
- **Tekilleştirme (idempotency) anahtarını kullanın** — Kredi tanımlamadan önce her zaman `idempotency_key` değerini kontrol edin. Sunucunuz kredi tanımladıktan sonra ancak yanıt vermeden önce çökerse, platform bir sonraki kredi düşüşünde webhook'u yeniden gönderebilir.
- **Hatalar güvenlidir ve kendi kendini onarır** — Webhook URL'nize ulaşılamazsa veya bir hata döndürürse, hiçbir kredi tanımlanmaz. Platform, alt hesap eşiğin altında kaldığı sürece webhook'u yeniden göndermeye devam eder (5 dakikalık bekleme süresinde bir kez) — bakiyenin tekrar eşiğin üzerine çıkıp tekrar düşmesini **gerektirmez**. Kaçırılan tek bir ücretlendirme, bir alt hesabın kalıcı olarak yüklemesiz kalmasına neden olmaz.
- **Yükleme miktarınızı eşiğe eşit veya üzerinde ayarlayın** — Yapılandırdığınız yükleme miktarı, otomatik yükleme eşiğine eşit veya ondan büyük olmalıdır, böylece tek bir yükleme her zaman bakiyeyi eşiğin üzerine çıkarır. (Eşiğin çok altına düşen bir alt hesabı düzeltmeniz gerekirse, platform aradaki farkı otomatik olarak tamamlar — yukarıdaki `credits_requested` kısmına bakın.)

***

## 2. Kredi Tanımlama API'si

Sunucunuz ödemeyi işledikten sonra, alt hesaba kredi eklemek için bu uç noktayı çağırın.

### İstek

```http
POST https://api.dmchamp.com/v1/subaccounts/credits
X-API-Key: YOUR_API_KEY
Content-Type: application/json

{
  "email": "customer@example.com",
  "amount": 500,
  "description": "Auto-recharge via webhook"
}
```

| Alan | Zorunlu | Açıklama |
|---|---|---|
| `email` | Evet | Alt hesabın e-posta adresi (ajansınız altındaki mevcut bir alt hesapla eşleşmelidir). |
| `amount` | Evet | Tanımlanacak kredi miktarı. |
| `description` | Hayır | Kredilerin neden eklendiğini açıklayan bir not (kredi işlem geçmişinde gösterilir). |

**Kimlik Doğrulama:** API anahtarınızı bir istek başlığında gönderin — `X-API-Key: YOUR_API_KEY` veya `Authorization: Bearer YOUR_API_KEY`. Başlıklar önerilen yöntemdir, çünkü URL içindeki bir anahtar tarayıcı geçmişinde, proxy günlüklerinde ve sunucu erişim günlüklerinde kalır. `?apiKey=YOUR_API_KEY` sorgu parametresi ve JSON gövdesindeki bir `apiKey` alanı da hala çalışmaktadır, bu sayede eski entegrasyonlar değişmeden çalışmaya devam eder.

### Yanıt

```json
{
  "success": true,
  "sub_account_id": "abc123xyz",
  "credits_added": 500,
  "new_balance": 542
}
```

::: tip
**İpucu:** Webhook yükünden `idempotency_key` değerini saklayın ve bu uç noktayı çağırmadan önce kontrol edin. Bu, sunucunuzun aynı webhook'u birden fazla kez alması durumunda yanlışlıkla iki kez kredi verilmesini önler.
:::


### Aylık sıfırlamada verilen kredilere ne olur

Bu, alt hesabın nasıl yapılandırıldığına bağlıdır:

- **Yeniden Satış** (alt hesap krediler için size ödeme yapar): burada verdiğiniz krediler satın alınmış krediler olarak kaydedilir ve her ay **devreder**. Alt hesabın harcamadığı her şey bakiyede kalır.
- **Tahsis** (alt hesaba aylık ödenek verirsiniz): bakiye, sıfırlama tarihinde aylık ödenek miktarına tamamlanır, bu nedenle harcanmayan tutarlar devretmez. Bu kasıtlıdır; ödenek her ay yeniden verilir.

Bir alt hesabın kalan bakiyesinin, yeni aylık ödeneğinin yerine geçmek yerine üzerine eklenmesini istiyorsanız, kredi devretme özelliğini açın:

```
PUT https://api.dmchamp.com/v1/subaccounts/{subAccountUid}/limits
X-API-Key: YOUR_API_KEY
Content-Type: application/json

{
  "usageLimits": { "roll_over_to_next_month": true }
}
```

Alt hesabın veya dahil olduğu planın bir devretme sınırı veya son kullanma tarihi ayarlanmışsa, sıfırlama işlemi bunların uygulandığı anda gerçekleşir: devredilen hak, izin verdiğiniz ay sayısına göre kırpılır ve son kullanma süresinden daha uzun süre kullanılmayan haklar, yeni haklar eklenmeden önce silinir. Bu uç nokta aracılığıyla verilen krediler, otomatik yüklemeler ve müşterinin kendi yaptığı yüklemeler tek seferlik kredilerdir ve hiçbir zaman kırpılmazlar. Bkz. [Devredilenleri sınırlama](sub-accounts.md#capping-what-rolls-over).

***

## Uçtan uca örnek

Tipik bir işleyici şu şekilde görünür:

```pseudo
on POST /your-recharge-webhook:
  payload = request.body

  if seen(payload.idempotency_key):
    return 200  // already processed, ack and exit

  charge_result = your_payment_provider.charge(
    email = payload.sub_account_email,
    amount_cents = payload.total_amount_cents,
    currency = payload.price_per_credit_currency,
  )

  if not charge_result.ok:
    return 500  // platform will retry on next balance drop

  api.post("/v1/subaccounts/credits", {
    email = payload.sub_account_email,
    amount = payload.credits_requested,
    description = "Auto-recharge via " + your_provider_name,
  })

  mark_seen(payload.idempotency_key)
  return 200
```
