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

Webhook हस्ताक्षर की जाँच

भुगतान की सूचना ऐसे पते पर आती है, जिसे सिर्फ़ आपका स्टोर और हमारी सेवा जानते हैं। लेकिन पता लीक हो सकता है — लॉग से, कॉन्फ़िगरेशन से, डेवलपमेंट के इतिहास से। असली सूचना को जालसाज़ी से अलग पहचानने के लिए हर अनुरोध पर Webhook की गुप्त कुंजी से हस्ताक्षर होता है।

ऑर्डर पूरा करने या उसकी स्थिति बदलने से पहले हस्ताक्षर की जाँच करें।

हस्ताक्षर के हेडर

हेडरमान
X-Timestampभेजने का समय, सेकंड में unix time
X-Signaturesha256= उपसर्ग और hex में HMAC-SHA256

जिस स्ट्रिंग पर हस्ताक्षर होता है, वह है भेजने का समय, एक बिंदु और अनुरोध की बॉडी:

1756901234.{"wallet":{...},"project":{...},"invoice":{...},"payment":{...}}

साइनिंग कुंजी प्रोजेक्ट सेटिंग्स का Webhook की गुप्त कुंजी (Webhook secret) फ़ील्ड है। मान लीक हो जाने पर आप उसे वहीं दोबारा जारी कर सकते हैं।

जाँच के चरण

  1. JSON पार्स करने से पहले की raw अनुरोध बॉडी लें।
  2. X-Timestamp का मान, एक बिंदु और बॉडी को आपस में जोड़ लें।
  3. Webhook की गुप्त कुंजी से HMAC-SHA256 की गणना करें।
  4. नतीजे की तुलना X-Signature से constant-time तुलना के ज़रिए करें।
  5. अगर X-Timestamp मौजूदा समय से बहुत दूर है, तो अनुरोध ठुकरा दें।

लागू करने के उदाहरण

<?php
$secret = 'webhook secret from your project settings';

$body = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';

// Guards against a replayed request
if (abs(time() - (int)$timestamp) > 300) {
http_response_code(400);
exit;
}

$expected = 'sha256='.hash_hmac('sha256', $timestamp.'.'.$body, $secret);

// hash_equals compares in constant time
if (!hash_equals($expected, $signature)) {
http_response_code(403);
exit;
}

$data = json_decode($body, true);

// Handle the order

http_response_code(200);

ध्यान रखने की बातें

हस्ताक्षर raw बॉडी पर होता है। अगर आप JSON पार्स करके उसे दोबारा बनाते हैं, तो कुंजियों का क्रम और स्पेस बदल जाते हैं — हस्ताक्षर मेल नहीं खाएगा। HMAC की गणना पार्स करने से पहले करें।

हर पुनः प्रयास का अपना हस्ताक्षर है। हर पुनः प्रयास पर भेजने का समय नया होता है, इसलिए हस्ताक्षर भी अलग होता है। भविष्य के अनुरोधों से तुलना के लिए हस्ताक्षर सेव न करें।

गुप्त कुंजी दोबारा जारी की जा सकती है। दोबारा जारी होते ही पुरानी कुंजी काम करना बंद कर देती है, इसलिए अपने स्टोर में मान उसी समय बदलें।

हस्ताक्षर की जाँच idempotency की जगह नहीं लेती। हस्ताक्षर साबित करता है कि अनुरोध असली है, न कि यह कि आप उसे पहली बार देख रहे हैं। पुनः प्रयास मान्य हस्ताक्षर के साथ आता है — invoice.id से जाँचें।