Aynı yöntem PayTR'nin bildirim (callback) URL'si için de geçerlidir. Tünel tüm planlarda, ücretsiz planda da açılır; istek yakalama ve tekrar gönderme (replay) de tüm planlardadır.
callbackUrl, webhook ve PayTR bildirim URL'si arasındaki fark ne?
Üçü de "ödeme sonucunu bana bildir" der ama farklı yollardan gelir. Hangisini test ettiğini bilmek, sorunun yerini bulmayı kolaylaştırır:
| Özellik | iyzico callbackUrl (3DS / ödeme formu) | iyzico webhook (İşyeri Bildirimleri) | PayTR bildirim URL'si |
|---|---|---|---|
| Kim gönderir | Müşterinin tarayıcısı, iyzico yönlendirmesiyle POST | iyzico sunucusu | PayTR sunucusu |
| Gelen alanlar | status, paymentId, conversationId, conversationData, mdStatus | paymentConversationId, status, iyziEventType, iyziReferenceCode vb. | merchant_oid, status, total_amount, hash |
| Beklenen yanıt | Kullanıcıya gösterilecek sayfa | 2xx durum kodu | Düz metin OK |
| Yeniden deneme | Yok (tek yönlendirme) | 2xx gelmezse 15 dakikada bir, en çok 3 deneme | OK gelmezse tekrar gönderir; aynı ödeme için birden çok bildirim gelebilir |
| Localhost'a ulaşır mı | Yalnızca aynı tarayıcıda; telefon ya da başka cihazla test için hayır | Hayır, HTTPS genel URL zorunlu | Hayır, PayTR sunucusu erişebilmeli |
Adım 1: Yerel uygulamayı 3000 portunda çalıştır
Aşağıdaki küçük Express uygulaması üç uç noktayı karşılar ve gelen veriyi konsola yazar. Amaç akışı görmek; canlıya çıkmadan önce imza ve hash doğrulamasını mutlaka ekle.
// npm install express
const express = require("express");
const app = express();
// iyzico 3DS / ödeme formu: tarayıcı form POST ile döner
app.post("/iyzico/callback", express.urlencoded({ extended: false }), (req, res) => {
console.log("iyzico callback", req.body); // status, paymentId, mdStatus...
res.send("Ödeme sonucu alındı");
});
// iyzico webhook: sunucudan sunucuya, 2xx beklenir
app.post("/iyzico/webhook", express.raw({ type: "*/*" }), (req, res) => {
console.log("imza", req.get("x-iyz-signature-v3"));
console.log("gövde", req.body.toString("utf8"));
res.sendStatus(200);
});
// PayTR bildirim URL'si: form POST, yanıt yalnızca "OK"
app.post("/paytr/bildirim", express.urlencoded({ extended: false }), (req, res) => {
console.log("paytr", req.body); // merchant_oid, status, total_amount, hash
// Canlıda: hash'i merchant_key/merchant_salt ile doğrula, siparişi bir kez işle
res.type("text/plain").send("OK");
});
app.listen(3000, () => console.log("http://localhost:3000"));
Adım 2: zorven 3000 ile HTTPS adresi al
İstemciyi kur, panelden aldığın token'ı kaydet ve tüneli aç:
zorven authtoken zrv_live_...
zorven 3000
Çıktıda https://<ad>--<slug>.zorven.app biçiminde bir adres görünür. Sertifika otomatik ve geçerlidir; ek ayar gerekmez. Yalnızca birkaç saatlik bir test için kendini silen geçici tünel de açabilirsin:
zorven ephemeral 3000 --ttl 2h
Adım 3: Adresi iyzico sandbox ve PayTR ayarlarına yaz
- callbackUrl: ödeme başlatma (3DS initialize ya da ödeme formu) isteğinde
callbackUrlalanınahttps://<ad>--<slug>.zorven.app/iyzico/callbackyaz. iyzico sandbox API adresihttps://sandbox-api.iyzipay.com'dur. - Webhook: iyzico üye işyeri panelinde Settings > Merchant Settings > Merchant Notifications (İşyeri Bildirimleri) alanına
.../iyzico/webhookadresini gir.X-IYZ-SIGNATURE-V3imza başlığı hesabında imza özelliği açıksa gönderilir; açtırmak için iyzico dokümanı entegrasyon@iyzico.com adresini gösterir. - PayTR: mağaza panelindeki bildirim URL'si ayarına
.../paytr/bildirimadresini yaz. PayTR, bu URL'nin oturum kontrolü gibi bir erişim kısıtının arkasında olmamasını ister. - Sandbox'ta test kartıyla bir ödeme yap.
Adım 4: İstekleri canlı incele ve tekrar gönder
Panelde Loglar sayfasındaki Yakalama düğmesini aç (varsayılan kapalıdır; owner veya admin açar). Bundan sonra her isteğin başlıklarını ve gövdesini görürsün. Bir bildirimi seçip yeniden gönder dersen aynı istek yerel uygulamana tekrar gider; iyzico'nun 15 dakikalık yeniden denemesini beklemen gerekmez. "Düzenle ve yeniden gönder" ile gövdeyi ya da başlıkları değiştirip hata senaryolarını denersin, replay farkı (diff) da eski ve yeni yanıtı karşılaştırır. Yakalanan gövde varsayılan olarak 256 KB ile sınırlıdır.
Sık yapılan hatalar ve dikkat edilecekler
- Adres her seferinde değişiyor mu? Aynı istemciden aynı portla çalıştırdığında tünel adı aynı kalır, sandbox ayarını yeniden yazman gerekmez.
zorven ephemeraltüneli süre dolunca silinir. Hobby ve üstünde kendi alan adını, Pro ve üstündead.zorven.appkısa adını kullanabilirsin. - Free plan uyarı sayfası yalnızca tarayıcıdan yapılan HTML GET gezintilerinde çıkar; iyzico ve PayTR'nin POST bildirimleri etkilenmez.
- İmza için ham gövde: imzayı doğrulayacaksan gövdeyi JSON'a çevirmeden önceki hâliyle sakla; örnekte
express.rawbu yüzden kullanıldı. - CSRF korumalı çatılar (Laravel, Django, Rails) bildirim rotasını muaf tutmazsan 419/403 döner; gelen istek panelde görünür, sorunun yerini oradan bulursun.
- PayTR'ye HTML döndürme: yanıt yalnızca
OKolmalı; aksi hâlde ödeme panelde "Devam ediyor" kalır. - Zorven'in kenarda imza doğrulaması (
verify_webhook, Pro+) GitHub, Stripe, GitLab, Shopify ve Slack imzalarını doğrular; iyzico ve PayTR imzasını kendi kodunda doğrula.
Geliştirici senaryolarının tamamı için Geliştiriciler sayfasına, plan farkları için fiyatlandırma sayfasına, tüm komutlar için dokümanlara bak. Operatörün CGNAT kullanıyorsa bu yöntem yine çalışır; ayrıntı CGNAT nedir rehberinde. Oyun sunucusu açmak istersen Minecraft sunucusu port açmadan rehberine göz at. Tüm rehberler rehber sayfasında.
Ücretsiz başla Dokümanları oku
Ne zaman başka bir yöntem seçmelisin?
- Ekip ortak bir staging ortamı kullanıyorsa, bildirimleri herkesin bilgisayarına değil staging sunucusuna yönlendirmek daha düzenlidir.
- Yalnızca callbackUrl'i aynı tarayıcıda deniyorsan tarayıcı yönlendirmesi localhost'a da ulaşır; tünel, webhook ve PayTR bildirimi ya da telefondan test için gerekir.
- Canlı ortam için bildirim URL'sini geliştirici bilgisayarına bağlama; üretim sunucunu kullan.
Sık sorulan sorular
Kaynaklar
- iyzico: Webhook (HTTPS URL zorunluluğu, X-IYZ-SIGNATURE-V3, yeniden denemeler) (erişim: 2026-11-08)
- iyzico: 3DS Implementation (callbackUrl alanları) (erişim: 2026-11-08)
- PayTR: iFrame API 2. adım (bildirim URL'si, OK yanıtı, hash) (erişim: 2026-11-08)
- Zorven dokümanları: tüneller, istek denetleyicisi ve replay (erişim: 2026-11-08)
- Zorven fiyatlandırma ve plan limitleri (erişim: 2026-11-08)