अनुमोदित ऐप्स को PIN पुष्टि के साथ आपके Vito को चार्ज करने दें, और अपने Purchases पृष्ठ से भुगतान अनुरोध प्रबंधित करें।
Silver या उससे ऊपर की सदस्यता ज़रूरी है — आवेदन करने के लिए भी और हर प्रमाणित कॉल के लिए भी। अगर कुंजी के मालिक की सदस्यता समाप्त हो जाए, तो दोबारा सदस्यता लेने तक प्रोजेक्ट फ़्रीज़ रहता है।
एक REST API जो आपके ऐप्लिकेशन को Discord के भीतर से किसी उपयोगकर्ता के Vito बैलेंस के साथ काम करने देता है — उसे पढ़ना, उससे राशि लेना, उसमें जोड़ना, या उपयोगकर्ताओं के बीच स्थानांतरित करना। सभी एंडपॉइंट JSON लौटाते हैं और /v1 के अंतर्गत वर्ज़न किए गए हैं।
Vito कभी असली पैसे में नहीं बदलता और न ही उससे आता है। यह केवल Vetox बैलेंस के बीच ही चलता है।
आपकी कुंजी और हस्ताक्षर सीक्रेट ठीक एक बार दिखाए जाते हैं। स्वीकृति के बाद उन्हें API कुंजी टैब में देखने के लिए आपके पास 7 दिन की अवधि होती है। Vetox सिर्फ़ एक हैश रखता है और उन्हें दोबारा नहीं दिखा सकता — यह अवधि चूक गए तो नई कुंजी के लिए रोटेशन करना होगा।
इसे केवल सर्वर पर रखें — जिसके पास यह है, वह आपके उपयोगकर्ताओं से राशि ले सकता है
रोटेशन API कुंजी टैब से करें। पुरानी कुंजी 24 घंटे की छूट अवधि तक काम करती रहती है, ताकि आप बिना रुकावट तैनाती कर सकें
webhook हस्ताक्षर सीक्रेट अलग से रोटेट होता है और उसकी अपनी 24 घंटे की अतिव्यापी अवधि होती है
अकेली कुंजी किसी उपयोगकर्ता के Vito को हिला नहीं सकती। हर कटौती के लिए उपयोगकर्ता को vetox.io पर अपने वॉलेट PIN से मंज़ूरी देनी होती है — न आपके ऐप के भीतर, न Discord के भीतर।
1
आपका ऐप POST /v1/deduct कॉल करता है
उपयोगकर्ता, राशि, मूल guildId और वस्तु के विवरण के साथ।
2
Vito एक confirmUrl लौटाता है
एक लंबित पुष्टि, जो 10 मिनट तक वैध रहती है। उपयोगकर्ता को DM भी जाता है।
3
उपयोगकर्ता अपने PIN से मंज़ूरी देता है
vetox.io पर।
4
Vito निपटान करता है और सूचित करता है
बैलेंस से कटौती होती है, लेनदेन दर्ज होता है, और यदि आपने कॉन्फ़िगर किया है तो हस्ताक्षरित webhook भेजा जाता है।
5
आपका ऐप सत्यापित करके पूरा करता है
हस्ताक्षर जाँचें, फिर सामग्री खोलें या वस्तु सौंपें।
अपनी कार्रवाई केवल confirmation.completed पर पूरी करें — कभी भी /deduct की प्रतिक्रिया पर नहीं। उस समय कटौती अंतिम नहीं होती।
POST /v1/add किसी उपयोगकर्ता को आपके अपने बैलेंस से Vito देता है — इनाम या धनवापसी के लिए। guildId और product को छोड़कर वही फ़ील्ड जो /deduct में हैं।
कटौती के विपरीत, जोड़ने में कोई पुष्टि चरण नहीं होता — निपटान तुरंत हो जाता है। इसके लिए credit:create scope और पर्याप्त बैलेंस चाहिए, वरना कॉल 402 VITO_INSUFFICIENT_OWNER_FUNDS लौटाता है।
सेटिंग्स टैब में एक या अधिक https कॉलबैक URL जोड़ें। जब भी कोई पुष्टि अंतिम स्थिति तक पहुँचती है, Vito एक हस्ताक्षरित POST भेजता है।
webhooks तभी भेजे जाते हैं जब आपके प्रोजेक्ट में कॉलबैक URL और हस्ताक्षर सीक्रेट दोनों हों। सीक्रेट (whsec_…) को API कुंजी टैब से एक ही बार देखा जा सकता है।
हर डिलीवरी के साथ दो और हेडर आते हैं — X-Vito-Event-Id को डुप्लिकेट हटाने की कुंजी बनाएँ, क्योंकि पुनः प्रयास वही id दोबारा भेजता है:
हेडर
इसमें होता है
X-Vito-Event-Id
इस ईवेंट का स्थिर id — हर पुनः प्रयास में एक जैसा
X-Vito-Event-Type
जैसे confirmation.completed
हस्ताक्षर सीक्रेट के रोटेशन के दौरान हेडर में एक से अधिक हस्ताक्षर आते हैं, सबसे नया पहले:
X-Vito-Signature: ts=<unix>;h1=<नया>;h1=<पुराना>
यदि कोई भीh1 मेल खाए तो डिलीवरी स्वीकार करें। केवल पहला पढ़ने वाला सत्यापक नया सीक्रेट तैनात करने तक हर webhook अस्वीकार करेगा — और यही 24 घंटे की अतिव्यापी अवधि के पूरे उद्देश्य को व्यर्थ कर देता है।
अपने हस्ताक्षर सीक्रेट से <ts>:<rawBody> पर HMAC दोबारा निकालें और स्थिर समय में तुलना करें।
const crypto = require('crypto');function verify(rawBody, header, secret) { const parts = header.split(';'); const ts = parts.find(p => p.startsWith('ts='))?.slice(3); const sigs = parts.filter(p => p.startsWith('h1=')).map(p => p.slice(3)); if (!ts || sigs.length === 0) return false; // Reject anything older than ~5 minutes — replay protection. if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; const expected = Buffer.from( crypto.createHmac('sha256', secret).update(`${ts}:${rawBody}`).digest('hex'), ); // Any matching signature is valid — a rotation emits several. return sigs.some(sig => { const actual = Buffer.from(sig); // timingSafeEqual throws when the lengths differ, so check first. return ( actual.length === expected.length && crypto.timingSafeEqual(actual, expected) ); });}
कच्चे बॉडी के आधार पर सत्यापित करें — किसी भी JSON पार्सिंग या मिडलवेयर द्वारा उसे बदले जाने से पहले।
आपकी प्रति-मिनट सीमा की आधी, कम से कम 30, एक प्रति-IP सीमा भी लागू होती है।
भारी लोड में लिखने वाले एंडपॉइंट बंद होकर विफल होते हैं — दोहरे ख़र्च का जोखिम लेने के बजाय कटौती अस्वीकार कर दी जाती है। पढ़ने वाले एंडपॉइंट खुले होकर विफल होते हैं। अस्वीकृत लेखन को “हुआ ही नहीं” मानकर दोबारा भेजें।
पुनः प्रयासों को सुरक्षित ढंग से डुप्लिकेट-मुक्त रखने के लिए Idempotency-Key हेडर भेजें।