Webhooklar: olaylar, imzalar ve teslimat
Genel bir HTTPS uç noktası kaydedin, kontrolü kanıtlayın ve imzalı fatura ve ödeme olaylarını alın. Teslimat kalıcı olarak kuyruğa alınır; aynı olayı tekrar işlemek siparişiniz için güvenli olmalıdır.
Bu sayfada
Olaylar nereden gelir#
invoice.created ödendiği anlamına gelmez. Ödeme olayları, geçerli bir ağ geçidi okumasından sonra doğrulanmış bir sunucu işleminden gelir; yalnızca gelen bir olay adı yetersizdir.
Ağ geçidi → Kevmi girişi ve Kevmi → tüccar teslimatı, ayrı sırlara sahip farklı bacaklardır. Tarayıcı, geri dönüş navigasyonu ve araç pencere öğesi mesajları finansal durum belirlemez.
| Olay | Kaynak |
|---|---|
| invoice.created | Fatura kaydedildi |
| invoice.updated | Bağlantı kullanılabilirliği değişti |
| payment.succeeded | Sunucu tarafından doğrulanmış kesin ödeme |
| payment.failed | Başarısız işlem doğrulandı |
| payment.refunded | Tam iade doğrulandı |
| payment.partially_refunded | Kısmi iade doğrulandı |
| payment.disputed | İtiraz doğrulandı |
| payment.review_required | İşlem ek inceleme gerektirir |
Bir uç nokta kaydedin ve doğrulayın#
URL'ler IP adreslerini, localhost'u, özel ağları, standart dışı bağlantı noktalarını hedefleyemez veya kimlik bilgileri içeremez. DNS teslimattan önce kontrol edilir; giden POST istekleri yönlendirmeleri takip etmez. Bir hesap en fazla beş uç nokta kaydedebilir.
Doğrulama olayı livemode=false değerine sahiptir. Yalnızca başarılı bir HTTP durumu yetersizdir: meydan okuma tam olarak eşleşmelidir. Sırrı döndürmek yeniden doğrulama gerektirir.
- 1
Tüccar hesabınızda /account#webhooks adresinde genel bir HTTPS URL, açıklama ve ihtiyacınız olan olay türlerini girin.
- 2
Verilen sırrı sunucu tarafı depolamada saklayın. Tam değeri yalnızca bir kez gösterilir.
- 3
İmzaları orijinal istek baytları üzerinde doğrulayın.
- 4
Uç nokta doğrulamasını çalıştırın. endpoint.verification için, data.challenge değerini yansıtan JSON döndürün: {"challenge":"alınan değer"}.
- 5
Doğrulanmış uç noktayı etkinleştirin ve teslimat geçmişini inceleyin.
Olay zarfı#
id, bir olayın her teslimat denemesinde aynı kalır. createdAt, milisaniye cinsinden bir Unix zaman damgasıdır ve apiVersion sözleşme sürümünü tanımlar. data, kalıcı sunucu nesnesini içerir; örnek kısaltılmıştır.
livemode=true, gerçek bir sunucu olayını uç nokta doğrulamasından ayırır. Bir faturanın ödendiği anlamına gelmez: type ve ödeme verilerini kontrol edin. Bilinen olay türlerini işleyin ve şemayı doğrulayın.
{
"id": "evt_example",
"type": "invoice.created",
"apiVersion": "2026-10-21",
"createdAt": 1792540800000,
"livemode": true,
"data": {
"invoice": {
"id": "lnk_example",
"orderId": "order-1042",
"currency": "USD",
"amountMinor": 500,
"vatCustomerPercent": 100,
"feeCustomerPercent": 0
}
}
}HMAC-SHA256 doğrulayın#
Kevmi-Signature, t=saniye,v1=hex içerir. İmza, zaman damgası dizesi, bir nokta ve orijinal gövde üzerinde HMAC-SHA256'dır: timestamp + "." + rawBody. Belirli uç nokta sırrını ve sabit zamanlı bir karşılaştırmayı kullanın.
Zaman damgası sunucu saatinden her iki yönde de 300 saniyeden fazla farklı olan imzaları reddedin. Saatleri senkronize edin. Doğrulamadan önce JSON'u ayrıştırıp yeniden serileştirmeyin: boşluk ve özellik sırası imzalanan baytları etkiler.
import { createHmac, timingSafeEqual } from 'node:crypto';
function verifyKevmi(rawBody, header, secret, nowSeconds) {
const match = /^t=(\d{10}),v1=([a-f0-9]{64})$/.exec(header || '');
if (!match || Math.abs(nowSeconds - Number(match[1])) > 300) {
return false;
}
const expected = createHmac('sha256', secret)
.update(match[1] + '.')
.update(rawBody)
.digest();
const received = Buffer.from(match[2], 'hex');
return expected.length === received.length
&& timingSafeEqual(expected, received);
}
// Read bytes before JSON parsing; cap the request body.
// secret comes from your server secret store.
const valid = verifyKevmi(rawBody, signature, secret,
Math.floor(Date.now() / 1000));
if (!valid) throw new Error('Invalid webhook signature');
const event = JSON.parse(rawBody.toString('utf8'));
// Validate the event schema and persist its ID together
// with your order update in one database transaction.
// Return a 2xx response after durable acceptance.Yeniden denemeler ve onay#
Herhangi bir 2xx yanıtı, sıradan bir olayı onaylar. Yanıt vermeden önce olayı kalıcı olarak saklayın; pahalı işler kendi kuyruğunuz üzerinden devam edebilir. Yanıt zaman aşımı sekiz saniyedir. Bir ağ hatası veya 2xx olmayan yanıt, yeniden deneme planlar.
En fazla altı deneme vardır: ilk teslimat artı ardışık başarısızlıklardan sonra bir dakika, beş dakika, 30 dakika, iki saat ve 12 saatlik gecikmeler. Bunlar kuyruk programlarıdır, kesin teslimat süresi garantisi değildir. Denemelerin tükenmesi teslimatı başarısız olarak işaretler.
Teslimat en az bir kezdir ve kesin sıralama vaat etmez. Benzersiz olay kimliğini sipariş güncellemenizle aynı işlemde saklayın. Zaten uygulanmış bir kopya, siparişi yeniden yerine getirmeden 2xx almalıdır.
Manuel bir yeniden deneme, orijinal olay kimliğini, teslimat kimliğini ve birebir gövdeyi koruyarak teslimat denemelerini yeniden başlatır. Her deneme yeni bir imza zaman damgası alır. Bir uç noktayı duraklatmak kuyruğunu korur; silmek bekleyen ve başarısız teslimatları iptal eder.
Teslimat geçmişi ve mutabakat#
Arayüz, uç nokta durumunu, son teslimatları, deneme sayılarını, son HTTP yanıtını, hatayı ve sonraki deneme zamanını gösterir. Bu tanılamalar kendi sipariş kayıtlarınızı tamamlar.
GET /api/v1/events, events:read ile en fazla 50 olay ve nextCursor döndürür. Opak nextCursor'u değiştirmeden cursor olarak iletin; null sonu işaretler. Sıralama hem createdAt hem de id kullanır. Eski before Unix-milisaniye sınırı ayrı olarak kullanılabilir ve cursor ile birleştirilemez. Doğrulanmış uç noktalar, kayıtlarından daha önce abone olunan olayları almaz; duraklatılmış uç noktalar, devam ettirildikten sonra teslimat için kuyruğa alınmış olayları biriktirmeye devam eder. Bu, uç nokta oluşturulmadan önceki geçmişi vaat etmez.
Gelen ağ geçidi makbuz kontrolleri#
Gateway v3, /api/gateway/webhook adresine X-Gateway-Event-Id, X-Gateway-Timestamp ve X-Gateway-Signature: v1=<hex> ile gönderim yapar. HMAC-SHA256, timestamp + "." + rawBody'yi GATEWAY_WEBHOOK_SECRET ile imzalar; saat penceresi 300 saniyedir. Başlık/gövde kimlik eşitliği, API sürümü, canlı mod ve gövde karması kontrol edilir.
Farklı gövde baytlarıyla yeniden kullanılan bir olay kimliği reddedilir. İmzalı bir bildirim, tam işlemin kimliği doğrulanmış bir GET isteğini tetikler. Sipariş, yöntem, para birimi, taban, onaylanan toplam ve sürüm kontrol edilir. Başarı için fulfillment_ready=true, verification=provider_confirmed, tam ödenen tutar ve anlaşmazlık olmaması gerekir; kripto ayrıca doğrulanmış mutabakat kanıtı gerektirir.
Giriş işleme, makbuzlar ve tüccar olayları kopyalara karşı korunur. Eski tarayıcı tabanlı bildirim biçimleri başarılı ödeme sağlayamaz. Tüccar webhook'ları asla kart alanları, banka kodları, QR verileri, sağlayıcı kimlik bilgileri veya ağ geçidi sırrını içermez.
Telegram'ın ayrı bir sözleşmesi vardır#
POST /api/telegram/webhook, X-Telegram-Bot-Api-Secret-Token'ı, güncelleme yapısını ve göndereni doğrular. update_id, yinelenen işlemeye karşı korur. Bu rota oturum açma, komutlar, destek ve moderasyon eylemlerini işler; mali makbuzları kabul etmez.
Dağıtım sahibi, bot jetonunu, webhook sırrını, setWebhook kaydını ve erişilebilir HTTPS adresini yapılandırır. Bunlar, tüccar uç noktası imza sırrından ayrıdır.
Birden fazla mağaza ve tek USD taban fiyat#
Toplu analiz ve işlemler için Tüm mağazaları seçin veya kendi kayıtları için bir mağaza seçin. Her mağazanın ayrı bir storeId'si, adı, varsayılan KDV'si, faturaları, API anahtarları, webhook uç noktaları, olay geçmişi ve web sitesi uygulaması vardır. Bildirimler ve destek talepleri hesaba aittir. Bir hesap en fazla 100 mağaza oluşturabilir. Mevcut kayıtlar ilk mağazasında kalır.
Yeni çalışma alanı faturaları pricingMode="universal" ve USD taban fiyat kullanır. Any, kart, alipay, sbp ve kriptoyu içerir; bir satıcı bir alt küme seçebilir. Kartlar ve Alipay USD tahsil eder. SBP, Rusya Merkez Bankası USD/RUB referans kurunu kullanarak RUB tahsil eder. Kripto, açık fatura kuralı 1 USD = 1 USDT kapsamında USDT tahsil eder. Bu bir fatura dönüştürme kuralıdır, piyasa USDT kotasyonu değildir. Ağ geçidi, transferden önce seçilen coin'in kurunu, tam transfer tutarını ve talimatlarını sağlar.
Referans kuru ve her iki tutar oluşturma sırasında dondurulur. RUB dönüştürmesi içeren faturalar 24 saat içinde sona erer. Referans kuru alınamazsa, oluşturma FX_UNAVAILABLE ile başarısız olur; uydurulmuş veya bayat yedek kur kullanılmaz. Sahip yanıt tutarı ve kotasyonlar USD muhasebe para birimini kullanır. quotes[method].settlement, yerel tahsil kotasyonunu içerir. Genel ödeme sayfası, seçilen tahsil para birimini currency içinde, orijinal fiyatı baseAmountMinor/baseCurrency içinde ve referans kurunu fx içinde gösterir. Bir ödeme gönderildikten sonra yöntemi değiştirilemez; bir faturanın tek ağ geçidi işlemi vardır.
Amaçlanan mağaza içinde bir API anahtarı oluşturun ve sunucunuzdan Authorization: Bearer <key> gönderin. Mağaza bağlaması değişmezdir; X-Kevmi-Store, anahtara başka bir mağazaya erişim izni veremez. Tarayıcı oturumları X-Kevmi-Store: <storeId> seçer; atlanırsa ilk mağaza seçilir. all değeri yalnızca GET /api/account/dashboard ve GET /api/payment-links tarafından kabul edilir. Değişiklikler seçili bir mağaza, Origin ve X-CSRF-Token gerektirir. Hesap kimlikleri ve mağaza kimlikleri farklı tanımlayıcılardır.
Uyumluluk için, pricingMode="universal" içermeyen API istekleri yerel fiyatlandırmayı ve orijinal para birimi kısıtlamalarını korur. Mevcut faturalar asla yeniden hesaplanmaz. Analizlerdeki onaylanmış tahsilatlar, doğrulanmış ödemelerden kaydedilmiş fatura giderlerinin düşülmesiyle elde edilir; bunlar çekilebilir bakiye değildir. Eski fatura para birimleri ayrı kalır ve ödemeler destek ile düzenlenir. Bir siparişi yalnızca sunucu API'si, olay geçmişi veya imzalı bir webhook üzerinden payment.fulfillmentReady=true ve payment.status="succeeded" durumunu kontrol ettikten sonra yerine getirin.