सामग्री पर जाएं

PHP में Payora वेबहुक हस्ताक्षर सत्यापित करें

PHP में Payora के वेबहुक का रॉ पेलोड पढ़ें, HMAC हस्ताक्षर जाँचें और नकली भुगतान इवेंट से अपने एंडपॉइंट को सुरक्षित रखें।

Payora11 मिनट पढ़ने का समयEN · RU · UK · ES · DE · FR · IT · PL · PT · HI · ZH
PHP में Payora वेबहुक हस्ताक्षर सत्यापित करें

Payora के हस्ताक्षरित वेबहुक क्या होते हैं

Payora के हस्ताक्षरित वेबहुक ऐसे HTTP अनुरोध होते हैं जिनमें डिजिटल हस्ताक्षर शामिल होता है। इससे आपका PHP एंडपॉइंट जाँच सकता है कि इवेंट सचमुच Payora से आया है और रास्ते में उसमें कोई बदलाव नहीं हुआ। अगर आप जानना चाहते हैं कि PHP में Payora वेबहुक हस्ताक्षर कैसे सत्यापित करें, तो इसकी बुनियादी प्रक्रिया आसान है: Payora एक इवेंट भेजता है, आपका सर्वर उसका रॉ पेलोड पढ़ता है और फिर आपका कोड हस्ताक्षर की पुष्टि करता है। उसके बाद ही वह अनुरोध के मुख्य भाग में मौजूद जानकारी पर भरोसा करता है।

यह जाँच ज़रूरी है, क्योंकि आपके URL की जानकारी रखने वाला कोई भी क्लाइंट वेबहुक भेज सकता है। कोई हमलावर लॉग से एंडपॉइंट कॉपी करके साफ़-सुथरे JSON बॉडी के साथ नकली भुगतान इवेंट POST कर सकता है। हस्ताक्षर इस चाल को रोकता है।

सत्यापन के बाद ही इवेंट काम का होता है। उससे पहले वह सिर्फ़ टेक्स्ट है।

इसे दरवाज़े पर मिलने वाले नंबर वाले टिकट की तरह समझें। बॉडी संदेश है, हस्ताक्षर उस पर लगी मुहर है और आपका PHP कोड तय करता है कि दोनों मेल खाते हैं या नहीं। मेल खाने पर आप इवेंट प्रोसेस करते हैं। नहीं मिलने पर उसे तुरंत अस्वीकार कर देते हैं।

अगर आपकी साइट पर पहले से भुगतान की प्रक्रिया चल रही है, तो यही सावधानी सिस्टम के दूसरे हिस्सों में भी काम आती है। ई-कॉमर्स के लिए क्रिप्टो पेमेंट गेटवे गाइड पढ़ने वाले व्यापारी को भी यही तरीका दिखेगा: कम स्वीकार करें, ज़्यादा सत्यापित करें और उसके बाद ही ऑर्डर अपडेट करें।

PHP वेबहुक एंडपॉइंट के लिए ज़रूरी चीज़ें

इसके लिए किसी बड़े फ्रेमवर्क की ज़रूरत नहीं है। PHP 8.x का एंडपॉइंट काफ़ी है। कुछ प्रोजेक्ट में PHP 7.4 भी काम कर सकता है, लेकिन कोड को रॉ रिक्वेस्ट बॉडी और Payora की ओर से भेजे गए हेडर तक पहुँच होनी चाहिए। यानी आपके सर्वर सेटअप में सामान्य HTTP अनुरोधों को पढ़ने की सुविधा होनी चाहिए—ऐसी कस्टम परत नहीं जो हेडर बदल दे या हटा दे।

HTTPS का इस्तेमाल करें। TLS के बिना वेबहुक का डेटा खुले में भेजा जाता है, और सिर्फ़ हस्ताक्षर होने से कमज़ोर ट्रांसपोर्ट सुरक्षा की भरपाई नहीं होती। सर्टिफ़िकेट, सही वर्चुअल होस्ट कॉन्फ़िगरेशन और सार्वजनिक रूप से पहुँच योग्य URL बुनियादी ज़रूरतें हैं।

व्यावहारिक तौर पर PHP के दो एक्सटेंशन काम आते हैं: HMAC के लिए hash और, अगर आप JSON के साथ काम कर रहे हैं, तो PHP के साथ आने वाले मुख्य JSON फ़ंक्शन। अपनी तरफ़ से टेस्ट करने के लिए cURL भी काम आ सकता है, लेकिन वेबहुक एंडपॉइंट को इसकी ज़रूरत नहीं होती।

आपको Payora की वह सीक्रेट कुंजी या साइनिंग की भी चाहिए जो आपके Payora खाते में वेबहुक कॉन्फ़िगरेशन से मेल खाती हो। इस मान को वेब रूट के बाहर रखें और git में न डालें। सार्वजनिक रिपॉज़िटरी में सीक्रेट डालना सत्यापन को दिखावा बनाने का तेज़ तरीका है।

एक और बात: आपके एंडपॉइंट को सिर्फ़ POST अनुरोध स्वीकार करने चाहिए। GET अनुरोधों के लिए 405 लौटाया जा सकता है। यह छोटी-सी पाबंदी समस्या की जाँच आसान करती है, क्योंकि इससे पता चलता है कि आपको किस तरह के ट्रैफ़िक पर ध्यान देना है।

रॉ वेबहुक पेलोड और हेडर पढ़ें

हस्ताक्षर की जाँच इस बात पर निर्भर करती है कि Payora ने कौन-से सटीक बाइट भेजे थे। PHP में रॉ रिक्वेस्ट बॉडी पढ़ने के लिए file_get_contents('php://input') का इस्तेमाल करें। पेलोड को $_POST से या डिकोड किए गए JSON से दोबारा न बनाएँ, क्योंकि इन तरीकों से स्पेसिंग, कुंजियों का क्रम या एन्कोडिंग बदल सकती है।

हेडर के लिए भी यही नियम है। आपको हस्ताक्षर वाला हेडर चाहिए। जहाँ उपलब्ध हो, वहाँ getallheaders() का इस्तेमाल करें। अगर आपके एनवायरनमेंट में यह हेल्पर हेडर हटा देता है, तो $_SERVER['HTTP_X_...'] जैसे सर्वर वेरिएबल पढ़ें। होस्टिंग के छोटे-मोटे अंतर भी यहाँ मायने रखते हैं।

मान लीजिए वेबहुक बॉडी 412 बाइट की है। अगर आपका कोड उसे डिकोड करके फिर से एन्कोड करता है, तो हो सकता है कि फ़ील्ड वही दिखें, लेकिन बाइट अब पहले जैसे नहीं होंगे। इतना-सा अंतर भी सत्यापन विफल करने के लिए काफ़ी है।

यह आदत बनाए रखें: पहले डेटा लें, फिर उसे पार्स करें। पहले रॉ स्ट्रिंग सेव करें। फिर हेडर देखें। पेलोड की संरचना को उसके बाद ही छुएँ।

लॉन्च से पहले भुगतान की प्रक्रिया जाँचते समय भी यह तरीका आपका समय बचाता है। क्रिप्टो भुगतान को टेस्ट करने वाला लेख सैंडबॉक्स इवेंट के लिए भी यही तरीका अपनाता है—टेस्ट को उपयोगी बनाए रखने के लिए पेलोड का हूबहू बने रहना ज़रूरी है।

PHP में अपेक्षित हस्ताक्षर फिर से बनाएँ

आमतौर पर रॉ पेलोड और साझा सीक्रेट से HMAC बनाया जाता है। Payora के वेबहुक दस्तावेज़ों में दिया गया एल्गोरिदम इस्तेमाल करें। दस्तावेज़ SHA-256 कहते हैं, तो SHA-256 लें। अगर उसमें प्रीफ़िक्स, वर्ज़न टैग या टाइमस्टैम्प का कोई फ़ॉर्मैट बताया गया है, तो उसी सटीक संरचना का इस्तेमाल करें। इसी प्रक्रिया को Payora वेबहुक HMAC सत्यापन PHP के रूप में समझा जा सकता है: पेलोड, सीक्रेट और दस्तावेज़ों में बताया गया फ़ॉर्मैट एक साथ सही होने चाहिए।

एक सामान्य तरीका यह है: टाइमस्टैम्प और रॉ बॉडी से हस्ताक्षरित संदेश बनाएँ, फिर साझा सीक्रेट और बताए गए हैश एल्गोरिदम के साथ hash_hmac() चलाएँ। विनिर्देश के आधार पर नतीजे को hex या base64 में एन्कोड करना पड़ सकता है। फ़ॉर्मैट का अंदाज़ा न लगाएँ—वेबहुक सेटिंग में देखें।

नीचे PHP शैली का एक छोटा उदाहरण है। जहाँ Payora का फ़ॉर्मैट अलग हो सकता है, वहाँ बदलाव की जगह छोड़ी गई है:

$rawBody = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_PAYORA_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_PAYORA_SIGNATURE'] ?? '';
$secret = getenv('PAYORA_WEBHOOK_SECRET');

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

यह उदाहरण सिर्फ़ एक सामान्य रूप दिखाता है, इसकी गारंटी नहीं देता। अगर Payora केवल पेलोड पर हस्ताक्षर करता है, तो स्ट्रिंग से टाइमस्टैम्प हटा दें। अगर Payora किसी कैनोनिकल JSON फ़ॉर्म पर हस्ताक्षर करता है, तो अपनी पसंद के तरीके के बजाय उसी सटीक तरीके का पालन करें। एक गलत डिलिमिटर से हर अनुरोध विफल हो जाएगा।

बिलिंग के नियमों और खास स्थितियों पर ध्यान देने वाले व्यापारियों के लिए क्रिप्टो भुगतान इनवॉइस की सीमाओं वाला लेख भी उपयोगी है। वेबहुक हैंडलिंग और इनवॉइस नीति अक्सर ऑर्डर के एक ही चरण में मिलती हैं।

बनाए गए हस्ताक्षर की तुलना Payora के हस्ताक्षर से करें

अपेक्षित हस्ताक्षर मिलने के बाद, आने वाले हस्ताक्षर से उसकी तुलना कॉन्स्टेंट-टाइम तरीके से करें। PHP में आम तौर पर इसके लिए hash_equals() इस्तेमाल किया जाता है। साधारण == या === सही विकल्प नहीं हैं, क्योंकि उनसे समय के आधार पर संकेत मिल सकते हैं और कुछ सूक्ष्म अंतर के मामलों में वे कम सुरक्षित हैं।

तुलना करने से पहले फ़ॉर्मैट को ठीक वैसे ही सामान्य करें जैसा Payora के विनिर्देश में बताया गया है। हेडर hex में है, तो hex से तुलना करें। base64 में है, तो base64 से। अगर आने वाले हस्ताक्षर में sha256= जैसा प्रीफ़िक्स है, तो दस्तावेज़ों के अनुसार उसे शामिल करें या हटाएँ।

प्रक्रिया कुछ इस तरह होगी:

  1. रॉ बॉडी पढ़ें।
  2. हस्ताक्षर वाला हेडर पढ़ें।
  3. दस्तावेज़ों में दिए फ़ॉर्मूले से अपेक्षित हस्ताक्षर बनाएँ।
  4. hash_equals() से दोनों स्ट्रिंग की तुलना करें।
  5. हस्ताक्षर मेल न खाए तो 401 या 400 के साथ अनुरोध अस्वीकार करें।

हस्ताक्षर गलत होने पर 401 उचित है। ज़रूरी हेडर न होने पर 400 ठीक रहता है। दोनों ही मामलों में जवाब छोटा रखें—कोई अतिरिक्त जानकारी न दें।

यह बात याद रखें: सीक्रेट को कभी प्रिंट न करें। ऐसा बहुत कम होता है, लेकिन इसके नतीजे विनाशकारी हो सकते हैं।

टाइमस्टैम्प, रीप्ले सुरक्षा और समय-सीमा के नियम संभालें

अगर Payora टाइमस्टैम्प या nonce शामिल करता है, तो इवेंट स्वीकार करने से पहले उसकी जाँच करें। इससे रीप्ले अटैक रुकते हैं—ऐसे हमले जिनमें कोई हमलावर बाद में एक वैध वेबहुक दोबारा भेजकर आपके ऐप से दो बार भुगतान करवाने या सामान भेजने की कोशिश करता है। टाइमस्टैम्प की अवधि Payora के नियमों के अनुसार तय करें, अपने अनुमान से नहीं।

आमतौर पर वेबहुक टाइमस्टैम्प की तुलना सर्वर के समय से की जाती है और तय अवधि से पुराने अनुरोध अस्वीकार कर दिए जाते हैं। दस्तावेज़ 5 मिनट कहते हैं, तो 5 मिनट ही रखें। 300 सेकंड कहते हैं, तो 300 सेकंड को नाम वाली सेटिंग में रखें। तीन फ़ाइलों में कोई अनजान संख्या हार्डकोड न करें।

घड़ी का समय आगे-पीछे होने से सही अनुरोध भी विफल हो सकते हैं। अगर सर्वर का समय 7 मिनट गलत है, तो वह वैध अनुरोध भी अस्वीकार कर सकता है। अपने सर्वरों को NTP से सिंक करें और टाइमज़ोन की सेटिंग एक जैसी रखें। टाइमज़ोन से Unix टाइमस्टैम्प नहीं बदलते, लेकिन गलत स्थानीय सेटिंग से लॉग पढ़ना मुश्किल हो सकता है।

अगर nonce मौजूद है, तो उसे संभालना और भी आसान है। हर nonce को एक बार सेव करें, इस्तेमाल हो जाने पर उसे चिह्नित करें और दोबारा आने पर अस्वीकार कर दें। एक छोटा कैश या डेटाबेस टेबल इसके लिए काफ़ी है। एक nonce, एक बार स्वीकार।

अगर आप भुगतान पेजों पर तय कीमत भी स्वीकार करते हैं, तो यहाँ सही नीति मायने रखती है। क्या मुझे तय कीमत इस्तेमाल करनी चाहिए वाला लेख आपको विनिमय दर के नियमों को वेबहुक के समय के साथ मिलाने में मदद कर सकता है, ताकि देर से आए इवेंट के बाद गलत रकम की पुष्टि न हो।

वैध इवेंट प्रोसेस करें और सही HTTP जवाब दें

सत्यापन सफल होने के बाद पेलोड पार्स करें और इवेंट के प्रकार के आधार पर आगे की प्रक्रिया चुनें। payment.succeeded इवेंट और refund.updated इवेंट को एक ही कोड पथ से नहीं चलाना चाहिए। उनके हैंडलर अलग रखें। इससे हर हैंडलर एक ही काम करेगा और लॉग पढ़ने में आसान रहेंगे।

2xx जवाब भेजने से पहले बिज़नेस लॉजिक चलना चाहिए। अगर ऑर्डर को भुगतान किया हुआ दिखाना है, तो पहले डेटाबेस में बदलाव सेव करें। ईमेल कतार में डालना है, तो पहले उसे कतार में जोड़ें। इनमें से कोई कदम विफल हो, तो 500 लौटाएँ और Payora को बाद में फिर से कोशिश करने दें।

यह क्रम ज़रूरी है, क्योंकि 2xx जवाब आम तौर पर Payora को बताता है कि इवेंट स्वीकार कर लिया गया है। अगर आप जल्दी 200 लौटा दें और फिर डेटाबेस में लिखते समय क्रैश हो जाएँ, तो Payora और आपके ऐप के डेटा में अंतर आ सकता है। ऐसा बग रात के 2 बजे महँगा पड़ता है।

जवाब में छोटा-सा बॉडी काफ़ी है। “OK” ठीक है। इससे भी बेहतर, कोई बॉडी न लौटाएँ और सिर्फ़ स्टेटस कोड स्पष्ट रखें। पेलोड को वापस न भेजें।

जो टीमें भुगतान इवेंट से क्लाइंट के इनवॉइस भी बनाती हैं, उनके लिए फ्रीलांसरों के लिए क्रिप्टो पेमेंट गेटवे वाला लेख दिखाता है कि बिना गैरज़रूरी चरण जोड़े वेबहुक को तकनीकी इवेंट से बिलिंग की वास्तविक कार्रवाई तक कैसे ले जाया जा सकता है।

हस्ताक्षर की जाँच विफल होने पर समस्या का पता लगाएँ

ज़्यादातर विफलताएँ पाँच वजहों से होती हैं: रॉ बॉडी बदल गई, हेडर का नाम गलत है, सीक्रेट गलत है, एन्कोडिंग अलग है या टाइमस्टैम्प तय अवधि से बाहर है। सबसे पहले बॉडी देखें। अगर आपने रॉ पेलोड और बनाया गया हस्ताक्षर लॉग किया है, तो डेटाबेस में बदलाव करने से पहले उनकी तुलना करें।

बॉडी का बदल जाना आम बात है। फ़्रेमवर्क का मिडलवेयर खाली जगह हटा सकता है, JSON डिकोड कर सकता है या लाइन एंडिंग सामान्य कर सकता है। एक अतिरिक्त नई लाइन भी काफ़ी है। अगर Payora ने {"a":1} पर हस्ताक्षर किया और आपका ऐप {"a":1}\n पढ़ता है, तो HMAC मेल नहीं खाएगा।

इसके बाद हेडर के अंतर की जाँच करें। कुछ सर्वर डैश को अंडरस्कोर में बदल देते हैं। कुछ प्रॉक्सी लेयर कस्टम हेडर को तब तक हटा देती हैं, जब तक उन्हें साफ़ तौर पर अनुमति न दी जाए। PHP में हस्ताक्षर वाला हेडर न मिले, तो सिर्फ़ कोड नहीं, वेब सर्वर और प्रॉक्सी की सेटिंग भी देखें।

एन्कोडिंग की समस्या आसानी से नज़र नहीं आती। UTF-8 और एस्केप किए गए Unicode लॉग में सही दिख सकते हैं, लेकिन उनके बाइट अलग हो सकते हैं। अगर आपका ऐप JSON को दोबारा लिखता है, तो ब्राउज़र में पेलोड एक जैसा दिखने के बावजूद हस्ताक्षर टूट सकता है।

गलत सीक्रेट सबसे सीधी वजह है, लेकिन अक्सर लोग इसे सबसे बाद में जाँचते हैं। एनवायरनमेंट वेरिएबल, स्टेजिंग सीक्रेट और प्रोडक्शन सीक्रेट को अलग-अलग सत्यापित करें। गलत खाते से कॉपी किया गया सीक्रेट आपका पूरा दोपहर बर्बाद कर सकता है।

घड़ी का समय गलत होने पर लक्षण अलग दिखते हैं: हस्ताक्षर मेल खाता है, लेकिन टाइमस्टैम्प बहुत पुराना होने से अनुरोध फिर भी अस्वीकार हो जाता है। ऐसा हो, तो NTP, कंटेनर की घड़ी और अपने समय की मुहर लगाने वाले रिवर्स प्रॉक्सी की जाँच करें। इन्फ्रास्ट्रक्चर में थोड़ा-सा समय-अंतर भी गलत हस्ताक्षर जैसा लग सकता है।

अगर आपका सेटअप WordPress या मेंबरशिप बिलिंग से भी जुड़ा है, तो how to accept USDT payments वाला लेख उपयोगी है। इसमें दिखाया गया है कि वेबहुक हैंडलिंग, एक्सेस कंट्रोल और भुगतान की पुष्टि एक ही प्रक्रिया में कैसे जुड़ते हैं।

आख़िरी जाँच भी काफ़ी मददगार है: एक ही पेलोड दो बार भेजें। पहला अनुरोध पास होना चाहिए। अगर आप इस्तेमाल किए गए nonce को सेव करके दोबारा आने पर अस्वीकार करते हैं, तो दूसरा अनुरोध विफल होना चाहिए। nonce पर आधारित रीप्ले सुरक्षा नहीं है, तो ही दूसरा अनुरोध पास होना चाहिए। यह डुप्लिकेट टेस्ट बता देता है कि आपकी सुरक्षा सच में काम कर रही है या नहीं।

इन सभी बातों को लागू करना ही PHP में सुरक्षित वेबहुक एंडपॉइंट कैसे बनाएं का व्यावहारिक आधार है: पहले अनुरोध की पुष्टि करें, रीप्ले रोकें, फिर इवेंट प्रोसेस करें और सही HTTP जवाब लौटाएँ।

Comments

शुरू करने के लिए तैयार हैं?

खाता बनाएँ और एक घंटे से भी कम समय में अपना पहला इनवॉइस जारी करें।

इस पृष्ठ का उत्तर क्या है