Geliştirici Dokümantasyonu

<p><strong>Kalkhan API</strong>, lisans doğrulama, aktivasyon ve bayi entegrasyonu işlemlerini kendi sistemleriniz üzerinden yürütmenizi sağlar. Bu doküman uç noktaların istek/yanıt yapısını, kimlik doğrulama yöntemini ve hata kodlarını açıklar.</p> <h2 id="genel-bakis" style="scroll-margin-top:120px;">Genel Bakış</h2> <p>Kalkhan API, kaynak odaklı bir <strong>REST</strong> arayüzüdür. Tüm istek ve yanıt gövdeleri <strong>JSON</strong> formatında ve <strong>UTF-8</strong> karakter kodlamasıyla iletilir. Bağlantılar <strong>TLS 1.2 ve üzeri</strong> ile şifrelenmek zorundadır; şifresiz (HTTP) istekler kabul edilmez.</p> <div class="table-responsive"> <table class="table" style="background:#ffffff;"> <tbody> <tr><th scope="row" style="width:32%;">Base URL</th><td><code>https://api.kalkhan.com.tr/v1</code></td></tr> <tr><th scope="row">Protokol</th><td>HTTPS / TLS 1.2+ (zorunlu)</td></tr> <tr><th scope="row">Veri formatı</th><td>JSON · <code>Content-Type: application/json; charset=utf-8</code></td></tr> <tr><th scope="row">Karakter kodlaması</th><td>UTF-8</td></tr> <tr><th scope="row">Tarih formatı</th><td>ISO 8601 (UTC), örn. <code>2027-07-23T00:00:00Z</code></td></tr> <tr><th scope="row">Hız sınırı</th><td>Dakikada 120 istek (anahtar başına)</td></tr> </tbody> </table> </div> <p>Tüm uç nokta adresleri base URL ile birleştirilerek kullanılır. Örneğin lisans doğrulama uç noktasının tam adresi <code>https://api.kalkhan.com.tr/v1/licenses/verify</code> şeklindedir.</p> <h2 id="kurulum" style="scroll-margin-top:120px;">Kurulum &amp; Başlangıç</h2> <p>Entegrasyona sıfırdan başlıyorsanız aşağıdaki adımları sırasıyla uygulayın. Tüm süreç ortalama <strong>15 dakika</strong> sürer ve sunucu tarafında herhangi bir Kalkhan yazılımı kurmanızı gerektirmez — yalnızca HTTPS istek gönderebilen bir ortam yeterlidir.</p> <h3 style="margin-top:26px;">Ön koşullar</h3> <ul> <li>Onaylanmış bir <strong>Kalkhan bayi hesabı</strong> (başvuru: <a href="/iletisim">iletişim formu</a>)</li> <li>TLS 1.2 veya üzeri destekleyen bir sunucu ortamı (PHP 7.4+, Node.js 16+, .NET 6+, Python 3.8+ vb.)</li> <li>API anahtarını <em>sunucu tarafında</em> saklayabileceğiniz bir yapılandırma yöntemi (ortam değişkeni önerilir)</li> </ul> <h3 style="margin-top:26px;">Adım adım kurulum</h3> <ol> <li style="margin-bottom:10px;"><strong>Bayi panelinize giriş yapın.</strong> Hesabınız yönetici onayından geçtikten sonra panel erişiminiz açılır.</li> <li style="margin-bottom:10px;"><strong>API anahtarı üretin.</strong> Panelde &ldquo;API Anahtarları&rdquo; bölümünden önce <code>klk_test_</code> ön ekli bir test anahtarı oluşturun.</li> <li style="margin-bottom:10px;"><strong>Ortam değişkenlerini tanımlayın.</strong> Anahtarı ve base URL&rsquo;i uygulamanızın yapılandırmasına ekleyin (aşağıdaki örnek).</li> <li style="margin-bottom:10px;"><strong>İlk isteği gönderin.</strong> Bağlantıyı doğrulamak için sağlık uç noktasını çağırın.</li> <li style="margin-bottom:10px;"><strong>Webhook adresinizi kaydedin.</strong> Lisans olaylarını anlık almak için panelden HTTPS webhook adresinizi tanımlayın.</li> <li><strong>Canlıya geçin.</strong> Testler tamamlanınca <code>klk_live_</code> anahtarına geçin; kod tarafında yalnızca anahtar değişir.</li> </ol> <h4 style="margin-top:22px;">1) Ortam yapılandırması</h4> <pre><code style="background:#0F2453;color:#e6edff;padding:18px;border-radius:10px;overflow-x:auto;font-size:14px;line-height:1.6;display:block;"># .env KALKHAN_API_URL=https://api.kalkhan.com.tr/v1 KALKHAN_API_KEY=klk_test_xxxxxxxxxxxxxxxx KALKHAN_WEBHOOK_SECRET=whsec_xxxxxxxxxxxx</code></pre> <h4 style="margin-top:22px;">2) Bağlantı testi</h4> <pre><code style="background:#0F2453;color:#e6edff;padding:18px;border-radius:10px;overflow-x:auto;font-size:14px;line-height:1.6;display:block;">curl -s https://api.kalkhan.com.tr/v1/ping \ -H "Authorization: Bearer $KALKHAN_API_KEY" # Başarılı yanıt { "ok": true, "env": "test", "dealer": "BYI-1001" }</code></pre> <div style="background:#eef3ff;border-left:4px solid #3F82FB;padding:16px 18px;border-radius:8px;margin:22px 0;"> <strong>İpucu:</strong> Test ortamında oluşturulan lisanslar gerçek faturalandırmaya girmez ve istediğiniz zaman silinebilir. Entegrasyonu canlıya almadan önce lisans oluşturma, doğrulama ve iptal akışlarının tamamını test anahtarıyla deneyin. </div> <h2 id="kimlik-dogrulama" style="scroll-margin-top:120px;">Kimlik Doğrulama</h2> <p>API istekleri <strong>Bearer</strong> şemasıyla, API anahtarınız kullanılarak yetkilendirilir. Anahtarı her isteğin <code>Authorization</code> başlığında göndermeniz gerekir.</p> <pre><code style="background:#0F2453;color:#e6edff;padding:18px;border-radius:10px;overflow-x:auto;font-size:14px;line-height:1.6;display:block;">Authorization: Bearer klk_live_xxx Content-Type: application/json; charset=utf-8 Accept: application/json</code></pre> <p>API anahtarınızı <strong>bayi panelinizdeki</strong> &ldquo;API Anahtarları&rdquo; bölümünden oluşturabilir ve iptal edebilirsiniz. Test ortamı için <code>klk_test_</code>, canlı ortam için <code>klk_live_</code> ön ekli anahtarlar kullanılır.</p> <p><strong>Güvenlik notu:</strong> API anahtarı gizli bir kimlik bilgisidir; yalnızca sunucu tarafında saklayın. Tarayıcı, mobil uygulama paketi veya herkese açık kod deposu içine gömmeyin. Anahtarın sızdığından şüphelenirseniz panelden hemen iptal edip yenisini oluşturun.</p> <h2 id="lisans-dogrulama" style="scroll-margin-top:120px;">Lisans Doğrulama</h2> <p>Bir lisans anahtarının geçerliliğini, ürününü ve kalan süresini sorgulamak için kullanılır. Lisans anahtarları <code>KLKN-XXXX-XXXX-XXXX-XXXX</code> biçimindedir.</p> <div class="table-responsive"> <table class="table" style="background:#ffffff;"> <thead> <tr><th>Metot</th><th>Uç nokta</th><th>Yetki</th></tr> </thead> <tbody> <tr><td><strong>POST</strong></td><td><code>/licenses/verify</code></td><td>Bearer API anahtarı</td></tr> </tbody> </table> </div> <h3>İstek</h3> <pre><code style="background:#0F2453;color:#e6edff;padding:18px;border-radius:10px;overflow-x:auto;font-size:14px;line-height:1.6;display:block;">POST /v1/licenses/verify HTTP/1.1 Host: api.kalkhan.com.tr Authorization: Bearer klk_live_xxx Content-Type: application/json; charset=utf-8 { "key": "KLKN-4F2A-9C71-B3D8-A15E", "deviceId": "WIN-8f2c41ab9d", "productId": "kalkhan-av-windows" }</code></pre> <h3>Yanıt (200 OK)</h3> <pre><code style="background:#0F2453;color:#e6edff;padding:18px;border-radius:10px;overflow-x:auto;font-size:14px;line-height:1.6;display:block;">{ "key": "KLKN-4F2A-9C71-B3D8-A15E", "status": "active", "product": "Kalkhan Anti-Virüs (Windows)", "edition": "business", "seats": 25, "seatsUsed": 11, "expiresAt": "2027-03-14T23:59:59Z" }</code></pre> <div class="table-responsive"> <table class="table" style="background:#ffffff;"> <thead> <tr><th style="width:24%;">Alan</th><th style="width:18%;">Tip</th><th>Açıklama</th></tr> </thead> <tbody> <tr><td><code>status</code></td><td>string</td><td><code>active</code>, <code>expired</code>, <code>suspended</code> veya <code>cancelled</code></td></tr> <tr><td><code>product</code></td><td>string</td><td>Lisansın ait olduğu ürünün görünen adı</td></tr> <tr><td><code>edition</code></td><td>string</td><td><code>home</code>, <code>business</code> veya <code>enterprise</code></td></tr> <tr><td><code>seats</code></td><td>integer</td><td>Lisansın kapsadığı toplam cihaz sayısı</td></tr> <tr><td><code>expiresAt</code></td><td>string</td><td>ISO 8601 biçiminde bitiş tarihi (UTC)</td></tr> </tbody> </table> </div> <p>Geçersiz veya sistemde bulunmayan bir anahtar için <code>404 not_found</code>, biçimi hatalı bir anahtar için <code>400 invalid_request</code> döner.</p> <h2 id="lisans-olusturma" style="scroll-margin-top:120px;">Lisans Oluşturma (Bayi)</h2> <p>Yetkili bayilerin son kullanıcı adına yeni lisans üretmesi için kullanılır. Bu uç nokta yalnızca bayi yetkisine sahip API anahtarlarıyla çağrılabilir.</p> <div class="table-responsive"> <table class="table" style="background:#ffffff;"> <thead> <tr><th>Metot</th><th>Uç nokta</th><th>Yetki</th></tr> </thead> <tbody> <tr><td><strong>POST</strong></td><td><code>/licenses</code></td><td>Bayi API anahtarı</td></tr> </tbody> </table> </div> <h3>İstek</h3> <pre><code style="background:#0F2453;color:#e6edff;padding:18px;border-radius:10px;overflow-x:auto;font-size:14px;line-height:1.6;display:block;">POST /v1/licenses HTTP/1.1 Host: api.kalkhan.com.tr Authorization: Bearer klk_live_xxx Content-Type: application/json; charset=utf-8 { "productId": "kalkhan-av-windows", "edition": "business", "seats": 25, "customer": { "name": "Örnek Bilişim A.Ş.", "email": "muhasebe@ornekbilisim.com.tr", "taxId": "1234567890", "taxOffice": "Ümraniye", "address": "Mithatpaşa Cd. No:116, Ümraniye/İstanbul" } }</code></pre> <h3>Yanıt (201 Created)</h3> <pre><code style="background:#0F2453;color:#e6edff;padding:18px;border-radius:10px;overflow-x:auto;font-size:14px;line-height:1.6;display:block;">{ "key": "KLKN-7B10-CE45-2F93-D8A6", "status": "active", "product": "Kalkhan Anti-Virüs (Windows)", "edition": "business", "seats": 25, "amount": 34750.00, "currency": "TRY", "expiresAt": "2027-07-23T23:59:59Z" }</code></pre> <p><strong>Kurumsal satışlarda</strong> (<code>edition</code> değeri <code>business</code> veya <code>enterprise</code> olduğunda) fatura düzenlenebilmesi için <code>customer.taxId</code> (vergi kimlik numarası), <code>customer.taxOffice</code> (vergi dairesi) ve <code>customer.address</code> alanlarının gönderilmesi <strong>zorunludur</strong>. Bu alanlar eksik gönderildiğinde istek <code>400 invalid_request</code> ile reddedilir. Bireysel (<code>home</code>) lisanslarda vergi alanları isteğe bağlıdır.</p> <p>Aynı müşteri ve ürün için kısa süre içinde tekrarlanan istekler <code>409 duplicate</code> ile yanıtlanır; mükerrer lisans üretimini önlemek için isteğinize <code>Idempotency-Key</code> başlığı eklemeniz önerilir.</p> <h2 id="bayi-api" style="scroll-margin-top:120px;">Bayi API</h2> <p>Bayilerin kendi lisans portföyünü ve satış özetini sorgulaması için iki uç nokta sunulur.</p> <div class="table-responsive"> <table class="table" style="background:#ffffff;"> <thead> <tr><th style="width:14%;">Metot</th><th style="width:32%;">Uç nokta</th><th>Açıklama</th></tr> </thead> <tbody> <tr><td><strong>GET</strong></td><td><code>/dealer/licenses</code></td><td>Bayiye ait lisansların sayfalanmış listesi</td></tr> <tr><td><strong>GET</strong></td><td><code>/dealer/stats</code></td><td>Satış adedi, ciro ve yaklaşan yenileme özeti</td></tr> </tbody> </table> </div> <h3>Sayfalama parametreleri</h3> <div class="table-responsive"> <table class="table" style="background:#ffffff;"> <thead> <tr><th style="width:18%;">Parametre</th><th style="width:16%;">Varsayılan</th><th>Açıklama</th></tr> </thead> <tbody> <tr><td><code>page</code></td><td>1</td><td>Görüntülenecek sayfa numarası (1&rsquo;den başlar)</td></tr> <tr><td><code>limit</code></td><td>25</td><td>Sayfa başına kayıt sayısı (en fazla 100)</td></tr> <tr><td><code>status</code></td><td>&mdash;</td><td>İsteğe bağlı filtre: <code>active</code>, <code>expired</code>, <code>cancelled</code></td></tr> </tbody> </table> </div> <h3>İstek ve yanıt</h3> <pre><code style="background:#0F2453;color:#e6edff;padding:18px;border-radius:10px;overflow-x:auto;font-size:14px;line-height:1.6;display:block;">GET /v1/dealer/licenses?page=2&amp;limit=25&amp;status=active HTTP/1.1 Host: api.kalkhan.com.tr Authorization: Bearer klk_live_xxx { "data": [ { "key": "KLKN-4F2A-9C71-B3D8-A15E", "status": "active", "product": "Kalkhan Anti-Virüs (Windows)", "edition": "business", "seats": 25, "customer": "Örnek Bilişim A.Ş.", "expiresAt": "2027-03-14T23:59:59Z" } ], "pagination": { "page": 2, "limit": 25, "total": 143, "totalPages": 6 } }</code></pre> <p><code>GET /dealer/stats</code> uç noktası ise dönemsel özet döndürür: toplam aktif lisans sayısı, aylık satış adedi, toplam ciro ve önümüzdeki 30 gün içinde süresi dolacak lisans sayısı.</p> <h2 id="webhooks" style="scroll-margin-top:120px;">Webhooks</h2> <p>Lisans yaşam döngüsündeki değişiklikleri sistemlerinize anlık olarak iletmek için webhook kullanabilirsiniz. Hedef adresinizi bayi panelinden tanımlarsınız; Kalkhan bu adrese <code>POST</code> isteğiyle JSON gövde gönderir.</p> <div class="table-responsive"> <table class="table" style="background:#ffffff;"> <thead> <tr><th style="width:34%;">Olay</th><th>Ne zaman tetiklenir?</th></tr> </thead> <tbody> <tr><td><code>license.created</code></td><td>Yeni bir lisans oluşturulduğunda</td></tr> <tr><td><code>license.expired</code></td><td>Lisansın geçerlilik süresi dolduğunda</td></tr> <tr><td><code>license.cancelled</code></td><td>Lisans iptal edildiğinde veya iade işlendiğinde</td></tr> </tbody> </table> </div> <h3>Örnek olay gövdesi</h3> <pre><code style="background:#0F2453;color:#e6edff;padding:18px;border-radius:10px;overflow-x:auto;font-size:14px;line-height:1.6;display:block;">POST /webhooks/kalkhan HTTP/1.1 X-Kalkhan-Signature: t=1784937600,v1=9f8c1d2b7e4a63f05c8b1a9d4e7f2c30b6a5d8e1f4c7b0a3d6e9f2c5b8a1d4e7 Content-Type: application/json; charset=utf-8 { "id": "evt_01J9X2K7QF", "event": "license.created", "createdAt": "2026-07-23T09:41:02Z", "data": { "key": "KLKN-7B10-CE45-2F93-D8A6", "product": "Kalkhan Anti-Virüs (Windows)", "edition": "business", "seats": 25, "expiresAt": "2027-07-23T23:59:59Z" } }</code></pre> <h3>İmza doğrulama</h3> <p>Her webhook isteği <code>X-Kalkhan-Signature</code> başlığı ile imzalanır. İmza, zaman damgası ve ham istek gövdesinin <strong>HMAC-SHA256</strong> ile webhook gizli anahtarınız kullanılarak hesaplanmış özetidir. İsteği işlemeden önce imzayı mutlaka doğrulayın ve 5 dakikadan eski zaman damgalarını reddedin.</p> <pre><code style="background:#0F2453;color:#e6edff;padding:18px;border-radius:10px;overflow-x:auto;font-size:14px;line-height:1.6;display:block;">// Node.js — imza doğrulama const crypto = require('crypto'); function dogrula(rawBody, header, secret) { const parts = Object.fromEntries( header.split(',').map(p =&gt; p.split('=')) ); const beklenen = crypto .createHmac('sha256', secret) .update(parts.t + '.' + rawBody) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(beklenen), Buffer.from(parts.v1) ); }</code></pre> <p>Sunucunuz <code>2xx</code> yanıt döndürmezse olay, artan aralıklarla (1 dk, 5 dk, 30 dk, 2 sa, 12 sa) en fazla 5 kez yeniden gönderilir. Aynı olayın birden fazla kez ulaşabileceğini varsayarak <code>id</code> alanına göre tekrar denetimi yapın.</p> <h2 id="hata-kodlari" style="scroll-margin-top:120px;">Hata Kodları</h2> <p>Hatalar standart HTTP durum kodlarıyla döner ve gövdede makine tarafından okunabilir bir <code>code</code> ile açıklayıcı bir <code>message</code> içerir.</p> <div class="table-responsive"> <table class="table" style="background:#ffffff;"> <thead> <tr><th style="width:14%;">HTTP</th><th style="width:26%;">Kod</th><th>Açıklama</th></tr> </thead> <tbody> <tr><td><strong>400</strong></td><td><code>invalid_request</code></td><td>Eksik veya biçimi hatalı parametre gönderildi</td></tr> <tr><td><strong>401</strong></td><td><code>unauthorized</code></td><td>API anahtarı yok, geçersiz veya iptal edilmiş</td></tr> <tr><td><strong>403</strong></td><td><code>forbidden</code></td><td>Anahtarın bu uç nokta için yetkisi bulunmuyor</td></tr> <tr><td><strong>404</strong></td><td><code>not_found</code></td><td>İstenen lisans veya kaynak bulunamadı</td></tr> <tr><td><strong>409</strong></td><td><code>duplicate</code></td><td>Kayıt zaten mevcut; mükerrer istek engellendi</td></tr> <tr><td><strong>429</strong></td><td><code>rate_limited</code></td><td>Hız sınırı aşıldı; <code>Retry-After</code> başlığını bekleyin</td></tr> <tr><td><strong>500</strong></td><td><code>server_error</code></td><td>Sunucu tarafında beklenmeyen bir hata oluştu</td></tr> </tbody> </table> </div> <h3>Örnek hata yanıtı</h3> <pre><code style="background:#0F2453;color:#e6edff;padding:18px;border-radius:10px;overflow-x:auto;font-size:14px;line-height:1.6;display:block;">HTTP/1.1 400 Bad Request Content-Type: application/json; charset=utf-8 { "error": { "code": "invalid_request", "message": "customer.taxId alanı kurumsal lisanslar için zorunludur.", "field": "customer.taxId", "requestId": "req_01J9X2K7QF" } }</code></pre> <p>Destek talebi oluştururken yanıttaki <code>requestId</code> değerini paylaşmanız, sorunun hızlıca incelenmesini sağlar.</p> <h2 id="sdk" style="scroll-margin-top:120px;">SDK &amp; Örnekler</h2> <p>Resmî SDK&rsquo;lar hazırlanma aşamasındadır. Bu süreçte API&rsquo;yi doğrudan HTTP üzerinden çağırabilirsiniz. Aşağıda lisans doğrulama isteğinin cURL ve JavaScript karşılıkları yer alıyor.</p> <h3>cURL</h3> <pre><code style="background:#0F2453;color:#e6edff;padding:18px;border-radius:10px;overflow-x:auto;font-size:14px;line-height:1.6;display:block;">curl -X POST https://api.kalkhan.com.tr/v1/licenses/verify \ -H "Authorization: Bearer klk_live_xxx" \ -H "Content-Type: application/json; charset=utf-8" \ -d '{ "key": "KLKN-4F2A-9C71-B3D8-A15E", "deviceId": "WIN-8f2c41ab9d", "productId": "kalkhan-av-windows" }'</code></pre> <h3>JavaScript (fetch)</h3> <pre><code style="background:#0F2453;color:#e6edff;padding:18px;border-radius:10px;overflow-x:auto;font-size:14px;line-height:1.6;display:block;">const API_KEY = process.env.KALKHAN_API_KEY; // sunucu tarafında saklayın async function lisansDogrula(key, deviceId) { const res = await fetch( 'https://api.kalkhan.com.tr/v1/licenses/verify', { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json; charset=utf-8' }, body: JSON.stringify({ key, deviceId, productId: 'kalkhan-av-windows' }) } ); if (!res.ok) { const { error } = await res.json(); throw new Error(`${error.code}: ${error.message}`); } return res.json(); // { status, product, edition, seats, expiresAt } } lisansDogrula('KLKN-4F2A-9C71-B3D8-A15E', 'WIN-8f2c41ab9d') .then(lisans =&gt; console.log(lisans.status, lisans.expiresAt)) .catch(err =&gt; console.error('Doğrulama başarısız:', err.message));</code></pre> <p>Bu örnekler yalnızca sunucu tarafı kullanım içindir. API anahtarını tarayıcıda çalışan koda yerleştirmeyin; istemci uygulamalarınızdan gelen doğrulama isteklerini kendi arka uç servisiniz üzerinden geçirin.</p> <!-- Uyarı Kutusu Start --> <div role="note" style="margin-top:40px;background:#FFF8E6;border:1px solid #F0D28A;border-left:5px solid #C9A227;border-radius:12px;padding:22px 24px;display:flex;gap:16px;align-items:flex-start;"> <span style="flex:0 0 auto;color:#C9A227;font-size:22px;line-height:1.2;"><i class="fa-solid fa-triangle-exclamation" aria-hidden="true"></i></span> <span style="color:#4a3d12;font-size:15px;line-height:1.7;"> <strong style="display:block;color:#0F2453;font-size:16px;margin-bottom:4px;">Kapalı beta</strong> API şu anda kapalı beta aşamasındadır; erişim için <a href="mailto:bilgi@kalkhan.com.tr" style="color:#0F2453;font-weight:600;">bilgi@kalkhan.com.tr</a> adresinden başvurun. Beta süresince uç noktalarda geriye dönük uyumsuz değişiklikler yapılabilir. </span> </div> <!-- Uyarı Kutusu End -->