Kripto Ödeme API Entegrasyonu: Fatura, İmza ve Webhook Rehberi

Pratik bir geliştirici rehberi: fatura için tek imzalı istek, durum için tek webhook adresi ve sistemi güvenilir kılan güvenlik ayrıntıları.

Güncellendi: 5 dk okuma
Kripto ödeme API entegrasyonu: fatura oluşturan imzalı POST isteği ve webhook cevabı

Kripto ödeme API entegrasyonu iki parçadan oluşur: her sipariş için fatura oluşturup ödeme sayfası adresini döndüren sunucu tarafı bir istek ve ödeme zincirde tespit edilip onaylandığında imzalı durum bildirimlerini alan bir webhook adresi. mistKET'te ikisi de düz HTTPS ve JSON'dur, HMAC-SHA256 ile imzalanır; SDK gerekmez.

Bu rehberde akışın tamamını kodla anlatıyor, ardından bir demoyu üretim sisteminden ayıran güvenlik ve güvenilirlik ayrıntılarına geçiyoruz.

Tek bakışta mimari

Her kripto ödeme API entegrasyonu aynı beş adımlı döngüyü izler:

  1. Sipariş oluşur — sisteminiz tutar, para birimi, sipariş numarası ve callback adresiyle POST /api/v1/invoices çağırır.
  2. Yönlendirme — müşteriyi dönen checkout_url adresine gönderirsiniz.
  3. Ödeme — müşteri hazır sayfada ağı seçip öder; kur fatura süresince kilitlidir.
  4. Webhook — mistKET callback adresinize invoice.paid, invoice.confirmed ya da istisna olayını POST eder.
  5. Teslimat — imzayı doğrular, siparişi ödendi yapar ve teslim edersiniz.

API anahtarınız, API secret'ınız ve webhook secret'ınız hesabınız onaylandıktan sonra merchant panelinde oluşturulur. Tam referans paneldeki API bölümündedir.

Adım 1: fatura isteğini imzalayıp gönderin

Her API isteği üç başlık taşır. İmza, {timestamp}.{ham gövde} metninin API secret'ınızla alınmış HMAC-SHA256 değerinin hex hâlidir:

POST /api/v1/invoices
X-Api-Key: mp_live_…
X-Api-Timestamp: 1760000000
X-Api-Signature: hex(hmac_sha256("{ts}.{body}", secret))

{
  "amount": "184.50",
  "currency": "USD",
  "order_id": "2041",
  "callback_url": "https://magazaniz.com/webhooks/mistket"
}

En basit PHP sürümü şöyle:

$body = json_encode([
  'amount' => '184.50', 'currency' => 'USD',
  'order_id' => '2041',
  'callback_url' => 'https://magazaniz.com/webhooks/mistket',
]);
$ts  = (string) time();
$sig = hash_hmac('sha256', $ts . '.' . $body, $apiSecret);
// $body'yi X-Api-Key, X-Api-Timestamp, X-Api-Signature ile gönderin

Gönderdiğiniz baytların aynısını imzalayın. İmzaladıktan sonra JSON'u yeniden kodlamak (farklı boşluk ya da anahtar sırası) imza hatalarının bir numaralı sebebidir.

Adım 2: hazır ödeme sayfasına yönlendirin

Başarılı çağrı; fatura UUID'si, durumu (new) ve checkout_url ile 201 Created döner. UUID'yi siparişinizle eşleştirip saklayın ve müşteriyi yönlendirin. Hazır sayfa tam tutarı, QR kodu, geri sayımı ve canlı durumu gösterir, mobilde sorunsuz çalışır. Ağı müşteri orada seçer — TRON, BNB Smart Chain, Ethereum ya da Arbitrum üzerinde USDT; ayrıca TRX, BNB ve ETH — siz API çağrısında sabitlemediyseniz.

API fatura oluşturmanın yanında listeleme, sorgulama ve iptal de sunar; sepet değiştiğinde ya da sipariş yarım kaldığında işe yarar.

Adım 3: webhook'u alın ve doğrulayın

Durum değiştiğinde mistKET callback adresinize şu başlıklarla JSON POST eder:

BaşlıkAmaç
X-Mistket-EventOlay adı, ör. invoice.confirmed
X-Mistket-Timestampİmzada kullanılan Unix zamanı
X-Mistket-Signaturesha256= + webhook secret ile {timestamp}.{ham gövde} HMAC-SHA256 değeri
X-Mistket-DeliveryTeslim numarası, loglama için

PHP ile doğrulama:

$raw = file_get_contents('php://input');
$ts  = $_SERVER['HTTP_X_MISTKET_TIMESTAMP'] ?? '';
$got = $_SERVER['HTTP_X_MISTKET_SIGNATURE'] ?? '';
$exp = 'sha256=' . hash_hmac('sha256', $ts . '.' . $raw, $webhookSecret);
if (!hash_equals($exp, $got) || abs(time() - (int) $ts) > 300) {
  http_response_code(401); exit;
}
$event = json_decode($raw, true);

Sabit zamanlı karşılaştırma kullanın (PHP'de hash_equals, Python'da hmac.compare_digest, Node.js'te crypto.timingSafeEqual) ve tekrar saldırılarını engellemek için eski zaman damgalarını reddedin. HMAC'in temeli için RFC 2104 belgesine bakabilirsiniz.

Özetle: doğruluk kaynağı müşterinin tarayıcısının sitenize dönmesi değil, webhook'tur. Geçerli imza olmadan hiçbir siparişi ödendi yapmayın.

Örnek webhook içeriği

Onaylanan bir ödeme kısa bir JSON belgesi olarak gelir. En çok kullanacağınız alanlar olay adı, sipariş numaranız, durum ve beklenen ile alınan tutarlardır:

POST https://magazaniz.com/webhooks/mistket
X-Mistket-Event: invoice.confirmed
X-Mistket-Signature: sha256=…

{ "event": "invoice.confirmed", "data": {
  "order_id": "2041", "status": "confirmed",
  "pay_amount": "184.5", "paid_amount": "184.5",
  "pay_currency": "USDT", "network": "TRC20" } }

pay_currency ve network alanlarını siparişle birlikte saklayın. Hem muhasebe hem de sonradan yapılacak destek yazışmaları için işe yarar.

Node.js ve Python ile doğrulama

Aynı kontrol iki popüler dilde şöyle görünür:

// Node.js (bu route için express.raw ile)
const exp = 'sha256=' + crypto.createHmac('sha256', secret)
  .update(ts + '.' + rawBody).digest('hex');
const ok = crypto.timingSafeEqual(Buffer.from(exp), Buffer.from(sig));

# Python
exp = 'sha256=' + hmac.new(secret.encode(), f'{ts}.{raw}'.encode(),
                           hashlib.sha256).hexdigest()
ok = hmac.compare_digest(exp, sig)

İki durumda da ham istek gövdesini okuduğunuzdan emin olun. Birçok framework JSON'u otomatik ayrıştırır; ayrıştırılıp yeniden oluşturulan baytlar artık imzayla eşleşmez.

Yerelde test

Webhook'lar herkese açık bir HTTPS adresi ister; bu yüzden dizüstü bilgisayarınız onları doğrudan alamaz. İki pratik seçenek var: karşılayıcıyı erkenden bir test sunucusuna kurmak ya da yerel portunuzu geçici olarak bir tünel aracıyla dışarı açmak. Test callback adresine işaret eden küçük faturalar oluşturun, ardından merchant panelindeki webhook teslim kayıtlarından tam olarak ne gönderildiğini ve sunucunuzun ne cevap verdiğini inceleyin.

Test sırasında her olay türünü en az bir kez görmeye çalışın: ödendi, onaylandı, eksik ödendi ve süresi doldu. Kodunuzun her dalı gerçek bir webhook ile çalıştırılmış olursa canlıda sürprizle karşılaşma ihtimaliniz çok düşer.

Adım 4: her durumu yönetin

Webhook içeriğinde sipariş numarası, durum, beklenen tutar (pay_amount), alınan tutar (paid_amount), para birimi ve ağ bulunur. Her olayı bir aksiyona bağlayın:

OlayAnlamıTipik aksiyon
invoice.paidTransfer görüldü, onay bekleniyor"Ödeme alındı, onaylanıyor" göster
invoice.confirmedGerekli onay sayısına ulaşıldıÖdendi yap ve teslim et
invoice.underpaidToleransın altındaTamamlamayı bekle ya da müşteriye yaz
invoice.overpaidBeklenenden fazlaTeslim et, farka karar ver
invoice.expiredSüresinde geçerli ödeme yokStoku serbest bırak, sipariş ödenmemiş kalsın

Eksik ödeme toleransı, toplanan kısmi ödemeler ve tanımlı süre içindeki geç ödemeleri mistKET yönetir; kodunuz yalnızca nihai sonuca tepki verir.

Güvenilirlik: yeniden deneme ve idempotency

Adresiniz kapalıysa ya da hata dönerse webhook'lar saatlerce artan aralıklarla yeniden denenir. Yani aynı olayı bazen iki kez alırsınız. Karşılayıcınızı sipariş numarasına göre idempotent yapın:

  • Hızlıca 2xx dönün, ağır işleri kuyruğa atın.
  • Teslim etmeden önce siparişin zaten ödendi olup olmadığını kontrol edin.
  • Sorunları izleyebilmek için teslim numarasını ve olayı loglayın; panel de webhook teslim kayıtlarını gösterir.

Güvenlik kontrol listesi

Kripto ödeme API entegrasyonu para taşır; onu diğer ödeme kodlarınız kadar ciddiye alın:

  • API secret ve webhook secret yalnızca sunucuda kalsın; ön yüz koduna ya da mobil uygulamaya asla koymayın.
  • Paneldeki IP izin listesiyle API erişimini kısıtlayın.
  • Kısa bir zaman penceresi dışındaki istekleri reddedin.
  • Fatura süresini stok rezervasyon mantığınıza göre ayarlayın.
  • Tutarları float değil, metin ya da ondalık tip olarak işleyin.
İpucu: canlıya almadan önce küçük bir faturayı kendiniz ödeyin, eksik ödeme akışını görmek için bilerek az tutar gönderin ve bir faturanın süresinin dolmasını bekleyin. Bir saatten kısa sürede tüm dalları test etmiş olursunuz.

Sonraki adımlar

Kripto ödeme API entegrasyonunun tamamı bu kadar: tek imzalı istek, tek doğrulanmış webhook ve bir durum haritası. Aynı akışın yazılımcı olmayanlara yönelik anlatımı için web sitesinde kripto ödeme alma yazısını okuyun. Web sitesi yerine bot mu geliştiriyorsunuz? Telegram botunda kripto ödeme alma rehberine göz atın. API anahtarları için Telegram @mistnetwork üzerinden başvurun, geliştirici bölümündeki örneği inceleyin ve anahtarlarınızı merchant girişi sonrası panelden yönetin.

Türkiye notu: TCMB'nin 2021 yönetmeliği kripto varlıkların ödemelerde kullanımını kısıtlıyor; Türkiye'de yerleşik işletmeler entegrasyondan önce hukuki durumu netleştirmeli.

Sık sorulan sorular

Kripto ödeme API entegrasyonu için SDK gerekir mi?
mistKET'te hayır. Düz HTTPS ve JSON kullanılır; HTTP isteği atıp HMAC-SHA256 hesaplayabilen her dil entegre olabilir.
mistKET API istekleri nasıl doğrulanır?
Her istek X-Api-Key, X-Api-Timestamp ve X-Api-Signature başlıklarını taşır; imza, '{timestamp}.{ham gövde}' metninin API secret ile alınmış HMAC-SHA256 değerinin hex hâlidir.
Kripto ödeme webhook'u nasıl doğrulanır?
'{timestamp}.{ham gövde}' metninin webhook secret ile HMAC-SHA256 değerini yeniden hesaplayın, X-Mistket-Signature ile sabit zamanlı karşılaştırın ve eski zaman damgalarını reddedin.
Sunucum bir webhook'u kaçırırsa ne olur?
Webhook'lar saatlerce artan aralıklarla yeniden denenir; fatura durumunu API'den de sorgulayabilirsiniz. Karşılayıcıyı sipariş numarasına göre idempotent yapın.
API ile belirli bir ağı zorunlu tutabilir miyim?
Evet. Ağı API çağrısında sabitleyebilirsiniz; aksi hâlde müşteri ödeme sayfasında seçer.
Sipariş hangi olayda teslim edilmeli?
invoice.confirmed geldiğinde teslim edin. invoice.paid yalnızca ilerlemeyi göstermek içindir; eksik, fazla ve süresi dolan ödemeleri politikanıza göre yönetin.

İlgili yazılar