Create Withdrawal Request
POST /external/withdrawals ile kullanıcı payout talebi oluştur.


POST /api/v1/external/withdrawalsBu endpoint Backend-to-Backend API kategorisindedir. Partner site, kullanıcı
withdrawal istediğinde bu endpoint'i server-side çağırır.
Pientegra withdrawal kaydını PENDING_REVIEW durumunda oluşturur. Operasyon ekibi
panelde onay, gönderim veya red aksiyonu alır; sonuç webhook ile site backend'ine
iletilir.
Withdrawal flow'da kullanıcı redirect edilmez. Bu endpoint sadece kayıt oluşturur;
money movement sonucu withdrawal.sent, withdrawal.rejected veya
withdrawal.returned webhook'u ile finalize edilir.
Withdrawal tarafındaki kullanıcı deneyimi için Withdrawal Experience sayfasına bakın.
Headers
| Header | Required | Açıklama |
|---|---|---|
Authorization | Evet | Bearer <raw-api-key> formatında API key. |
Idempotency-Key | Evet | Bu create operation için benzersiz UUID v4/v7. |
Content-Type | Evet | application/json |
Request body
{
"externalUserId": "user-12345",
"externalUserLabel": "Ahmet Y.",
"amount": "250000",
"currency": "TRY",
"targetIban": "TR320010009999901234567890",
"targetHolderName": "Ahmet Yılmaz"
}| Field | Type | Required | Açıklama |
|---|---|---|---|
externalUserId | string | Evet | Partner site tarafındaki kullanıcı ID'si. |
externalUserLabel | string | Hayır | Operatör panelinde görünen kısa kullanıcı etiketi. |
amount | string veya number | Evet | Withdrawal tutarı minor unit olarak. |
currency | string | Hayır | Varsayılan TRY. Bugün aktif currency TRY'dir. |
targetIban | string | Evet | Boşluksuz IBAN. Pattern: ^[A-Z0-9]{15,34}$. |
targetHolderName | string | Evet | Alıcı hesap sahibi adı. |
webhookUrl | string | Hayır | Contract'ta kabul edilir; current delivery target için site-level webhook config esas alınmalıdır. |
Response
{
"withdrawalId": "01927b3c-9c1f-7a3a-9c4f-8a3e1f8b1c00",
"referenceNo": "W-2026-0000123"
}| Field | Açıklama |
|---|---|
withdrawalId | Withdrawal kaydının stable UUID'si. Webhook payload'ında withdrawal.id olarak gelir. |
referenceNo | Operasyon ekibinin panelde arayabileceği human-readable referans. |
Balance handling
Withdrawal entegrasyonunda iki model yaygındır:
| Model | Site tarafı aksiyon |
|---|---|
| Pre-reserve | Kullanıcı withdrawal istediğinde bakiyeyi reserve et; withdrawal.sent ile finalize et; withdrawal.rejected veya withdrawal.returned ile release/refund yap. |
| Final debit | Request sırasında bakiye değiştirme; sadece withdrawal.sent geldikten sonra debit et. |
Hangi modeli kullanırsanız kullanın, final state için webhook'u source of truth kabul edin. Synchronous response para gönderildi anlamına gelmez.
Status lifecycle
PENDING_REVIEW
├─ APPROVED
│ └─ SENT
│ └─ RETURNED
└─ REJECTED| Status | Anlam |
|---|---|
PENDING_REVIEW | Withdrawal kaydı alındı, operator review bekliyor. |
APPROVED | Operator onayladı; gönderim hazırlanıyor. |
SENT | Para bankadan çıktı. Site için successful final state. |
REJECTED | Operator request'i reddetti. |
RETURNED | Para gönderildi ancak banka tarafından iade edildi. |
Pientegra operasyon panelinde split payout gibi internal state'ler bulunabilir; External API contract'ında final integration kararları yukarıdaki event'ler üzerinden verilmelidir.
TypeScript example
import { randomUUID } from 'node:crypto';
type CreateWithdrawalInput = {
externalUserId: string;
externalUserLabel?: string;
amount: string;
targetIban: string;
targetHolderName: string;
};
export async function createWithdrawal(input: CreateWithdrawalInput) {
const response = await fetch(`${process.env.PIENTEGRA_API_BASE}/external/withdrawals`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.PIENTEGRA_API_KEY!}`,
'Idempotency-Key': randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify({ ...input, currency: 'TRY' }),
});
const body = await response.json();
if (!response.ok) {
throw new Error(`Pientegra ${body.error}: ${body.message}`);
}
return body as {
withdrawalId: string;
referenceNo: string;
};
}Error cases
| HTTP | error | Tipik sebep |
|---|---|---|
| 400 | validation_failed | IBAN formatı geçersiz, required field eksik veya partner provisioning tamamlanmamış. |
| 401 | unauthorized | API key geçersiz, inactive veya expired. |
| 409 | idempotency_key_reuse_with_different_body | Aynı key farklı body ile tekrar kullanıldı. |
| 409 | duplicate_idempotency_key | Aynı key ile request halen in-flight. |
| 429 | rate_limited | Rate limit aşıldı. |
Tam liste için Error Reference.