Genel bakış
Vito API, uygulamanızın Discord içinden bir kullanıcının Vito bakiyesiyle çalışmasını sağlar — onu okumak, ondan tahsilat yapmak veya geri alacak yazmak. Kullanıcı, herhangi bir Vito hareket etmeden önce her tahsilatı vetox.io’da PIN’iyle onaylar ve uygulamanız sonuçtan haberdar edilir. Vito, Vetox ekosistemine ait sanal para birimidir; Vito tabanlı deneyimler oluşturmak için API’yi kullanın — içerik, özellik, ayrıcalık veya ödül kilidini açma. Gerçek parayla hiçbir alım veya satım gerçekleşmez.
Bu, gizli bir anahtarla kimlik doğrulayan bir REST API’dir. Tüm uç noktalar JSON döndürür ve /v1 altında sürümlenir.
https://api.vetox.io/public/vito/v1Bakiyeler ve mutabakat
API anahtarınız Vetox hesabınıza bağlıdır. Her tahsilat sizin lehinize mutabık kılınır: uygulamanız bir kullanıcıdan Vito düştüğünde, o Vito kendi bakiyenize (platform ücreti düşülerek) eklenir, asla yakılmaz. Uygulamanız bir kullanıcıya Vito eklediğinde, bu sizin bakiyenizden finanse edilir.
Vito her zaman bakiyeler arasında hareket eder — asla gerçek paradan veya gerçek paraya değil. Kullanıcıdan istediğiniz tutarın tamamı tahsil edilir; siz platform ücreti sonrası tutarı alırsınız; alacaklar ve ödüller /add ile bakiyenizden finanse edilir.
Gereksinimler
Vito API erişimi proje başına verilir. Onu çağırabilmeniz için şunlara ihtiyacınız var:
- Etkin bir Kullanıcı Üyeliği (Silver seviyesi veya üzeri). Sahibin üyeliği sona ererse API otomatik olarak dondurulur ve yeniden abone olunduğunda geri yüklenir.
- Onaylanmış bir geliştirici başvurusu. Bu sayfadan bir tane gönderin; Vetox ekibi manuel olarak inceler.
- Kabul edilen API Geliştirici Şartları — geliştirici başvurunuzu gönderdiğinizde onaylanır.
- Projenizin ihtiyaç duyduğu kapsamlar. Başvurunuza göre Vetox ekibi tarafından verilir.
Kullanılabilir kapsamlar
balance:readdeduct:createcredit:createtransfer:createtransactions:readKimlik doğrulama
Her isteği, Authorization başlığında Bearer belirteci olarak gizli API anahtarınızla doğrulayın. Anahtarlar vito_live_ önekini taşır.
Authorization: Bearer vito_live_xxxxxxxxxxxxxxxxİki isteğe bağlı katman projenizi daha da korur:
- IP izin listesi — istekleri belirli sunucu IP’leriyle kısıtlayın (Ayarlar sekmesinde yapılandırın).
- Hız sınırları — üyelik seviyenizle ölçeklenen proje başına istek tavanları.
API anahtarları — saklama, döndürme ve güvenlik
Anahtarınız başvurunuz onaylandığında oluşturulur. Yalnızca bir kez gösterilir — API anahtarları sekmesinden görüntüleyin ve hemen saklayın.
Vetox anahtarınızı asla okunabilir biçimde saklamaz (yalnızca tuzlu bir karma). Onu sunucu tarafı bir sır olarak — bir ortam değişkeni veya bir sır yöneticisi — saklayın, asla istemci kodunda, bir git deposunda veya bir tarayıcıda değil.
API anahtarları sekmesinden döndürün. Eski anahtar, yenisini kesinti olmadan dağıtmanız için 24 saatlik bir geçiş süresi boyunca çalışmaya devam eder, sonra durur.
Tahsilat onay akışı
Her tahsilat, kullanıcının PIN’iyle onayladığı bir doğrulamadan geçer — anahtarınız tek başına asla Vito taşımaz:
- 1Uygulamanız kullanıcı, tutar, kaynak guildId ve öğe ayrıntılarıyla POST /deduct çağrısı yapar.
- 2Vito bekleyen bir doğrulama (10 dakika geçerli) oluşturur ve bir confirmUrl döndürür. Bir guildId verilirse, kullanıcıya ayrıntıları ve doğrulama sayfasına bir düğmeyi içeren bir DM de gönderilir.
- 3Kullanıcı vetox.io’da confirmUrl’yi açar ve cüzdan PIN’iyle tahsilatı onaylar.
- 4Vito, Vito’yu düşer, işlemi kaydeder ve — bir webhook yapılandırdıysanız — geri çağırma URL’nize imzalı bir confirmation.completed olayı gönderir.
- 5Uygulamanız imzayı doğrular ve kendi eylemini tamamlar (örneğin, içeriğin kilidini açar).
İstek parametreleri (/deduct)
/v1/deductKesinti uç noktası aşağıdaki gövde alanlarını kabul eder:
discordIdamountguildIdreasonmerchantRefproductproduct.imageUrlmetadata* zorunlu alan.
POST https://api.vetox.io/public/vito/v1/deduct
Authorization: Bearer vito_live_xxxxxxxxxxxxxxxx
Content-Type: application/json
Idempotency-Key: req_9a1f2b # optional, dedupes retries for 24h
{
"discordId": "123456789012345678",
"amount": 500,
"guildId": "1470389021162209280",
"reason": "Unlock premium theme",
"merchantRef": "ref_1042",
"product": {
"type": "feature",
"name": "Premium theme",
"description": "Unlocks the premium theme pack",
"imageUrl": "https://cdn.example.com/theme.png"
},
"metadata": { "ref": "1042" }
}{
"success": true,
"data": {
"confirmationId": "f3c9...e1",
"confirmUrl": "https://vetox.io/confirm/vito/f3c9...e1",
"amount": 500,
"expiresAt": 1735689600000,
"status": "pending"
},
"requestId": "req_abc123",
"timestamp": 1735689300000
}Vito ekleme — alacaklar (/add)
/v1/addPOST /add, kendi bakiyenizden bir kullanıcıya Vito yatırır — ödüller veya alacaklar için. guildId ve product hariç /deduct ile aynı alanları alır. Bir tahsilatın aksine anlıktır ve kullanıcı PIN’i gerektirmez — API anahtarınız yetkinizdir — bu nedenle yanıt zaten tamamlanmış aktarımı yansıtır. Kullanıcı tutarın tamamını alır; hiçbir platform ücreti uygulanmaz.
POST https://api.vetox.io/public/vito/v1/add
Authorization: Bearer vito_live_xxxxxxxxxxxxxxxx
Content-Type: application/json
Idempotency-Key: credit_7f3a # optional, dedupes retries for 24h
{
"discordId": "123456789012345678",
"amount": 250,
"reason": "Event reward",
"merchantRef": "reward_1042",
"metadata": { "ref": "1042" }
}{
"success": true,
"data": {
"transactionId": "txn_91b2",
"toDiscordId": "123456789012345678",
"amount": 250,
"ownerBalance": 48250,
"recipientBalance": 1250,
"status": "completed"
},
"requestId": "req_def456",
"timestamp": 1735689300000
}Webhook’lar ve imza doğrulama
Ayarlar sekmesinde bir veya daha fazla https geri çağırma URL’si ekleyin. Vito, bir doğrulama nihai bir duruma ulaştığında her yapılandırılmış URL’ye imzalı bir POST teslim eder ve üstel geri çekilmeyle en fazla 5 kez yeniden dener.
İmzayı doğrulama
Her teslimat ts=<unix>;h1=<hex> biçiminde bir X-Vito-Signature başlığı taşır. HMAC’yi imzalama gizli anahtarınızla "<ts>:<rawBody>" üzerinde yeniden hesaplayın ve sabit zamanda karşılaştırın. JSON ayrıştırmadan önce her zaman ham istek gövdesine karşı doğrulayın.
signature = HMAC_SHA256(signingSecret, "<ts>:<rawBody>")
header = X-Vito-Signature: ts=<unix-seconds>;h1=<hex-signature>import crypto from 'crypto';
import express from 'express';
const app = express();
// IMPORTANT: verify against the RAW body, before JSON parsing.
app.post('/webhooks/vito', express.raw({ type: '*/*' }), (req, res) => {
const sig = req.header('X-Vito-Signature') || ''; // "ts=<unix>;h1=<hmac>[;h1=<hmac>]"
const pairs = sig.split(';').map(p => p.split('='));
const ts = pairs.find(([k]) => k === 'ts')?.[1];
const sigs = pairs.filter(([k]) => k === 'h1').map(([, v]) => v);
const rawBody = req.body.toString('utf8');
const expected = crypto
.createHmac('sha256', process.env.VITO_SIGNING_SECRET) // whsec_...
.update(`${ts}:${rawBody}`)
.digest('hex');
const expectedBuf = Buffer.from(expected, 'hex');
// During a 24h secret rotation the header carries TWO h1= values — accept ANY.
// Length-guard FIRST: crypto.timingSafeEqual throws on a length mismatch.
const ok = sigs.some(h => {
const got = Buffer.from(h, 'hex');
return (
got.length === expectedBuf.length &&
crypto.timingSafeEqual(got, expectedBuf)
);
});
// Reject anything older than ~5 minutes to stop replays.
const fresh = ts && Math.abs(Date.now() / 1000 - Number(ts)) < 300;
if (!ok || !fresh) return res.status(401).end();
const event = JSON.parse(rawBody);
if (event.eventType === 'confirmation.completed') {
grantPremiumTheme(event.data.merchantRef, event.data.fromDiscordId);
}
res.status(200).end(); // ack fast; run your action async if slow
});Webhook olayları ve yükler
Vito dört olay türünden birini gönderir. Hepsi aynı yük biçimini paylaşır; data.status sonucu yansıtır.
confirmation.completedconfirmation.failedconfirmation.expiredconfirmation.cancelledcredit.completedPOST https://your-app.com/webhooks/vito
X-Vito-Signature: ts=1735689600;h1=4f8b2c...e9
X-Vito-Event-Id: evt_3a2b1c
X-Vito-Event-Type: confirmation.completed
Content-Type: application/json
{
"eventId": "evt_3a2b1c",
"eventType": "confirmation.completed",
"timestamp": 1735689600000,
"data": {
"confirmationId": "f3c9...e1",
"type": "deduct",
"fromDiscordId": "123456789012345678",
"toDiscordId": null,
"amount": 500,
"reason": "Unlock premium theme",
"merchantRef": "ref_1042",
"product": { "type": "feature", "name": "Premium theme" },
"status": "completed",
"transactionId": "txn_77a2",
"metadata": { "ref": "1042" },
"failureReason": null
}
}Hata kodları
Hatalar, üst düzey bir error.code taşıyan bir JSON gövdesiyle 2xx olmayan bir durum döndürür. Yaygın durumlar:
VITO_VALIDATION_ERRORinvalid keyOWNER_MEMBERSHIP_INACTIVEscope / IPnot foundinsufficient balanceINSUFFICIENT_OWNER_FUNDSrate limited{
"success": false,
"error": { "type": "Bad Request", "message": "guildId must be a valid Discord server ID", "code": "VITO_VALIDATION_ERROR" },
"requestId": "req_abc123",
"timestamp": 1735689300000
}Entegrasyon örnekleri
Bir tahsilat isteği oluşturun:
/v1/deductcurl -X POST https://api.vetox.io/public/vito/v1/deduct \
-H "Authorization: Bearer $VITO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"discordId": "123456789012345678",
"amount": 500,
"guildId": "1470389021162209280",
"merchantRef": "ref_1042",
"product": { "type": "feature", "name": "Premium theme" }
}'Bir kullanıcının bakiyesini kontrol edin:
/v1/balance/:discordIdcurl https://api.vetox.io/public/vito/v1/balance/123456789012345678 \
-H "Authorization: Bearer $VITO_API_KEY"Demo entegrasyonuyla test etme
Tam akışı kod yazmadan baştan sona denemeniz için bağımsız bir demo entegrasyonu sağlanır. İstek → doğrulama → PIN → webhook → tamamlanma adımlarını izler.
- 1Demo entegrasyonu klasörünü açın ve Vito API anahtarınızı, bir Discord bot belirtecini ve test sunucusu (guild) kimliğinizi config.json’a ekleyin.
- 2npm install && npm start komutunu çalıştırın, ardından http://localhost:4000 adresini açın.
- 3Bir kullanıcıyı Discord kimliğiyle arayın, bir öğe seçin ve bir tahsilat başlatın — demo /deduct çağrısı yapar ve confirmUrl’yi gösterir.
- 4vetox.io’da PIN’i onaylayın; demo tamamlanmayı algılar (yapılandırıldıysa webhook ile, aksi takdirde yoklama ile) ve örnek eylemi tamamlar.
En iyi uygulamalar, sınırlar ve güvenlik
Güvenlik
- API anahtarınızı ve imzalama gizli anahtarınızı yalnızca sunucu tarafında tutun; biri sızarsa hemen döndürün.
- Webhook imzasını her zaman ham gövdeye karşı doğrulayın ve ~5 dakikadan eski teslimatları reddedin (yeniden oynatma koruması).
- Kendi eyleminizi yalnızca confirmation.completed’da tamamlayın — asla /deduct yanıtında değil (o noktada tahsilat henüz kesinleşmemiştir).
- IP izin listesini kullanın ve yalnızca gerçekten ihtiyaç duyduğunuz kapsamları isteyin.
Sınırlar
- Doğrulamaların süresi 10 dakika sonra dolar; onaylanmamış istekleri terk edilmiş sayın.
- Hız sınırları proje başınadır ve sahibin üyelik seviyesiyle ölçeklenir.
- amount pozitif bir tam sayı olmalıdır; metadata 10 anahtarla sınırlıdır.