मुख्य कंटेंट तक स्किप करें

सुरक्षा गाइड

अपने PayerScan Payment Gateway इंटीग्रेशन को सुरक्षित करने के लिए सर्वोत्तम प्रथाएं।

API Key सुरक्षा

अपनी API Key कभी उजागर न करें

आपकी API Key PayerScan API को भेजे गए अनुरोधों को प्रमाणित करती है। यह कभी भी अंतिम उपयोगकर्ताओं को दिखाई नहीं देनी चाहिए।

// ❌ गलत - फ्रंटएंड से API कॉल करना (API Key सबको दिखाई देती है)
fetch('https://api.payerscan.com/payment/crypto', {
headers: { 'x-api-key': 'EQnhBYpknGAP...' } // API Key उजागर!
})

// ✅ सही - बैकएंड सर्वर से API कॉल करना
// फ्रंटएंड आपके आंतरिक API को कॉल करता है
fetch('/api/create-payment', { body: { amount: 100 } })

// आपका बैकएंड PayerScan को कॉल करता है (API Key सर्वर पर सुरक्षित)
app.post('/api/create-payment', async (req, res) => {
const result = await fetch('https://api.payerscan.com/payment/crypto', {
headers: { 'x-api-key': process.env.PAYERSCAN_API_KEY }
})
res.json(result)
})

API Key सुरक्षित रूप से संग्रहीत करें

# ✅ Environment variables का उपयोग करें
PAYERSCAN_API_KEY=EQnhBYpknGAP...

# ❌ कोड में हार्डकोड न करें
const API_KEY = 'EQnhBYpknGAP...' # ऐसा न करें

ध्यान दें: API Key को कभी भी version control (Git) में commit न करें। .env को अपनी .gitignore फ़ाइल में जोड़ें।

API Key को समय-समय पर बदलें

  • यदि API Key के उजागर होने का संदेह हो तो तुरंत बदलें
  • Store प्रबंधन पर जाएं → नई API Key जनरेट करें
  • अपने सर्वर पर तुरंत नई API Key अपडेट करें
  • नई Key जनरेट होने के बाद पुरानी API Key तुरंत रद्द हो जाएगी

Webhook सुरक्षा

HTTPS का उपयोग करें

डेटा को ट्रांज़िट में एन्क्रिप्ट करने और man-in-the-middle हमलों को रोकने के लिए हमेशा अपने callback_url के लिए HTTPS का उपयोग करें।

// ✅ सही - HTTPS का उपयोग
callback_url: 'https://your-server.com/webhook/payment'

// ❌ गलत - HTTP का उपयोग (डेटा एन्क्रिप्ट नहीं, इंटरसेप्शन के प्रति संवेदनशील)
callback_url: 'http://your-server.com/webhook/payment'

Webhook अनुरोध सत्यापित करें

हमेशा सत्यापित करें कि webhook अनुरोध वास्तव में PayerScan से आ रहे हैं:

app.post('/webhook/payment', express.json(), async (req, res) => {
try {
const { merchant_id, api_key, trans_id, request_id, status, amount, transaction_hash } = req.body

// 1. merchant_id सत्यापित करें (completed और expired दोनों)
if (merchant_id !== process.env.PAYERSCAN_MERCHANT_ID) {
return res.status(401).json({ error: 'Invalid merchant' })
}

// 2. api_key सत्यापित करें (केवल completed — expired में api_key नहीं होती)
if (status === 'completed' && api_key !== process.env.PAYERSCAN_API_KEY) {
return res.status(401).json({ error: 'Invalid API Key' })
}

// 3. request_id (यदि उपलब्ध हो) या trans_id से ऑर्डर खोजें
let order = null
if (request_id) {
order = await db.orders.findOne({ request_id })
}
if (!order) {
order = await db.orders.findOne({ trans_id })
}
if (!order) {
return res.status(404).json({ error: 'Order not found' })
}

// 4. केवल अपडेट करने योग्य स्थिति वाले ऑर्डर प्रोसेस करें (idempotent)
const processableStatuses = ['waiting', 'pending', 'processing']
if (!processableStatuses.includes(order.status)) {
return res.status(200).json({ message: 'Already processed' })
}

// 5. राशि मिलान सत्यापित करें (केवल completed — छेड़छाड़ रोकथाम)
if (status === 'completed') {
if (parseFloat(amount) !== parseFloat(order.amount)) {
return res.status(400).json({ error: 'Amount mismatch' })
}
}

// 6. जांचें कि transaction_hash पहले से उपयोग नहीं हुआ है (रीप्ले रोकथाम)
if (status === 'completed') {
const existingTx = await db.orders.findOne({ transaction_hash })
if (existingTx) {
return res.status(409).json({ error: 'Transaction hash already used' })
}
}

// 7. एटॉमिक अपडेट — रेस कंडीशन रोकने के लिए स्थिति फ़िल्टर शामिल
if (status === 'completed') {
const result = await db.orders.update(
{ trans_id, status: { $in: processableStatuses } },
{ status: 'completed', transaction_hash }
)
if (result.modifiedCount === 0) {
return res.status(200).json({ message: 'Already processed' })
}
} else if (status === 'expired') {
const result = await db.orders.update(
{ trans_id, status: { $in: processableStatuses } },
{ status: 'expired' }
)
if (result.modifiedCount === 0) {
return res.status(200).json({ message: 'Already processed' })
}
}

res.status(200).json({ success: true })
} catch (error) {
console.error('Webhook processing error:', error)
res.status(500).json({ error: 'Internal server error' })
}
})

Idempotent प्रोसेसिंग

Webhook अधिकतम 5 बार पुनः प्रयास किया जा सकता है। सुनिश्चित करें कि कई बार प्रोसेसिंग सुरक्षित है:

// ✅ सही - केवल प्रोसेस करने योग्य स्थिति वाले ऑर्डर अपडेट करें
const processableStatuses = ['waiting', 'pending', 'processing']
if (!processableStatuses.includes(order.status)) {
return res.status(200).json({ message: 'Already processed' })
}

// ❌ गलत - कोई जांच नहीं, बैलेंस कई बार जुड़ सकता है
await addBalance(user, amount) // यदि webhook 2 बार भेजा → 2 बार क्रेडिट!

डेटा सुरक्षा

संवेदनशील डेटा लॉग न करें

// ❌ गलत - API Key लॉग करना
console.log('Request with API Key:', req.headers['x-api-key'])

// ✅ सही - केवल आवश्यक जानकारी लॉग करें
console.log('Payment created:', { trans_id, amount, status })

इनपुट सत्यापित करें

PayerScan सर्वर साइड पर इनपुट सत्यापित करता है, लेकिन आपको अपनी ओर से भी सत्यापित करना चाहिए:

// राशि सत्यापित करें (सकारात्मक होनी चाहिए, अधिकतम 1,000,000 USD)
const amount = parseFloat(req.body.amount)
if (isNaN(amount) || amount <= 0 || amount > 1000000) {
return res.status(400).json({ error: 'Invalid amount' })
}

// callback_url प्रारूप सत्यापित करें
if (req.body.callback_url) {
try {
const url = new URL(req.body.callback_url)
if (url.protocol !== 'https:') {
console.warn('callback_url को सुरक्षा के लिए HTTPS का उपयोग करना चाहिए')
}
} catch {
return res.status(400).json({ error: 'Invalid callback_url' })
}
}

PayerScan सर्वर-साइड सुरक्षा

PayerScan सर्वर साइड पर सुरक्षा की कई परतें लागू करता है:

  • SSRF सुरक्षा: सिस्टम webhook भेजने से पहले सभी callback_url मानों को सत्यापित करता है। आंतरिक/निजी IP और संदिग्ध URL स्वचालित रूप से ब्लॉक किए जाते हैं।
  • दर सीमा: API endpoint burst और sustained दर सीमाओं द्वारा दुरुपयोग से सुरक्षित हैं। विवरण के लिए दर सीमाएं देखें।
  • इनपुट सत्यापन: सभी अनुरोध पैरामीटर सख्त schema द्वारा सत्यापित किए जाते हैं (राशि सीमा, URL प्रारूप, स्ट्रिंग लंबाई सीमा)।
  • Webhook Timeout: Webhook callback का 10-सेकंड timeout होता है। यदि आपका सर्वर 10 सेकंड के भीतर प्रतिक्रिया नहीं देता, तो प्रयास विफल चिह्नित किया जाता है और पुनः प्रयास किया जाएगा।

सुरक्षा चेकलिस्ट

लाइव जाने से पहले

  • API Key environment variables में संग्रहीत (हार्डकोड नहीं)
  • API Key frontend/client-side कोड में उजागर नहीं
  • .env फ़ाइल .gitignore में जोड़ी गई
  • Webhook endpoint HTTPS का उपयोग करता है
  • Webhook completed और expired दोनों के लिए merchant_id सत्यापित करता है
  • Webhook completed webhook के लिए api_key सत्यापित करता है
  • Webhook request_id या trans_id द्वारा ऑर्डर खोजता है
  • Webhook प्रोसेसिंग idempotent है (कोई डुप्लिकेट प्रोसेसिंग नहीं)
  • Webhook amount को ऑर्डर राशि से मिलान करता है
  • Webhook जांचता है कि transaction_hash पहले से उपयोग नहीं हुआ (रीप्ले रोकथाम)
  • Webhook स्थिति फ़िल्टर के साथ एटॉमिक अपडेट का उपयोग करता है (रेस कंडीशन रोकथाम)
  • संवेदनशील डेटा लॉग नहीं किया गया (API Key, private key)
  • राशि, URL के लिए इनपुट सत्यापन

निरंतर

  • Webhook endpoint के एक्सेस लॉग की नियमित समीक्षा करें
  • अनधिकृत या संदिग्ध webhook अनुरोधों की निगरानी करें
  • API Key को समय-समय पर या उजागर होने पर बदलें
  • Security patches वाले dependencies अपडेट करें
  • Webhook endpoint 10 सेकंड के भीतर प्रतिक्रिया देता है, इसका परीक्षण करें

सुरक्षा घटना प्रतिक्रिया

यदि API Key उजागर हो गई

  1. तुरंत Store प्रबंधन पर जाएं → नई API Key जनरेट करें
  2. सभी सर्वर पर नई API Key अपडेट करें
  3. अनधिकृत अनुरोधों के लिए हालिया API लॉग की समीक्षा करें
  4. संदिग्ध लेनदेन पाए जाने पर सहायता से संपर्क करें

यदि नकली Webhook का पता चला

  1. सत्यापित करें कि आपका webhook हैंडलर merchant_id और api_key की जांच करता है
  2. लॉग में amount बेमेल या डुप्लिकेट transaction_hash प्रयास जांचें
  3. स्रोत IP को ब्लॉक करें (यदि पहचाना जा सके)
  4. यदि संभव हो तो IP allowlisting जोड़ें
  5. घटना की रिपोर्ट करने के लिए support से संपर्क करें

सहायता से संपर्क करें

तत्काल सुरक्षा समस्याओं के लिए, हमसे तुरंत संपर्क करें: