Kılavuzlara Geri Dön
Ödeme Geçidi API Entegrasyonu: Türk Geliştiriciler için Rehber
Bir ödeme geçidini yanlış entegre etmek kolaydır. Idempotency atlanır, webhook'lar eş zamanlı işlenir, "güvenilir" ağlarda imza doğrulaması atlanır ve altı ay sonra bir üretim olayının köküne çift çekim veya kaybolmuş bir webhook çıkar.
Bu rehber önemli kalıpları özetler: API kimlik doğrulama, idempotency anahtarları, imzalı webhook'lar, retry semantiği, hata işleme, sandbox paritesi ve kripto ödeme geçidi entegrasyonunun kendine özgü bacağı. iyzico, PayTR, Param ile çalışmış Türk geliştirici ekipleri için somut, kod seviyesinde öneriler.
Kripto Ödemelerini Kabul Ederek İşinizi Geliştirin
Mutlu Yol İşin Sadece %5'i
İlk geçiş entegrasyonu basit görünür: POST ile tahsilat oluştur, alıcıyı yönlendir, webhook al, siparişi ödendi olarak işaretle. Hafta sonunda demosu yapılabilir.
Üretim farklıdır. Göndereceğiniz kodun %95'i (ve olayların %100'ünün kaynağı) şunları ele alır:
- Yinelenen istekler (ağ retry, geri tuşu, çift tıklama).
- Yinelenen webhook teslimatları (at-least-once semantiği).
- Kaybolan webhook'lar (güvenlik duvarı, zaman aşımı, deploy anı).
- Kısmi başarısızlıklar (tahsilat başarılı, DB yazımı başarısız).
- API yanıtı ile webhook arasında yarış koşulları.
- İadeler, uyuşmazlıklar, geç durum geçişleri.
- Sandbox-üretim sapması: üretimde uç senaryolar tetiklenir.
İlk günden bu gerçeklik için inşa edin.
Kimlik Doğrulama: API Anahtarı, OAuth2, HMAC
Geçitler API çağrılarınızı üç biçimden biriyle doğrular:
- API anahtarı (secret + publishable). En yaygın. Secret sunucuda, publishable istemcide tokenizasyon için. Secret'i hiçbir zaman tarayıcıya koymayın. Planlı rotasyon; ifşa şüphesinde hemen.
- OAuth2 (client credentials). Platform tipi geçitlerde uygulamanız tüccar adına hareket eder. Kısa ömürlü access token + refresh token. Daha güçlü sınır, daha çok hareketli parça.
- HMAC imzalı istekler. Her istek paylaşılan gizli anahtarla imzalanır. Yüksek güvenlik gerektiren sunucu-sunucu için. Daha çok boilerplate.
Şema ne olursa olsun: secret'leri bir secrets manager'da saklayın (AWS Secrets Manager, HashiCorp Vault, 1Password Secrets Automation); asla kodda, asla git'e commit edilmiş env dosyasında. Anahtarları dar kapsamla çıkarın (salt okunur, fatura-özel, iade-özel). Üç ayda bir rotasyon. Türkiye'de iyzico ve PayTR her ikisi de merchant-key + secret yapısı kullanır; aynı disiplin geçerli.
Idempotency: Çift Çekimi Önleyen Kalıp
API çağrısı üç şekilde başarısız olabilir: sunucu almamış, sunucu işlemiş ama yanıt kaybolmuş, sunucu işlemiş ve hata dönmüş. İstemciden hangisi olduğu ayırt edilemez. Retry yaparsanız ikinci çekim riski doğar.
Idempotency bunu çözer. İstemci mantıksal istek başına benzersiz anahtar üretir (siparişe bağlı UUID) ve Idempotency-Key başlığında yollar. Sunucu anahtarı yanıtla birlikte kayda alır; aynı anahtarla retry orijinal yanıtı döner, işi yeniden çalıştırmaz.
POST /v1/charges
Idempotency-Key: 8b7cfa4d-1e6c-4a12-9a3e-...
Content-Type: application/json
{"amount": 9900, "currency": "try", "source": "tok_..."}
Uygulama kuralları:
- Anahtarı istemcide, mantıksal istek başına bir kez üret. Retry başına değil.
- Anahtarı sipariş kaydıyla birlikte persist et.
- UUIDv4 veya güçlü rastgele dizge. Timestamp değil. Otomatik artan sayı değil.
- Idempotency sonsuz değil: geçitler anahtarları 24-72 saat önbellekler. Sonrasında yeni istektir.
- Retry'ı açıkça test edin. Aynı anahtarı iki kez gönderin; tek çekim olduğunu doğrulayın.
Webhook: İmzalı, Asenkron, Idempotent
Webhook, API'nın asenkron karşılığıdır: bir olay gerçekleşince (ödeme tamamlandı, uyuşmazlık açıldı, iniş uzlaştı) geçit sizin endpoint'inize çağrı atar. Yanlış yaparsanız sessiz başarısızlıklar yaratır; doğru yaparsanız güvenilir ödeme durumunun omurgasıdır.
Pazarlıksız kurallar:
- İmzayı doğrula. Paylaşılan gizli anahtarla ham gövdenin HMAC-SHA256'sı ve
X-Signaturebaşlığıyla karşılaştırma (zaman-sabit). İmza geçersizse 401 dön. Kaynak IP'ye asla güvenme. - Hızla 200 dön. 500 ms altında teslim alındı bildirimi. Ağır işleri (DB yazımı, e-posta gönderimi, ardıl API çağrıları) arka plan kuyruğuna ittir. Yavaş handler zaman aşımına uğrar ve retry çığına sebep olur.
- Event ID üzerinde idempotent ol. Her webhook benzersiz event ID taşır. İşlemeden önce kaydet. Duplicate ise 200 dön ve tekrar işleme.
- Sırasız olayları tolere et. "Payment succeeded" webhook'u tahsilatı oluşturan API yanıtından önce gelebilir. Durum makinelerini her sıra altında çalışacak şekilde tasarla.
- Replay aracı aç. Endpoint'iniz düşmüşse operatörler panodan olayı yeniden tetikleyebilmeli.
// Express.js pseudokod
app.post('/webhooks/gateway', express.raw({type: 'application/json'}), (req, res) => {
const sig = req.headers['x-signature'];
const expected = hmac('sha256', SECRET, req.body).toString('hex');
if (!timingSafeEqual(sig, expected)) return res.status(401).end();
const event = JSON.parse(req.body);
if (await seenEvent(event.id)) return res.status(200).end();
await enqueue(event);
return res.status(200).end();
});
Hata İşleme ve Retry
Hataları retry'ye değer olup olmadığına göre sınıflandırın:
| Kategori | Örnek | Retry? |
|---|---|---|
| 4xx istemci | Geçersiz kart, eksik parametre | Hayır - isteği düzelt |
| 402 payment required | İhraççı reddi | Hayır - kullanıcıya bildir |
| 409 conflict | Idempotency anahtar çakışması | Hayır - duplicate olarak değerlendir, mevcut kaydı getir |
| 429 rate limit | Çok fazla istek | Evet - üssel backoff, Retry-After başlığına uy |
| 5xx sunucu | Geçit timeout, iç hata | Evet - backoff, aynı idempotency anahtarıyla |
| Ağ timeout | Connection reset, DNS | Evet - idempotency anahtarıyla retry |
Retry edilebilir hatalar için jitter'lı üssel backoff kullanın. Makul plan: 1 sn, 3 sn, 10 sn, 30 sn, 2 dk, 10 dk, sonra dur ve uyar. Retry'ı asla request handler içinde senkron yapmayın; her zaman kuyruğa koyun.
Sandbox, Test Kartları ve Test Stratejisi
Her büyük geçit belirli senaryoları tetikleyen test kartlarıyla bir sandbox ortamı sunar:
- 4242 4242 4242 4242 - genel başarı.
- 4000 0000 0000 0002 - genel ret.
- 4000 0000 0000 9995 - bakiye yetersiz.
- 4000 0027 6000 3184 - 3DS2 gerekli.
- 4000 0000 0000 0341 - ekleme başarılı, tahsilatta ret.
Test disiplini:
- Her üretim kod yolu bir sandbox testine sahip. "Basit" kod için istisna yok.
- Her webhook olayı simüle edilir; sırasız ve duplicate teslim dahil.
- Tasarım gereği hata zorlayın: seçilen ret koduyla ödemeyi yeniden oynatan test yardımcısı.
- Idempotency testi: aynı isteği iki kez gönder, tek çekim olduğunu doğrula.
- İade, kısmi iade ve uyuşmazlık testleri.
- Chaos testi: webhook işlenirken worker'ı öldürün; yeniden başlayınca temiz işlediğini doğrulayın.
Kripto Geçidi API Farkları
Yukarıdaki kalıplar kripto geçitlerine birebir uygulanır. Farklar olay modelinde, tesisat değil:
- Fatura yaşam döngüsü. Fiat tutarla fatura oluşturur, alıcı varlığı seçer, geçit depo adresi veya ödeme URI'si döner. Olaylar:
invoice.created,payment.detected,payment.completed,payment.settled,invoice.expired,invoice.underpaid. - Onaylar ayrı olay. İyi geçitler mempool algılamada bir olay, kesin onayda başka bir olay yayar. Durum makinesinde ayrı ele alın.
- Kart token'ı yok. Vault yok, 3DS yok, network tokenization yok. Yerini cüzdan imzası alır; alıcının cüzdanı çözer, sizin kodunuz değil.
- İade giden işlem. İade, cüzdanınızdan veya geçidin cüzdanından alıcının adresine zincir işlemi başlatmayı gerektirir. Alıcının adresinin değişmiş olabileceğini planlayın.
- Off-ramp olayları.
payout.initiated,payout.paid,payout.failed. Türk ihracatçı bunları KVHS ortağından gelen FAST/EFT ekstresine karşı mutabakat eder; bir iniş, çok fatura.
Kripto entegrasyonunun mutlu yol kodu kart entegrasyonundan daha kısadır: 3DS yok, vault yok, chargeback akışı yok. Uç senaryolar farklı ama daha fazla sayıda değil.
Lansman Öncesi Entegrasyon Kontrol Listesi
- Secret'ler secrets manager'da; kodda yok.
- Para hareketi yaratan her POST için idempotency anahtarı üretilip persist edildi.
- Webhook imza doğrulaması devrede ve tahrif edilmiş payload'larla unit test edildi.
- Webhook handler'ları 500 ms altında 200 dönüyor, iş asenkron.
- Event ID'leri işlemeden önce deduplicate ediliyor.
- Durum makineleri sırasız olayları tolere ediyor.
- Tüm retry edilebilir hatalarda jitter'lı üssel backoff.
- Başarısız webhook, başarısız ödeme ve başarısız iniş için panolar.
- Sürekli hata oranlarında alarm, tek başarısızlıkta değil.
- En olası 5 olay türü için runbook.
- Beklenen zirvenin 5 katıyla yük testi.
- Felaket testi: worker'ı işlem ortasında öldür; temiz kurtarmayı doğrula.
Kripto Ödemelerini Kabul Ederek İşinizi Geliştirin
Başlayın
Sıkça Sorulan Sorular
Idempotency, aynı anahtarla tekrar edilen isteğin aynı sonucu üretmesi ve çift çekim yapmamasıdır. İstemci mantıksal istek başına benzersiz Idempotency-Key başlığı gönderir; sunucu duplicate'leri tanır ve orijinal yanıtı döner.
Paylaşılan webhook gizli anahtarıyla ham istek gövdesi üzerinde HMAC-SHA256 hesaplayın ve imza başlığıyla zaman-sabit karşılaştırın. İmza geçersizse isteği reddedin, kaynak IP ne olursa olsun.
Mümkün olduğunca hızlı HTTP 200; ideal olarak 500 ms altında. Asıl işi arka plan kuyruğuna itin. İş mantığını inline yapan webhook handler'ları yük altında timeout'a düşer ve retry çığına yol açar.
Üssel backoff ile otomatik retry; tipik plan 1 sn, 5 sn, 30 sn, 2 dk, 15 dk, 1 sa, 6 sa, 24 sa. Retry bitince webhook başarısız işaretlenir ve panodan manuel replay edilebilir.
Webhook'a kaynak-of-truth olarak güvenin. Polling'i güvenlik ağı olarak kullanın: uçuş halindeki işlemleri mutabakat eden bir zamanlanmış iş. Polling'i hiçbir zaman birincil sinyal olarak kullanmayın.
Publishable key tarayıcıda güvenlidir ve istemcide kart verisini tokenize etmekte kullanılır. Secret key sunucunuzda durur ve diğer her şey için kullanılır. Secret key'i asla açığa çıkarmayın; ifşa şüphesinde ikisini de rotasyona alın.
Geçidin atanmış 3DS test kartlarını kullanın (sağlayıcıya göre değişir; genelde 4000 0027 6000 3184 gibi iyi belgelenmiş bir numara). Sandbox challenge akışını simüle eder ve karta göre frictionless başarı veya challenge-required döner.
Aynı REST + webhook kalıpları. Farklı olay adları (charge yerine fatura yaşam döngüsü), 3DS veya vaulting yok, iadeler giden zincir işlemleri. Entegrasyon disiplini (idempotency, imzalı webhook, asenkron işleme) aynıdır.
POST /refunds'u orijinal charge ID ile çağırın. Kripto için alıcının iade adresini de ekleyin (ödeyen adresten farklı olabilir). İadeler asenkrondur; müşteriyi bilgilendirmeden önce refund.completed veya refund.failed webhook'unu bekleyin.
Webhook handler içinde iş mantığı yapmak, kuyruğa itmek yerine. Geliştirmede çalışır, üretimde yük altında çöker. Hızla 200 dönün, iş asenkron; operasyon ekibiniz teşekkür edecek.