Banka Hesapları
Webhook Olayları

Webhook Olayları

Banka Hesapları ürünü iki olay ailesi gönderir:

OlayNe zaman
bank_account.transaction.receivedBağlı hesaplarınızda yeni bir hareket okunduğunda.
bank_transfer.created, bank_transfer.completed, bank_transfer.failed, bank_transfer.returnedBir para transferi oluşturulduğunda ve sonuçlandığında. → Transfer olayları

Teslimat, imza doğrulama ve yeniden deneme bütün ürünlerde aynıdır: Webhook'lar. Bu sayfanın ilk bölümü hareket olayını anlatır.

Ne zaman gönderilir

DurumOlay
Olağan okumada ilk kez görülen hareket — gelen (CREDIT) ya da giden (DEBIT)Gönderilir, hareket başına bir olay
Bağlantı ilk kurulduğunda geriye dönük okunan geçmiş hareketlerGönderilmez
Geçmiş verinin yeniden okunmasında bulunan hareketlerGönderilmez
Daha önce okunmuş bir hareketin bankadan yeniden gelmesiGönderilmez; aynı hareket ikinci kez kaydedilmez
Doğrulama için bekletilen, sonradan listede görünür hâle gelen hareketGönderilmez

Olay gönderilmeyen hareketler de Hareketler ucunda görünür. Hareketlerin tamamını almak için webhook'u liste ucuyla birlikte kullanın (aşağıya bakın).

Örnek teslimat

{
  "id": "00000000-0000-0000-0000-00000000e001",
  "type": "bank_account.transaction.received",
  "organizationId": "00000000-0000-0000-0000-00000000000a",
  "productCode": "BANK_CONNECT",
  "environment": "LIVE",
  "eventVersion": 1,
  "schemaVersion": "v1",
  "createdAt": "2026-01-01T07:05:01.000Z",
  "data": {
    "transactionId": "00000000-0000-0000-0000-000000001000",
    "accountId": "00000000-0000-0000-0000-000000000100",
    "connectionId": "00000000-0000-0000-0000-000000000010",
    "bankEftCode": "0000",
    "bankName": "ÖRNEK BANKA",
    "direction": "CREDIT",
    "amountMinor": 150000,
    "currency": "TRY",
    "bookedAt": "2026-01-01T07:00:00.000Z",
    "valueAt": null,
    "receivedAt": "2026-01-01T07:05:00.000Z",
    "canonicalType": "TRANSFER_IN",
    "description": "ORNEK ACIKLAMA",
    "counterpartyNameMasked": "Ö**** A****",
    "counterpartyIbanMasked": "TR00 **** **** **** **** **00 00",
    "receiptNo": null
  }
}

Zarf

AlanAnlamı
idOlay kimliği; x-lunixi-event-id başlığıyla aynı değer.
typebank_account.transaction.received
organizationIdOrganizasyonunuz.
productCodeBANK_CONNECT
environmentTEST ya da LIVE.
eventVersionOlayın sürümü; bugün 1.
schemaVersiondata şemasının sürümü; bugün v1.
createdAtOlayın oluşturulduğu an.
dataHareketin alanları; aşağıya bakın.

Zarfta bu tabloda olmayan alanlar da bulunabilir; kodunuzu yalnız burada belgelenen alanlara dayandırın.

data

AlanTipAçıklama
transactionIdstring (UUID)Hareketin kimliği; Hareketler ucundaki transactionId ile aynı.
accountIdstring (UUID)Hareketin ait olduğu hesap.
connectionIdstring (UUID)Hesabın bağlantısı.
bankEftCodestringBankanın EFT kodu.
bankNamestringBankanın adı.
directionstringCREDIT (giren) ya da DEBIT (çıkan).
amountMinorintegerTutar, minor birimde; her zaman sıfır ya da pozitif.
currencystringPara birimi (ISO 4217).
bookedAtstringİşlem tarihi.
valueAtstring | nullValör tarihi.
receivedAtstringHareketin Lunixi'de kaydedildiği an.
canonicalTypestringBankadan bağımsız hareket tipi. → Hareket tipleri
descriptionstring | nullBankanın yazdığı açıklama, maskelenmeden.
counterpartyNameMaskedstring | nullKarşı tarafın maskeli adı.
counterpartyIbanMaskedstring | nullKarşı tarafın maskeli IBAN'ı.
receiptNostring | nullDekont numarası.

API yanıtlarından farklı olarak webhook'ta değeri olmayan alanlar null olarak gelir; alan yine de gövdede bulunur. Hem API'yi hem webhook'u işleyen kodunuz iki durumu da karşılamalıdır.

Abonelik

Olayı almak için Banka Bağlantıları ürünü için bir webhook endpoint'i oluşturun:

AlanDeğer
productCodeBANK_CONNECT
eventTypes["bank_account.transaction.received"] ya da bu ailedeki bütün olaylar için ["bank_account.*"]. Transfer olayları için ["bank_transfer.*"] ekleyin.
environmentTEST endpoint test ortamındaki hareketleri, LIVE endpoint canlı ortamdaki hareketleri alır.

Endpoint oluşturma, imza secret'ı ve teslimat geçmişi: Webhook Kurulumu.

İmza, yeniden deneme ve tekilleştirme

İmzayı her teslimatta doğrulayın; imza biçimi ve yeniden deneme politikası bütün ürünlerde aynıdır: Webhook'lar.

Teslimat en az bir kez yapılır; aynı olay birden çok kez gelebilir. Olayı x-lunixi-event-id ile idempotent işleyin. Aynı hareket için olay kimliği her zaman aynıdır; ayrıca data.transactionId ile de tekilleştirebilirsiniz.

PHP ile işleme

PHP SDK imzayı doğrular ve data alanlarını tipli olarak verir:

use Lunixi\Sdk\BankConnect\BankAccountTransactionReceived;
use Lunixi\Sdk\BankConnect\BankConnectEvents;
use Lunixi\Sdk\Exception\WebhookVerificationException;
 
$rawBody = file_get_contents('php://input') ?: '';
 
try {
    $event = $lunixi->webhooks()->verify($rawBody, getallheaders() ?: [], getenv('LUNIXI_WEBHOOK_SECRET'));
} catch (WebhookVerificationException $e) {
    http_response_code(400);
    return;
}
 
if ($event->type() === BankConnectEvents::TRANSACTION_RECEIVED) {
    $transaction = BankAccountTransactionReceived::fromEvent($event);
    // $event->id() ile tekilleştirip kaydedin; ör. $transaction->transactionId(),
    // $transaction->direction(), $transaction->amountMinor(), $transaction->description()
}
 
http_response_code(200);

BankConnectEvents::ALL_EVENTS değeri (bank_account.*) endpoint aboneliğinde kullanılabilir.

Webhook'u liste ucuyla birlikte kullanma

Webhook yeni hareketi hızlı öğrenmenin yoludur; tek kaynak değildir. Endpoint'iniz bir süre erişilemezse, ya da hareket olay üretmeyen bir yoldan geldiyse (ör. ilk geriye dönük okuma), hareketi Hareketler ucundan tamamlayın:

Hareketleri senkron tutmakVeri akışı: hareketler webhook’tan (hızlı) ve liste ucunun düzenli telafi okumalarından gelir; ikisi de saklanmadan önce transactionId ile tekilleştirilir, saklanan en yeni receivedAt bir sonraki telafi okumasının durma noktasıdır.HIZLITELAFİTEK KEZ YAZDURMA NOKTASIWebhookbank_account.transaction.receivedListe ucuGET …/transactionsTekilleştirmetransactionId ileKayıtlarınızen yeni receivedAtLEJANTKAYNAKTEKİLLEŞTİRMESİZİN SİSTEMİNİZSONRAKİ TELAFİ BURADA DURUR
Webhook’tan gelen her hareketi transactionId ile kaydedin, liste ucunu düzenli aralıklarla ilk sayfadan okuyup kaydetmediklerinizi ekleyin ve iki kaynaktan gelen aynı hareketi transactionId ile tekilleştirin.

Transfer olayları

Para transferi oluşturulduğunda ve sonuçlandığında Lunixi endpoint'inize aşağıdaki olayları gönderir. Döviz işlemleri için webhook gönderilmez; sonucu Döviz İşlemi ucundan sorgulayın.

OlayNe zamandata.status
bank_transfer.createdTransfer oluşturulduğunda. API'den oluşturulan transfer SUBMITTED, panelden başlatılan ve doğrulama kodu bekleyen transfer PENDING_OTP durumundadır.SUBMITTED ya da PENDING_OTP
bank_transfer.completedBanka transferi tamamladığında.COMPLETED
bank_transfer.failedTransfer gerçekleşmediğinde; sebep data.failureCode alanında.FAILED
bank_transfer.returnedTamamlanan transfer alıcı bankadan iade edildiğinde.RETURNED
  • Her transfer için her olay en çok bir kez üretilir; yeniden teslimatlarda olay kimliği aynıdır.
  • Panelden başlatılıp doğrulama kodu süresinde onaylanmayan ya da iptal edilen transfer CANCELED olur; bunun için ayrı olay gönderilmez. Durumu transfer ucundan okuyun.
  • Sonucu bankadan doğrulanamayan transfer (outcomeUnknown) için olay, sonuç kesinleştiğinde gönderilir.
  • Olaylar sırasız gelebilir (ör. completed, created'dan önce). Kodunuzu olayın sırasına değil data.status alanına ve transferin güncel durumuna göre yazın.

Örnek teslimat

{
  "id": "00000000-0000-0000-0000-00000000e101",
  "type": "bank_transfer.completed",
  "organizationId": "00000000-0000-0000-0000-00000000000a",
  "productCode": "BANK_CONNECT",
  "environment": "LIVE",
  "eventVersion": 1,
  "schemaVersion": "v1",
  "createdAt": "2026-01-01T07:00:21.000Z",
  "data": {
    "transferId": "00000000-0000-0000-0000-000000002000",
    "connectionId": "00000000-0000-0000-0000-000000000010",
    "accountId": "00000000-0000-0000-0000-000000000100",
    "bankEftCode": "0000",
    "bankName": "ÖRNEK BANKA",
    "status": "COMPLETED",
    "rail": "FAST",
    "amountMinor": 150075,
    "currency": "TRY",
    "receiverIbanMasked": "TR00 **** **** **** **** **00 00",
    "receiverNameMasked": "Ö**** T****** A.Ş.",
    "paymentPurpose": null,
    "description": "Fatura 2026-0042",
    "failureCode": null,
    "idempotencyKey": "payout-2026-0042",
    "createdAt": "2026-01-01T07:00:00.000Z",
    "completedAt": "2026-01-01T07:00:20.000Z",
    "failedAt": null,
    "returnedAt": null
  }
}

Zarf alanları hareket olayıyla aynıdır; type olayın adını taşır.

Transfer olayının data alanları

AlanTipAçıklama
transferIdstring (UUID)Transferin kimliği; transfer ucundaki id ile aynı.
connectionIdstring (UUID)Hesabın bağlantısı.
accountIdstring (UUID)Paranın çıktığı hesap.
bankEftCodestringBankanın EFT kodu.
bankNamestringBankanın adı.
statusstringOlay anındaki transfer durumu.
railstring | nullBankanın seçtiği yol (INTERNAL, INTRABANK, FAST, EFT, UNKNOWN).
amountMinorintegerTutar, minor birimde.
currencystringPara birimi (ISO 4217).
receiverIbanMaskedstringAlıcının maskeli IBAN'ı.
receiverNameMaskedstringAlıcının maskeli adı.
paymentPurposestring | nullÖdeme amacı kodu.
descriptionstring | nullTransfer açıklaması.
failureCodestring | nullfailed ve returned olaylarında sebep kodu. → Transfer sonuç kodları
idempotencyKeystringTransferin Idempotency-Key'i; kendi ödeme kaydınızla eşleştirmek için kullanın.
createdAtstringTransferin oluşturulma zamanı.
completedAtstring | nullTamamlanma zamanı.
failedAtstring | nullBaşarısız olma zamanı.
returnedAtstring | nullİade zamanı.

Değeri olmayan alanlar null olarak gelir.

PHP ile işleme

use Lunixi\Sdk\BankConnect\BankTransferEvent;
use Lunixi\Sdk\BankConnect\BankTransferEvents;
 
$event = $lunixi->webhooks()->verify($rawBody, getallheaders() ?: [], getenv('LUNIXI_WEBHOOK_SECRET'));
 
if (in_array($event->type(), BankTransferEvents::ALL, true)) {
    $transfer = BankTransferEvent::fromEvent($event);
    // $event->id() ile tekilleştirin; $transfer->idempotencyKey() ile kendi ödeme kaydınızı bulun.
    if ($event->type() === BankTransferEvents::FAILED) {
        // $transfer->failureCode()
    }
}

BankTransferEvents::ALL_EVENTS değeri (bank_transfer.*) endpoint aboneliğinde kullanılabilir. PHP SDK 0.22.0 ve üstü gerekir.