API dokümantasyonu
REST + JSON. Fatura açın, müşteriyi ödeme sayfasına yönlendirin, sonucu imzalı webhook ile alın.
Başlarken
API anahtarı ve gizli anahtar (secret) mağaza panelinde API bölümünden oluşturulur; secret yalnızca bir kez gösterilir. Webhook adresi ve webhook gizli anahtarı da aynı sayfadan yönetilir. Mağaza hesabı açmak için Telegram'dan @mistnetwork adresine yazın.
Taban adres: https://mistket.com/api/v1
Kimlik doğrulama
Her istekte üç başlık gönderilir:
| Başlık | Değer |
|---|---|
| X-Api-Key | Panelden alınan anahtar (mp_live_…) |
| X-Api-Timestamp | Unix zaman damgası (saniye); sunucu saatinden en fazla ±300 sn sapabilir |
| X-Api-Signature | hex( HMAC-SHA256( "{timestamp}.{ham gövde}", API_SECRET ) ) |
İmzalanan metin, zaman damgası + nokta + isteğin ham gövdesidir (JSON'u imzaladığınız haliyle aynen gönderin). Gövdesiz isteklerde (GET ve gövdesiz POST) gövde boş string "" kabul edilir; sorgu parametreleri imzaya dahil değildir.
Tekrar oynatma koruması: veri değiştiren isteklerde (POST vb.) aynı imza ±5 dk içinde ikinci kez kabul edilmez. Her istekte zaman damgasını yeniden alıp imzayı yeniden hesaplayın.
İmza sürüm 2 (önerilen): X-Api-Signature-Version: 2 ve her istekte yeni bir X-Api-Nonce (8–64 karakter [A-Za-z0-9_-]) gönderin; imza hex( HMAC-SHA256( "{timestamp}.{nonce}.{METOT}.{yol?sorgu}.{ham gövde}", API_SECRET ) ) olur. Aynı nonce ±5 dk içinde ikinci kez kullanılamaz. Sürüm 1 çalışmaya devam eder.
Panelde IP kısıtlaması tanımladıysanız yalnızca o adreslerden gelen istekler kabul edilir.
Örnek istemci
function mistket(string $method, string $path, array $body = []): array
{
$key = getenv('MISTKET_KEY');
$secret = getenv('MISTKET_SECRET');
$payload = $body ? json_encode($body, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) : '';
$timestamp = (string) time();
$signature = hash_hmac('sha256', $timestamp.'.'.$payload, $secret);
$ch = curl_init('https://mistket.com/api/v1'.$path);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_POSTFIELDS => $payload !== '' ? $payload : null,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Api-Key: '.$key,
'X-Api-Timestamp: '.$timestamp,
'X-Api-Signature: '.$signature,
],
]);
return json_decode(curl_exec($ch), true);
}
$invoice = mistket('POST', '/invoices', [
'amount' => '49.90',
'currency' => 'USD',
'order_id' => 'ORDER-1001',
'callback_url' => 'https://example.com/webhook/mistket',
'success_url' => 'https://example.com/thanks',
]);
header('Location: '.$invoice['data']['checkout_url']);
import crypto from 'node:crypto';
async function mistket(method, path, body) {
const payload = body ? JSON.stringify(body) : '';
const ts = Math.floor(Date.now() / 1000).toString();
const sig = crypto.createHmac('sha256', process.env.MISTKET_SECRET)
.update(`${ts}.${payload}`).digest('hex');
const res = await fetch(`https://mistket.com/api/v1${path}`, {
method,
headers: {
'Content-Type': 'application/json',
'X-Api-Key': process.env.MISTKET_KEY,
'X-Api-Timestamp': ts,
'X-Api-Signature': sig,
},
body: payload || undefined,
});
return res.json();
}
const inv = await mistket('POST', '/invoices', { amount: '49.90', currency: 'USD', order_id: 'ORDER-1001' });
console.log(inv.data.checkout_url);
import hashlib, hmac, json, os, time, urllib.request
def mistket(method, path, body=None):
payload = json.dumps(body, separators=(",", ":")) if body else ""
ts = str(int(time.time()))
sig = hmac.new(os.environ["MISTKET_SECRET"].encode(),
f"{ts}.{payload}".encode(), hashlib.sha256).hexdigest()
req = urllib.request.Request(
"https://mistket.com/api/v1" + path,
data=payload.encode() if payload else None,
method=method,
headers={
"Content-Type": "application/json",
"X-Api-Key": os.environ["MISTKET_KEY"],
"X-Api-Timestamp": ts,
"X-Api-Signature": sig,
},
)
with urllib.request.urlopen(req) as r:
return json.load(r)
inv = mistket("POST", "/invoices", {"amount": "49.90", "currency": "USD", "order_id": "ORDER-1001"})
print(inv["data"]["checkout_url"])
Uç noktalar
| POST /invoices | Fatura oluştur |
| GET /invoices/{uuid} | Fatura durumunu sorgula |
| GET /invoices | Faturaları listele |
| POST /invoices/{uuid}/cancel | Açık faturayı iptal et |
| GET /assets | Desteklenen coin / ağ listesi |
| GET /rate | Kur ve ödenecek tutar |
| GET /health | Servis durumu (kimlik doğrulama gerekmez) |
POST/invoices — Fatura oluştur
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
| amount | string | ✓ | Tutar, ör. "49.90" (sıfırdan büyük) |
| currency | string | ✓ | Fiyat para birimi: USD, EUR, TRY, RUB, GBP, AED ya da doğrudan kripto sembolü (ör. USDT; ödenen varlıkla aynıysa birebir) |
| order_id | string | Kendi sipariş numaranız. Idempotency anahtarıdır: aynı order_id ile tekrar çağrılırsa yeni fatura açılmaz, mevcut fatura "idempotent": true ile döner. | |
| pay_currency network | string | Ağ önceden sabitlenecekse, ör. USDT + TRC20. Verilmezse müşteri ağı ödeme ekranında seçer (önerilen). | |
| asset_id | int | Alternatif: /assets yanıtındaki id | |
| callback_url | url | Bu faturanın webhook adresi (boşsa mağazanın varsayılan webhook adresi) | |
| success_url cancel_url | url | Ödeme sonrası / vazgeçince müşteri yönlendirmesi | |
| ttl_minutes | int | 5–1440 dakika; boşsa mağaza ayarı (varsayılan 60) | |
| description customer_email meta | Serbest alanlar (description ≤191 karakter, meta nesne) |
Başarılı yanıt 201; müşteriyi data.checkout_url adresine yönlendirin.
{
"success": true,
"data": {
"uuid": "9b1c…",
"order_id": "ORDER-1001",
"status": "new",
"price_amount": "49.90",
"price_currency": "USD",
"pay_amount": null,
"pay_currency": null,
"network": null,
"pay_address": null,
"checkout_url": "https://mistket.com/pay/9b1c…",
"expires_at": "2026-09-12T22:51:00+00:00",
"seconds_remaining": 3600
}
}
GET/invoices/{uuid} — Fatura durumunu sorgula
{
"success": true,
"data": {
"uuid": "9b1c…",
"status": "confirmed",
"pay_amount": "49.912345",
"paid_amount": "49.912345",
"remaining_amount": "0",
"pay_currency": "USDT",
"network": "TRC20",
"chain": "TRON",
"pay_address": "T…",
"confirmations": 21,
"required_confirmations": 19,
"is_underpaid": false,
"can_pay_remaining": false,
"under_review": false,
"checkout_url": "https://mistket.com/pay/9b1c…",
"transactions": [
{
"tx_hash": "f3a…",
"amount": "49.912345",
"confirmations": 21,
"status": "confirmed",
"explorer_url": "https://tronscan.org/#/transaction/f3a…"
}
]
}
}
GET/invoices — Faturaları listele
Sorgu parametreleri: status, order_id, per_page (en fazla 100), page. Yanıtta meta.current_page, meta.last_page, meta.total bulunur.
POST/invoices/{uuid}/cancel — Açık faturayı iptal et
Açık faturayı kapatır ve ödeme adresini havuza geri verir; invoice.cancelled webhook'u gönderilir.
GET/assets — Desteklenen coin / ağ listesi
Her kayıt: id, symbol, name, network, chain, contract, decimals, min_amount, confirmations, available. available: false → o ağda şu an boşta adres yok.
GET/rate?asset_id=1¤cy=USD&amount=100
Fatura açmadan kur ve ödenecek kripto miktarını gösterir. Parametreler: asset_id (zorunlu), currency (zorunlu), amount.
GET/health — Servis durumu (kimlik doğrulama gerekmez)
Fatura nesnesi
Tüm fatura yanıtları ve webhook gövdesindeki data aynı yapıdadır. Öne çıkan alanlar:
| status status_label | Durum (aşağıdaki tablo) ve müşteri diline göre etiketi |
| *_amount | pay_amount: ödenecek kripto tutar · paid_amount / received_amount: adrese ulaşan toplam · remaining_amount: kalan |
| pay_currency network chain pay_address | Ödeme varlığı, ağ, zincir kodu ve adres (ağ seçilene kadar null) |
| confirmations required_confirmations | Mevcut / gereken blok onayı |
| is_underpaid … | is_underpaid, can_pay_remaining (müşteri kalanı aynı adrese gönderebilir), under_review (süre kısmi ödemeyle doldu; manuel inceleme), expiry_extensions |
| transactions[] | Zincirde görülen işlemler: tx_hash, amount, confirmations, status, explorer_url, detected_at |
Fatura durumları
| new | Oluşturuldu, müşteri henüz ağ seçmedi |
| pending | Ağ seçildi, adres ve tutar kilitlendi; ödeme bekleniyor |
| underpaid | Beklenenden az geldi; kalan aynı adrese gönderilebilir (açıkken süre otomatik uzar) |
| paid | Tutar görüldü, blok onayı bekleniyor — siparişi henüz onaylamayın |
| confirmed | Ödendi ve onaylandı |
| overpaid | Beklenenden fazla ödendi ve onaylandı |
| expired | Süre doldu, ödeme tamamlanmadı |
| cancelled | İptal edildi |
Webhook
Fatura durumu her değiştiğinde faturanın callback_url adresine (yoksa mağazanın webhook adresine) JSON POST gönderilir.
Başlıklar
Content-Type: application/json
User-Agent: mistket-webhook/1.0
X-Mistket-Event: invoice.confirmed
X-Mistket-Timestamp: 1789456123
X-Mistket-Signature: sha256=<hex>
X-Mistket-Delivery: 4412
Gövde
{
"event": "invoice.confirmed",
"sent_at": "2026-09-12T21:55:03+00:00",
"data": { "uuid": "9b1c…", "order_id": "ORDER-1001", "status": "confirmed", "…": "…" }
}
Olaylar
invoice.pending, invoice.underpaid, invoice.paid, invoice.confirmed, invoice.overpaid, invoice.expired, invoice.cancelled
İmza doğrulama
İmza, webhook gizli anahtarınızla HMAC-SHA256( "{X-Mistket-Timestamp}.{ham gövde}" ) olarak hesaplanır ve sha256= önekiyle gönderilir. Ham gövdeyi JSON'a çevirmeden önce doğrulayın, karşılaştırmayı sabit zamanlı yapın ve eski zaman damgalarını reddedin.
$payload = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_MISTKET_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_MISTKET_SIGNATURE'] ?? '';
$expected = 'sha256='.hash_hmac('sha256', $timestamp.'.'.$payload, WEBHOOK_SECRET);
if (! hash_equals($expected, $signature) || abs(time() - (int) $timestamp) > 300) {
http_response_code(400);
exit('invalid signature');
}
$event = json_decode($payload, true);
if (in_array($event['event'], ['invoice.confirmed', 'invoice.overpaid'], true)) {
// fulfil the order: check data.order_id and data.paid_amount
}
http_response_code(200);
echo 'ok';
Siparişi yalnızca invoice.confirmed veya invoice.overpaid olayında onaylayın; invoice.paid “işlem görüldü, onay bekleniyor” demektir. Aynı olay birden fazla gelebilir; işleyiciniz tekrarlara dayanıklı olmalı (X-Mistket-Delivery ve uuid ile).
Yeniden deneme
2xx dışındaki yanıtlarda (veya 15 sn zaman aşımında) artan aralıklarla yeniden denenir: 10 sn · 30 sn · 2 dk · 10 dk · 30 dk · 1 sa · 2 sa · 3 sa — ardından teslimat failed olur. Panelde her faturanın gönderim geçmişi görülür.
Hatalar ve sınırlar
Hatalar success: false ve error mesajıyla döner. Doğrulama hatalarında alan bazlı ayrıntı da gelir.
{ "success": false, "error": "…", "errors": null }
| Kod | Anlamı |
|---|---|
| 401 | Anahtar eksik/geçersiz, imza hatalı veya zaman damgası pencere dışında |
| 403 | İstek IP'sine izin verilmiyor |
| 404 | Fatura bulunamadı (başka mağazanın faturası da 404 döner) |
| 422 | Doğrulama hatası, desteklenmeyen coin/ağ veya boşta adres yok |
| 429 | Hız sınırı: API anahtarı başına 120 istek / 1 dk |
| 503 | Kur sağlayıcısına ulaşılamadı; birkaç saniye sonra tekrar deneyin |
Entegrasyona hazır mısınız?
Mağaza hesabı açmak veya sorularınız için Telegram'dan yazın.
Telegram'dan yazın Mağaza girişi