Webhooks
Paytalya, bir ödeme ya da iade durumu değiştikçe endpoint’inize bir webhook gönderir. Payload minimaldir: yalnızca olay tipi + paymentCode. Webhook bir tetikleyicidir, sonucun kendisi değildir; detayı ve nihai durumu GET /v1/payments ile çekersiniz.
Event tipleri
Bölüm başlığı “Event tipleri”| Event tipi | Ne zaman gönderilir |
|---|---|
payment.captured | Tahsilat onaylandı (ödeme captured). |
payment.failed | 3D ya da tahsilat reddedildi (ödeme failed). |
payment.expired | Ödeme süresi doldu / 3D yarıda bırakıldı (ödeme expired). |
refund.approved | Bir iade ya da iptal onaylandı. |
refund.declined | Bir iade ya da iptal reddedildi. |
Banka ham olayları (yetkilendirme adımları, ara durumlar) webhook olarak gönderilmez. Ödeme durumlarının tam listesi için Ödeme Yaşam Döngüsü.
Payload
Bölüm başlığı “Payload”{ "id": "whd_a1b2c3", "type": "payment.captured", "paymentCode": "pay_7Hq2bL", "occurredAt": "2026-06-14T12:05:11Z"}| Alan | Açıklama |
|---|---|
id | Teslimat kimliği (delivery-id). Idempotency için kullanılır. |
type | Event tipi (yukarıdaki tablo). |
paymentCode | İlgili ödemenin kodu; detayı sorgulamak için kullanın. |
occurredAt | Olayın gerçekleştiği an (UTC, ISO 8601). |
Payload, kesin sonucu veya tutarı taşımaz; bunlar kasıtlıdır. Ham banka yanıtı, kart verisi ya da başka bir hassas alan içermez. Karar vermek için her zaman ödemeyi sorgulayın.
Başlıklar (headers)
Bölüm başlığı “Başlıklar (headers)”Her teslimat üç imza başlığı taşır:
| Başlık | Açıklama |
|---|---|
X-Paytalya-Signature | sha256=<hex>: ham (raw) istek gövdesinin HMAC-SHA256 imzası. |
X-Paytalya-Timestamp | Olayın gerçekleştiği anın epoch saniyesi (gövdedeki occurredAt ile aynı an, saniye biçiminde). İsteğe bağlı replay sertleştirmesi içindir; imzaya dahil değildir. 5 dakikadan eski istekleri reddedebilirsiniz (replay koruması), ama bu kontrol imzadan bağımsızdır. |
X-Paytalya-Delivery-Id | Teslimat kimliği (gövdedeki id ile aynı). Aynı teslimat tekrar gelebilir; idempotency için kullanın. |
İmzada kullanılan secret, API anahtarından ayrı bir webhook secret’ıdır ve onboarding sırasında size verilir. Bu secret’ı asla loglamayın, istemciye göndermeyin ya da reponuzda saklamayın.
İmza doğrulama
Bölüm başlığı “İmza doğrulama”İmza, yalnızca ham (raw) istek gövdesi üzerinden hesaplanır; timestamp imzaya dahil edilmez, herhangi bir birleştirme yapılmaz. Doğrulamayı sabit-zamanlı karşılaştırma ile yapın (zamanlama saldırılarına karşı). Dil-agnostik sözde-kod:
rawBody = exact bytes received on the request
expected = "sha256=" + lowercase_hex( HMAC_SHA256(webhookSecret, rawBody) )
# 1) imza eşleşmeli (sabit-zamanlı karşılaştırma): yalnızca ham gövde üzerindenif not constantTimeEquals(expected, header["X-Paytalya-Signature"]): return 400
# 2) (opsiyonel) replay sertleştirmesi: çok eski olayları reddet (imzadan BAĞIMSIZ)timestamp = header["X-Paytalya-Timestamp"]if abs(now() - timestamp) > 5 minutes: return 400
# imza geçerli → 2xx döndür, sonra ödemeyi GET ile sorgulareturn 200Endpoint gereksinimleri
Bölüm başlığı “Endpoint gereksinimleri”- Hızlı
2xxdöndürün. Endpoint’iniz teslimatı 5 saniye içindeHTTP 2xxile yanıtlamalıdır; aksi halde teslimat timeout sayılır ve yeniden denenir. Ağır işi (sorgu, sipariş güncelleme) yanıttan sonra asenkron yapın. - İmzayı doğrulayın. Yukarıdaki adımlarla imzayı ve zaman damgasını doğrulamadan gövdeye güvenmeyin.
- Idempotent olun. Aynı
X-Paytalya-Delivery-Idbirden fazla gelebilir (retry’da delivery-id sabittir). İşleme mantığınız aynı teslimatı iki kez almaya dayanıklı olmalıdır. - Tetikleyici olarak kullanın. Bildirim gelince ödemenin detayını
GET /v1/paymentsile sorgulayın ve kararınızı sorgu sonucuna göre verin.
Yeniden deneme ve teslimat
Bölüm başlığı “Yeniden deneme ve teslimat”-
Başarı:
HTTP 2xx. Teslimat tamamlanmış sayılır. -
Kalıcı hata:
4xxistemci hatası → yeniden denenmez. Endpoint’inizin geçerli teslimatlara2xxdöndürdüğünden emin olun. -
Yeniden deneme:
5xxve timeout → exponential backoff ile tekrar denenir:30 sn → 2 dk → 10 dk → 1 sa → 6 saİlk teslimattan itibaren 24 saat boyunca başarı alınamazsa teslimat kalıcı olarak bırakılır.
-
Sıra garantisi yok: Olaylar gönderildikleri sırada gelmeyebilir. Durumu webhook tipine değil,
GET /v1/paymentssonucuna göre belirleyin.
Yapılandırma
Bölüm başlığı “Yapılandırma”Webhook URL’iniz ve secret’ınız hesabınıza onboarding sırasında tanımlanır. Webhook URL’i tanımlı değilse hiçbir bildirim gönderilmez; bu durumda ödeme durumlarını yalnızca GET /v1/payments ile takip edin.