> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tahsilat.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook Yönetimi

> Modern ödeme altyapısı için güçlü ve esnek API çözümü

Webhook'lar, ödeme durumu değişiklikleri hakkında uygulamanızı gerçek zamanlı olarak bilgilendirdiği HTTP POST istekleridir. Ödeme tamamlandığında, iptal edildiğinde veya başarısız olduğunda sistem otomatik olarak belirlediğiniz URL'e bildirim gönderir.

Bu mekanizma sayesinde uygulamanızın sürekli API'yi kontrol etmesine gerek kalmaz. Tahsilat, önemli olaylar gerçekleştiğinde doğrudan size haber verir.

***

<Warning>
  Webhook URL'inizi üye işyeri arayüzü webhook yönetimi sayfasından ayarlayabilirsiniz. Hangi olayların tetikleneceğini ve hangi URL'e bildirim gönderileceğini buradan belirleyebilirsiniz.
</Warning>

<Info>
  Webhook bildirimleri, başarısız durumlarda artan sürelerle (30 saniyeden başlayarak) yeniden gönderilmeye çalışılır. Maksimum 10 deneme yapılır ve HTTP 200 OK yanıt alındığında süreç tamamlanır.
</Info>

<Warning>
  Webhook endpoint'iniz harici bir POST isteği aldığı için CSRF korumasından muaf tutulmalıdır. Laravel kullanıyorsanız webhook route'unu CSRF doğrulamasından hariç tutun, aksi takdirde 419 (Page Expired) hatası alırsınız.
</Warning>

<Warning>
  Ön Provizyon (Pre-Authorization) işlemlerinde, işlem tamamlandığında pre\_auth parametresi true olarak döner. Bu durumda, işlemin kesinleştirilmesi için provizyonun tamamlanması gerekmektedir aksi takdirde karttan herhangi bir tahsilat yapılmaz.
</Warning>

### İmza Doğrulama

Her webhook isteği `X-Tahsilat-Signature` başlığı ile HMAC-SHA256 imzası içerir. İmza formatı: `t=timestamp,v1=signature`. Bu sayede isteklerin Tahsilat tarafından geldiğini doğrulayabilirsiniz.

### Webhook isteğini karşılama

<CodeGroup>
  ```php PHP theme={null}
  $webhookSecret = 'whsec_your_webhook_secret';
  $payload = file_get_contents('php://input');
  $signature = $_SERVER['HTTP_X_TAHSILAT_SIGNATURE'] ?? '';

  try {
      $event = Webhook::constructEvent($payload, $signature, $webhookSecret);
      $transactionId = $event->getTransactionId();

      if ($event->isSuccess()) {
          echo "Payment successful for transaction: " . $transactionId;
      } else {
          echo "Payment failed for transaction: " . $transactionId;
      }

      http_response_code(200);
      echo json_encode(['status' => 'success']);
  } catch (SignatureVerificationException $e) {
      error_log("Invalid webhook signature: " . $e->getMessage());
      http_response_code(400);
      echo json_encode(['error' => 'Invalid signature']);
  } catch (Exception $e) {
      error_log("Webhook processing error: " . $e->getMessage());
      http_response_code(500);
      echo json_encode(['error' => 'Webhook processing failed']);
  }
  ```

  ```csharp .NET theme={null}
  using Tahsilat.NET.Exceptions;
  using Tahsilat.NET.Webhooks;

  [HttpPost("webhook")]
  public async Task<IActionResult> Webhook()
  {
      using var ms = new MemoryStream();
      await Request.Body.CopyToAsync(ms);
      var payloadBytes = ms.ToArray();

      var signature = Request.Headers["X-Tahsilat-Signature"].FirstOrDefault() ?? string.Empty;

      try
      {
          var webhookEvent = WebhookHandler.ConstructEvent(payloadBytes, signature, "whsec_YOUR_WEBHOOK_SECRET");

          if (webhookEvent.IsSuccess())
          {
              Console.WriteLine($"Ödeme başarılı! Transaction ID: {webhookEvent.TransactionId}");
              Console.WriteLine($"Tutar: {webhookEvent.Amount} {webhookEvent.CurrencyCode}");
          }
          else if (webhookEvent.IsFailed())
          {
              Console.WriteLine($"Ödeme başarısız. Transaction ID: {webhookEvent.TransactionId}");
          }

          return Ok();
      }
      catch (TahsilatWebhookException ex)
      {
          return BadRequest(new { error = "Invalid signature" });
      }
  }
  ```
</CodeGroup>

### Veri Okuma

<CodeGroup>
  ```php PHP theme={null}
  $transactionId = $event->transaction_id;
  $amount = $event->amount;
  $currency = $event->currency_code;
  $installments = $event->installment_count;

  // Ödeme durumu
  $paymentStatus = $event->payment_status; // 1, 2, 3
  $paymentStatusText = $event->payment_status_text; // "success", "failed"

  // İşlem durumu
  $transactionStatus = $event->transaction_status; // 1-10
  $transactionStatusText = $event->transaction_status_text; // "completed", "pending" vs

  // Ödeme yöntemi
  $paymentMethod = $event->payment_method; // 1 veya 2
  $paymentMethodText = $event->payment_method_text; // "is_3d" veya "is_2d"

  // Tarihler
  $createdAt = $event->created_at;
  $startAt = $event->start_at;
  $endAt = $event->end_at;

  // Metadata (özel verileriniz)
  $orderId = $event->getMetadataValue('order_id');
  $allMetadata = $event->getMetadataAsKeyValue();

  // Ön provizyon kontrolü
  $isPreAuth = $event->pre_auth;
  ```
</CodeGroup>
