27 अक्टू॰ 2025·8 मिनट पढ़ने में

Webhook retries बनाम मैनुअल रिप्ले: सुरक्षित रिकवरी डिज़ाइन

Webhook retries बनाम मैनुअल रिप्ले: UX और सपोर्ट लोड की तुलना करें, और ऐसे रिप्ले टूल पैटर्न सीखें जो डबल चार्ज और डुप्लिकेट रिकॉर्ड रोकें।

Webhook retries बनाम मैनुअल रिप्ले: सुरक्षित रिकवरी डिज़ाइन

वेबहुक विफल होने पर क्या टूटता है

एक वेबहुक विफलता अक्सर "सिर्फ़ तकनीकी गड़बड़" नहीं होती। उपयोगकर्ता के लिए यह ऐसा ही लगता है जैसे आपकी ऐप ने कुछ भूल गया हो: ऑर्डर "पेंडिंग" पर रह जाता है, किसी सब्सक्रिप्शन का एक्सेस खुलता नहीं, टिकट "पेड" पर नहीं जाता, या डिलीवरी स्टेटस गलत दिखता है।

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

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

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

इसलिए Webhook retries बनाम मैनुअल रिप्ले एक प्रोडक्ट निर्णय है, सिर्फ़ इंजीनियरिंग का मामला नहीं। दो रास्ते हैं:

  • Provider automatic retries: भेजने वाला शेड्यूल के अनुसार फिर से कोशिश करता है जब तक उसे सफलता नहीं मिलती।
  • आपका मैनुअल रिप्ले: कोई इंसान (सपोर्ट या एक एडमिन यूजर) गलत दिखने पर फिर से प्रोसेस ट्रिगर करता है।

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

ऑटोमैटिक रीट्राई: कहाँ मदद करते हैं और कहाँ नुकसान

ऑटोमैटिक रीट्राई वेबहुक के लिए डिफ़ॉल्ट सुरक्षा नेट हैं। अधिकांश प्रदाता नेटवर्क एरर और टाइमआउट पर रीट्राई करते हैं, अक्सर बैकऑफ के साथ (मिनटों में, फिर घंटों में) और एक कटऑफ के बाद—एक या दो दिनों के भीतर। यह सुनकर सुखद लगता है, लेकिन यह यूएक्स और सपोर्ट की कहानी दोनों बदल देता है।

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

जब रीट्राई काम करते हैं तो सपोर्ट को अक्सर कम टिकट मिलते हैं, लेकिन जो टिकट बचते हैं वे ज़्यादा मुश्किल होते हैं। एक स्पष्ट फेल्योर की बजाय, आप कई डिलीवरीज़, अलग-अलग रिस्पॉन्स कोड, और मूल क्रिया और अंततः सफलता के बीच लंबा गैप खंगाल रहे होते हैं। वह गैप समझाना कठिन होता है।

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

रीट्राई आमतौर पर पर्याप्त होते हैं जब फेल्योर हैंडलिंग सरल हो: गैर-मनी अपडेट्स, ऐसी क्रियाएँ जो दो बार लगाने पर सुरक्षित हों, और घटनाएँ जहाँ थोड़ी देरी acceptable हो। अगर ईवेंट पैसे हिलाता है या स्थायी रिकॉर्ड बनाता है, तो Webhook retries बनाम मैनुअल रिप्ले सुविधा से ज़्यादा नियंत्रण का सवाल बन जाता है।

मैनुअल रिप्ले: नियंत्रण, जवाबदेही, और ट्रेडऑफ़

मैनुअल रिप्ले का मतलब है कोई इंसान वेबहुक ईवेंट को फिर से प्रोसेस करने का निर्णय लेता है बजाय प्रदाता के रीट्राई शेड्यूल पर निर्भर रहने के। वह व्यक्ति सपोर्ट एजेंट, ग्राहक की तरफ का एडमिन, या (कम जोखिम वाले मामलों में) एंड यूज़र हो सकता है जो "Try again" पर क्लिक करे। रिप्ले में इंसानी नियंत्रण स्पीड पर भारी रहता है।

यूएक्स मिश्रित होता है। उच्च-मूल्य मामलों के लिए, एक रिप्ले बटन एक केस को जल्दी ठीक कर सकता है बिना अगले रीट्राई विंडो का इंतज़ार किए। लेकिन कई समस्याएँ तब लंबित रहेंगी क्योंकि कुछ तब तक नहीं होता जब तक कोई नोटिस न करे और कार्रवाई न करे।

सपोर्ट का वर्कलोड आम तौर पर बढ़ता है, क्योंकि रिप्ले साइलेंट फेल्यर्स को टिकट में बदल देता है और फॉलो-अप बढ़ाते हैं। फायदा यह है कि स्पष्टता आती है: सपोर्ट यह देख सकता है कि क्या रिप्ले हुआ, कब, किसने और क्यों। यह ऑडिट ट्रेल पैसे, एक्सेस, या कानूनी रिकॉर्ड्स के मामलों में मायने रखता है।

सिक्योरिटी सबसे मुश्किल हिस्सा है। एक रिप्ले टूल को permissioned और संकीर्ण होना चाहिए:

  • केवल भरोसेमंद भूमिकाएँ रिप्ले कर सकें, और केवल खास सिस्टम्स के लिए।
  • रिप्ले एक single event तक सीमित हों, न कि "सब कुछ रिप्ले करो"।
  • हर रिप्ले लॉग हो, कारण, अभिनेता और टाइमस्टैम्प के साथ।
  • UI में संवेदनशील पेलोड डेटा मास्क किया जाए।
  • दुरुपयोग और अनजाने स्पैम रोकने के लिए रेट लिमिट्स हों।

मैनुअल रिप्ले अक्सर हाई-रिस्क कार्रवाइयों के लिए पसंद किया जाता है—जैसे इनवॉइस बनाना, अकाउंट प्रोविजन करना, रिफंड्स, या कुछ भी जो डबल-चार्ज या डबल-क्रिएट कर सकता है। यह उन टीमों के साथ भी बैठता है जिन्हें रिव्यू स्टेप्स चाहिए, जैसे "पेमेंट सैटल हुआ कन्फ़र्म करें" उसके बाद ऑर्डर क्रिएशन को पुनः प्रयास करना।

रीट्राई और रिप्ले के बीच कैसे चुनें

ऑटोमैटिक रीट्राई और मैनुअल रिप्ले चुनना कोई एक नियम नहीं है। सबसे सुरक्षित तरीका आमतौर पर मिश्रित होता है: लो-रिस्क ईवेंट्स को ऑटोमैटिकली रीट्राई करें, और जो कुछ पैसा खर्च कर सकता है या गड़बड़ डुप्लीकेट बनाएगा उसके लिए जानबूझकर रिप्ले माँगें।

शुरुआत करें हर वेबहुक ईवेंट को रिस्क के हिसाब से क्लासिफ़ाई करके। एक डिलीवरी स्टेटस अपडेट देरी होने पर परेशान करता है, लेकिन ज़्यादा नुकसान नहीं करता। एक payment_succeeded या create_subscription ईवेंट हाई-रिस्क है क्योंकि एक अतिरिक्त रन डबल-चार्ज या डबल-क्रिएट कर सकता है।

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

टाइम विंडो भी मायने रखती है। रीट्राई आमतौर पर मिनटों या घंटों में होते हैं क्योंकि वे ट्रांज़िएंट समस्याओं को ठीक करने के लिए होते हैं। मैनुअल रिप्ले को लंबा समय दिया जा सकता है, पर हमेशा नहीं। एक आम नियम है कि रिप्ले तभी अनुमति दें जब बिजनेस संदर्भ अभी भी वैध हो (शिप होने से पहले, बिलिंग पीरियड बंद होने से पहले), और उसके बाद सावधानी से एडजस्टमेंट की ज़रूरत हो।

प्रति ईवेंट एक त्वरित चेकलिस्ट:

  • अगर यह दो बार चले तो सबसे बुरा क्या होगा?
  • परिणाम कौन सत्यापित कर सकता है (सिस्टम, सपोर्ट, ops, यूज़र)?
  • कितनी जल्दी सफल होना चाहिए (सेकंड, मिनट, दिन)?
  • कौनसी डुप्लिकेट दर स्वीकार्य है (पैसे के लिए लगभग शून्य)?
  • प्रति घटना कितनी सपोर्ट समय सहनीय है?

अगर आपकी प्रणाली ने create_invoice मिस कर दिया, तो एक छोटा रीट्राई लूप ठीक हो सकता है। अगर उसने charge_customer मिस किया, तो मैनुअल रिप्ले वरीयता दें स्पष्ट ऑडिट ट्रेल और आइडेम्पोटेंसी चेक के साथ।

अगर आप नो-कोड टूल जैसे AppMaster में फ्लो बना रहे हैं, तो हर वेबहुक को एक बिजनेस प्रोसेस के रूप में ट्रीट करें जिसमें स्पष्ट रिकवरी पाथ हो: सुरक्षित स्टेप्स के लिए ऑटो-रीट्राई, और हाई-रिस्क स्टेप्स के लिए अलग रिप्ले एक्शन जो कन्फ़र्मेशन माँगे और रन करने से पहले दिखाए कि क्या होगा।

आइडेम्पोटेंसी और डेडुप्लिकेशन के बेसिक्स

स्रोत के साथ नियंत्रण रखें
रीकवरी डिज़ाइन को मेंटेन करने योग्य बनाए रखने के लिए असली सोर्स कोड जनरेट करें।
कोड एक्सपोर्ट करें

आइडेम्पोटेंसी का मतलब है कि आप एक ही वेबहुक को सुरक्षित रूप से एक से अधिक बार प्रोसेस कर सकें। अगर प्रदाता रीट्राई करता है, या सपोर्ट एजेंट ईवेंट को रिप्ले करता है, तो अंतिम नतीजा उसी होना चाहिए जैसा एक बार प्रोसेस करने पर होता। यह Webhook retries बनाम मैनुअल रिप्ले में सुरक्षित रिकवरी की नींव है।

एक भरोसेमंद idempotency की कैसे चुनें

कुंजी यह है कि आप कैसे तय करते हैं, "क्या हमने इसे पहले ही लागू कर लिया है?" अच्छे विकल्प इस बात पर निर्भर करते हैं जो भेजने वाला प्रदान करता है:

  • प्रदाता इवेंट ID (जब स्थिर और यूनिक हो तो सबसे अच्छा)
  • प्रदाता डिलिवरी ID (रीट्राई डायग्नोसिस के लिए उपयोगी, पर हमेशा इवेंट जैसा नहीं होता)
  • आपका कम्पोजिट की (उदाहरण: provider + account + object ID + event type)
  • रॉ पेलोड का हैश (जब कुछ भी नहीं है तो फॉलबैक, पर whitespace या फील्ड आर्डरिंग पर ध्यान दें)
  • एक जनरेट किया हुआ की जो आप प्रदाता को लौटाते हैं (सिर्फ उन APIs के साथ काम करता है जो इसे सपोर्ट करते हैं)

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

डेडुप्लिकेशन कहाँ लागू करें

एक लेयर पर निर्भर रहना जोखिम भरा है। एक सुरक्षित डिज़ाइन कई पॉइंट चेक करता है: वेबहुक एंडपॉइंट पर (त्वरित रिजेक्ट), बिजनेस लॉजिक में (स्टेट चेक्स), और डेटाबेस में (कठोर गारंटी)। डेटाबेस अंतिम लॉक है: प्रोसेस्ड कीज़ को एक टेबल में यूनिक कॉन्स्ट्रेंट के साथ स्टोर करें ताकि दो वर्कर्स एक ही ईवेंट को एक साथ लागू न कर सकें।

आउट-ऑफ-ऑर्डर ईवेंट्स अलग समस्या हैं। डेडुप्लिकेशन डुप्लीकेट रोकता है, पर पुराने अपडेट्स को नए स्टेट को ओवरराइट करने से नहीं रोकता। सरल गार्ड्स इस्तेमाल करें जैसे टाइमस्टैम्प, सीक्वेंस नंबर, या "केवल आगे बढ़ें" नियम। उदाहरण: अगर एक ऑर्डर पहले ही Paid पर है, तो बाद वाला "Pending" अपडेट इग्नोर करें भले ही वह नया ईवेंट हो।

नो-कोड बिल्ड में (उदाहरण के लिए, AppMaster में) आप processed_webhooks टेबल मॉडल कर सकते हैं और idempotency की पर यूनिक इंडेक्स जोड़ सकते हैं। फिर अपने बिजनेस प्रोसेस को पहले इस रिकॉर्ड को बनाने की कोशिश करने दें। अगर यह फेल हो, तो प्रोसेसिंग रोकें और भेजने वाले को सफलता लौटाएँ।

चरण-दर-चरण: एक ऐसा रिप्ले टूल डिज़ाइन करें जो डिफ़ॉल्ट रूप से सुरक्षित हो

इवेंट्स को वर्कफ़्लो में बदलें
वेबहुक एंडपॉइंट और बिजनेस लॉजिक एक ही जगह डिज़ाइन करें, अलग सेवाओं को जोड़ने की ज़रूरत नहीं।
बैकएंड बनाएं

एक अच्छा रिप्ले टूल जब कुछ गलत हो जाए तो घबराहट कम करता है। रिप्ले तब सबसे अच्छा काम करता है जब यह वही सुरक्षित प्रोसेसिंग पाथ फिर से चलाए, उन गार्डरेल्स के साथ जो डुप्लीकेट रोकें।

1) पहले कैप्चर करें, फिर कार्रवाई करें

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

सिग्नेचर सत्यापित करें, पर बिजनेस एक्शन्स चलाने से पहले मैसेज को परसिस्ट करें। अगर प्रोसेसिंग आधी राह में क्रैश हो जाए, तब भी आपके पास मूल ईवेंट होगा और आप यह साबित कर सकते हैं कि क्या आया था।

2) हैंडलर को आइडेम्पोटेंट बनाएं

आपका प्रोसेसर दो बार चलने पर भी एक ही अंतिम परिणाम देना चाहिए। रिकॉर्ड बनाने, कार्ड चार्ज करने, या एक्सेस प्रोवाइड करने से पहले उसे जांचनी चाहिए कि क्या यह ईवेंट (या यह बिजनेस ऑपरेशन) पहले सफल हुआ था।

कोर नियम को सरल रखें: एक इवेंट id + एक एक्शन = एक सफल परिणाम। अगर आपने पहले सफलता देखी है, तो फिर भी सफलता लौटाएँ लेकिन एक्शन को दोहराएँ नहीं।

3) इंसानों के लिए उपयोगी तरीके से आउटकम रिकॉर्ड करें

रिप्ले टूल तभी उपयोगी होता है जब उसकी हिस्ट्री साफ़ हो। प्रोसेसिंग स्टेटस और एक छोटा सा कारण स्टोर करें जिसे सपोर्ट समझ सके:

  • Success (बनाए गए रिकॉर्ड IDs के साथ)
  • Retryable failure (टाइमआउट्स, अस्थायी अपस्ट्रीम इश्यू)
  • Permanent failure (अन्यथ्या सिग्नेचर, आवश्यक फील्ड्स ग़ायब)
  • Ignored (डुप्लीकेट ईवेंट, आउट-ऑफ-ऑर्डर ईवेंट)

4) रिप्ले हैंडलर को फिर से वही हैंडलर चलाकर करें, "नई बनावट" से नहीं

रिप्ले बटन एक जॉब एनक्यू करेगा जो स्टोर किए गए पेलोड के साथ वही हैंडलर कॉल करे और वही idempotency चेक्स लागू करे। UI को डायरेक्ट राइट्स जैसे "अब ऑर्डर बनाओ" करने मत दें क्योंकि इससे डुप्लीकेशन चेक बाईपास हो सकता है।

हाई-रिस्क ईवेंट्स (पेमेंट्स, रिफंड्स, प्लान चेंज) के लिए एक प्रीव्यू मोड जोड़ें जो दिखाएगा क्या बदलेगा: कौनसे रिकॉर्ड बनेंगे/अपडेट होंगे, और क्या डुप्लीकेट के रूप में स्किप होगा।

अगर आप इसे AppMaster में बनाते हैं, तो रिप्ले एक सिंगल बैकएंड एंडपॉइंट या बिजनेस प्रोसेस ही रहे जो हमेशा आइडेम्पोटेंट लॉजिक से गुज़रे, भले ही यह एडमिन स्क्रीन से ट्रिगर हुआ हो।

क्या स्टोर करें ताकि सपोर्ट तेज़ी से समस्या सुलझा सके

जब वेबहुक फेल हो, सपोर्ट उतनी ही तेज़ी से मदद कर सकता जितनी आपकी रिकॉर्ड्स साफ़ हों। अगर सिर्फ़ क्लू "500 error" है, अगला कदम अंदाज़े पर आधारित होता है, और अंदाज़ा जोखिम भरा रिप्ले बनाता है।

अच्छा स्टोरेज एक डरावने इन्सिडेंट को रूटीन चेक में बदल देता है: ईवेंट ढूँढो, देखो क्या हुआ, सुरक्षित तरीके से रिप्ले करो, और प्रमाण दिखाओ कि क्या बदला।

हर इनकमिंग ईवेंट के लिए एक छोटा, सुसंगत वेबहुक डिलीवरी रिकॉर्ड रखें। इसे अपने बिजनेस डेटा (ऑर्डर्स, इनवॉइसेस, यूज़र्स) से अलग रखें ताकि आप फेल्यर्स का इंस्पेक्शन बिना प्रोडक्शन स्टेट को छेड़े कर सकें।

कम से कम स्टोर करें:

  • Event ID (प्रदाता से), स्रोत/सिस्टम का नाम, और एंडपॉइंट या हैंडलर का नाम
  • रिसीव्ड टाइम, करंट स्टेटस (new, processing, succeeded, failed), और प्रोसेसिंग अवधि
  • अटेम्प्ट काउंट, अगला रीट्राई टाइम (अगर कोई), आख़िरी एरर मैसेज, और एरर टाइप/कोड
  • कॉरिलेशन IDs जो ईवेंट को आपकी ऑब्जेक्ट्स से जोड़ते हैं (user_id, order_id, invoice_id, ticket_id) साथ में प्रदाता IDs
  • पेलोड हैंडलिंग डिटेल्स: raw payload (या एनक्रिप्टेड ब्लॉब), पेलोड हैश, और स्कीमा/वर्ज़न

कॉरिलेशन IDs वही चीज़ है जो सपोर्ट को प्रभावी बनाती है। एक सपोर्ट एजेंट को "Order 18431" सर्च करके तुरंत हर वेबहुक दिखना चाहिए जो उससे जुड़ा हो, उन फेल्यर्स सहित जिनसे रिकॉर्ड कभी बने ही नहीं।

मैनुअल एक्शन्स के लिए ऑडिट ट्रेल रखें। अगर किसी ने ईवेंट रिप्ले किया, रिकॉर्ड करें किसने, कब, कहाँ से (UI/API), और आउटकम क्या रहा। एक छोटा सा चेंज समरी भी रखें जैसे "invoice marked paid" या "customer record created." एक वाक्य भी विवादों को कम कर देता है।

रिटेंशन मायने रखती है। लॉग सस्ते हैं जब तक वे नहीं होते, और पेलोड में पर्सनल डेटा हो सकता है। एक स्पष्ट नियम बनाएं (उदा., पूरा पेलोड 7–30 दिनों तक, मेटाडेटा 90 दिनों तक) और उसका पालन करें।

आपका एडमिन स्क्रीन जवाब आसान बना दे। इवेंट ID और कॉरिलेशन ID से सर्च, स्टेटस और "needs attention" के लिए फिल्टर्स, अटेम्प्ट्स और एरर्स की टाइमलाइन, एक सुरक्षित रिप्ले बटन कन्फ़र्मेशन के साथ और दिखाई देने वाला idempotency की, और एक्सपोर्टेबल डिटेल्स इनसाइड इंसिडेंट नोट्स के लिए मददगार होते हैं।

डबल चार्ज और डुप्लीकेट रिकॉर्ड्स से कैसे बचें

जहाँ आप ऑपरेट करते हैं, वहीं डिप्लॉय करें
AppMaster Cloud पर या अपनी इंफ्रास्ट्रक्चर पर रीकवरी फ़्लो चलाएँ।
ऐप डिप्लॉय करें

Webhook retries बनाम मैनुअल रिप्ले में सबसे बड़ा रिस्क रीट्राई या रिप्ले का नहीं—बल्कि साइड-एफेक्ट्स को दोहराने का है: कार्ड को दो बार चार्ज करना, दो सब्सक्रिप्शन बनाना, या एक ही ऑर्डर दो बार भेजना।

एक सुरक्षित डिज़ाइन "पैसा मूवमेंट" और "बिजनेस फ़ुलफ़िलमेंट" को अलग करता है। पेमेंट्स के लिए इनको अलग स्टेप्स में रखें: पेमेंट इरादा बनाना (या ऑथराइज़ेशन), उसे कैप्चर करना, फिर फ़ुलफ़िल करना (ऑर्डर को Paid मार्क करना, एक्सेस खोलना, शिप करना)। अगर वेबहुक दो बार आता है, तो दूसरा रन यह देखे कि "पहले ही captured" या "पहले ही fulfilled" है और रुके।

जब आप चार्ज बनाते हैं तो प्रदाता-साइड आइडेम्पोटेंसी का उपयोग करें। अधिकांश पेमेंट प्रदाता एक idempotency की सपोर्ट करते हैं ताकि वही रिक्वेस्ट दूसरा चार्ज बनाने के बजाय वही परिणाम दे। उस की को अपने इंटरनल ऑर्डर के साथ स्टोर करें ताकि retries में उसे दोबारा उपयोग किया जा सके।

अपने डेटाबेस के अंदर भी रिकॉर्ड क्रिएशन आइडेम्पोटेंट बनाएं। सबसे सरल गार्ड एक यूनिक कॉन्स्ट्रेंट है बाहरी इवेंट ID या ऑब्जेक्ट ID (जैसे charge_id, payment_intent_id, subscription_id) पर। जब वही वेबहुक फिर से आए, इन्सर्ट सुरक्षित तरीके से फेल हो और आप "अस्तित्व में लोड करें और जारी रखें" करें।

स्टेट ट्रांज़िशन को गार्ड करें ताकि वे केवल आगे बढ़ें जब करंट स्टेट उम्मीद के अनुरूप हो। उदाहरण: केवल तभी ऑर्डर को pending से paid में बदलें जब वह अभी भी pending हो। अगर पहले से paid है तो कुछ न करें।

आंशिक फेल्यर्स आम हैं: पैसे सफल हो गए, पर आपका DB लिखना फेल हो गया। इसके लिए डिज़ाइन करें—पहले एक ड्यूरेबल "received event" रिकॉर्ड सेव करें, फिर प्रोसेसिंग करें। अगर सपोर्ट बाद में ईवेंट रिप्ले करे, तो आपका हैंडलर बाकी स्टेप्स पूरा कर सकता है बिना फिर से चार्ज किए।

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

सामान्य गलतियाँ और जाल

ज्यादातर रिकवरी योजनाएँ इसलिए फेल होती हैं क्योंकि वे एक वेबहुक को ऐसे बर्ताव करती हैं जैसे उसे फिर से दबाने लायक बटन हो। अगर पहली कोशिश ने पहले ही कुछ बदल दिया, तो दूसरी कोशिश कार्ड को दो बार चार्ज या डुप्लीकेट रिकॉर्ड बना दे सकती है।

एक सामान्य जाल है ईवेंट को स्टोर किए बिना रिप्ले करना। जब सपोर्ट बाद में रिप्ले दबाए, वे आज का पुनर्निर्मित डेटा भेज रहे होते हैं, न कि वही सटीक संदेश जो आया था। इससे ऑडिट टूटता है और बग्स का रीप्रोड्यूस करना मुश्किल हो जाता है।

एक और जाल है टाइमस्टैम्प को आइडेम्पोटेंसी की के रूप में इस्तेमाल करना। दो ईवेंट एक ही सेकंड में हो सकते हैं, क्लॉक्स ड्रिफ्ट कर सकते हैं, और रिप्ले घंटे बाद हो सकता है। आपको आइडेम्पोटेंसी की प्रोवाइडर के यूनिक इवेंट ID से जुड़ी होनी चाहिए (या पेलोड के स्थिर, यूनिक हैश) — समय से नहीं।

रेड फ्लैग्स जो टिकट में बदलते हैं:

  • स्टेट चेक के बिना नॉन-आइडेम्पोटेंट एक्शन्स को रीट्राई करना (उदा., "create invoice" फिर से रन होना भले ही इनवॉयस पहले से मौजूद हो)
  • रीट्राईएबल एरर्स (टाइमआउट, 503) और पर्मानेंट एरर्स (खराब सिग्नेचर, आवश्यक फील्ड गायब) के बीच स्पष्ट विभाजन न होना
  • किसी भी व्यक्ति द्वारा उपयोग किया जा सकने वाला रिप्ले बटन, बिना रोल चेक, बिना कारण फील्ड, और बिना ऑडिट ट्रेल के
  • असल बग्स को छिपाने वाले ऑटोमैटिक रीट्राई लूप्स जो डाउनस्ट्रीम सिस्टम्स को बार-बार हिट करते रहें
  • "Fire and forget" रीट्राई जो प्रयासों को कैप नहीं करते या जब एक ही ईवेंट बार-बार फेल हो तो इंसान को अलर्ट नहीं करते

मिश्रित नीतियों का भी ध्यान रखें। टीम्स कभी-कभी दोनों सिस्टम्स बिना समन्वय के चालू कर देती हैं और अंततः एक ही ईवेंट को दो अलग-अलग मैकेनिज़्म से फिर से भेज देती हैं।

एक साधारण परिदृश्य: एक पेमेंट वेबहुक आपके ऐप पर टाइमआउट हो गया जबकि आपका ऐप ऑर्डर सेव कर रहा था। अगर आपका रीट्राई फिर से "charge customer" करता है बजाय "यह सत्यापित करो कि चार्ज मौजूद है, फिर ऑर्डर को पेड मार्क करो," तो आप महंगा नुकसान कर सकते हैं। सुरक्षित रिप्ले टूल हमेशा पहले करंट स्टेट चेक करता है, फिर सिर्फ़ गायब स्टेप लागू करता है।

शिप करने से पहले एक त्वरित चेकलिस्ट

सुरक्षित रिप्ले टूल शिप करें
एक सपोर्ट-फ्रेंडली रिप्ले स्क्रीन जोड़ें जो वही गार्डेड वर्कफ़्लो दोहराती है।
बनाना शुरू करें

रिकवरी को एक फीचर समझें, बाद की बात नहीं। आपको हमेशा सुरक्षित रूप से फिर से चलाने में सक्षम होना चाहिए, और हमेशा यह समझाने में सक्षम होना चाहिए कि क्या हुआ।

एक प्रायोगिक प्री-लॉन्च चेकलिस्ट:

  • हर वेबहुक ईवेंट को जैसे ही आए पर परसिस्ट करें, बिजनेस लॉजिक चलाने से पहले। रॉ बॉडी, हेडर्स, रिसीव टाइम, और स्थिर बाहरी इवेंट ID स्टोर करें।
  • हर ईवेंट के लिए एक स्थिर idempotency की का उपयोग करें, और हर रीट्राई और मैनुअल रिप्ले में उसे रीयूज़ करें।
  • डेडुप्लिकेशन को डेटाबेस स्तर पर लागू करें। बाहरी IDs (पेमेंट ID, इनवॉइस ID, ईवेंट ID) पर यूनिक कॉन्स्ट्रेंट रखें ताकि दूसरा रन दूसरा रो ना बना सके।
  • रिप्ले को स्पष्ट और पूर्वानुमेय रखें। क्या होगा दिखाएँ और कैप्चर या किसी अपरिवर्तनीय चीज़ के लिए पुष्टि माँगें।
  • एंड-टू-एंड स्पष्ट स्टेटस ट्रैक करें: received, processing, succeeded, failed, ignored। आख़िरी एरर मैसेज, अटेम्प्ट की संख्या, और किसने रिप्ले ट्रिगर किया यह शामिल करें।

इसे खत्म कहने से पहले सपोर्ट प्रश्नों को टेस्ट करें। क्या कोई एक मिनट से कम समय में जवाब दे सकता है: क्या हुआ, क्यों फेल हुआ, और रिप्ले के बाद क्या बदला?

अगर आप यह AppMaster में बना रहे हैं, तो पहले Data Designer में इवेंट लॉग मॉडल करें, फिर एक छोटा एडमिन स्क्रीन जोड़ें जिसमें एक सुरक्षित रिप्ले एक्शन हो जो आइडेम्पोटेंसी चेक करे और कन्फ़र्मेशन दिखाए। यह ऑर्डर यह रोकता है कि "हम बाद में सुरक्षा जोड़ेंगे" कभी "हम सुरक्षित रूप से रिप्ले नहीं कर पा रहे" में बदल जाए।

उदाहरण: एक पेमेंट वेबहुक जो पहली बार फेल और फिर सफल हो

डबल चार्ज रोकें जल्दी से
ऑर्डर, इनवॉइस, और processed_webhooks को यूनिक कॉन्स्ट्रेंट्स के साथ मॉडल करें ताकि डुप्लीकेट रोके जा सकें।
प्रोटोटाइप करें

एक ग्राहक ने भुगतान किया, और आपका पेमेंट प्रदाता payment_succeeded वेबहुक भेजता है। ठीक उसी समय आपका डेटाबेस लोड में है और राइट टाइमआउट हो जाता है। प्रदाता को 500 मिलती है, तो वह बाद में रीट्राई करता है।

यहाँ सुरक्षित रिकवरी कैसी दिखनी चाहिए:

  • 12:01 वेबहुक अटेम्प्ट #1 event ID evt_123 के साथ आता है। आपका हैंडलर शुरू होता है, फिर INSERT invoice पर DB टाइमआउट के कारण फेल होता है। आप 500 लौटाते हैं।
  • 12:05 प्रदाता उसी event ID evt_123 के साथ रीट्राई करता है। आपका हैंडलर पहले डेडुप टेबल चेक करता है, देखता है कि यह लागू नहीं हुआ, इनवॉइस लिखता है, evt_123 को प्रोसेस्ड मार्क करता है, और 200 लौटाता है।

अब अहम बात: आपकी सिस्टम को दोनों डिलीवरीज़ को एक ही ईवेंट मानना चाहिए। इनवॉइस एक बार बनना चाहिए, ऑर्डर एक बार "Paid" होना चाहिए, और कस्टमर को एक ही रसीद मेल होनी चाहिए। अगर प्रदाता सफलता के बाद भी फिर से रीट्राई कर दे (हो सकता है), तो आपका हैंडलर evt_123 को पहले से प्रोसेस्ड पढ़े और एक नो-ऑप के साथ साफ़ 200 लौटाए।

आपके लॉग्स सपोर्ट को घबड़ाने की बजाय आत्मविश्वास देने चाहिए। एक अच्छा रिकॉर्ड दिखाता है कि अटेम्प्ट #1 "DB timeout" पर फेल हुआ, अटेम्प्ट #2 सफल हुआ, और आख़िरी स्टेट "applied" है।

अगर कोई सपोर्ट एजेंट evt_123 के लिए रिप्ले टूल खोलता है, तो उसे नीरस दिखना चाहिए: "Already applied" और रिप्ले बटन (अगर दबाया गया) केवल एक सुरक्षित चेक फिर से चलाएगा, न कि साइड-इफेक्ट्स। कोई डुप्लीकेट इनवॉइस, कोई डुप्लीकेट ईमेल, कोई डबल चार्ज नहीं।

अगले कदम: एक व्यावहारिक रिकवरी फ्लो बनाएं

आप जो भी वेबहुक ईवेंट्स प्राप्त करते हैं, उन्हें लिखकर हर एक को लो-रिस्क या हाई-रिस्क के रूप में मार्क करें। "User signed up" आम तौर पर लो-रिस्क है। "Payment succeeded," "refund issued," और "subscription renewed" हाई-रिस्क हैं क्योंकि गलती महंगा पड़ सकती है या उलझन पैदा कर सकती है जिसे सुधारना मुश्किल है।

फिर सबसे छोटा काम करने योग्य रिकवरी फ्लो बनाएं: हर इनकमिंग ईवेंट स्टोर करें, उसे आइडेम्पोटेंट हैंडलर से प्रोसेस करें, और सपोर्ट के लिए एक छोटा रिप्ले स्क्रीन एक्सपोज़ करें। उद्देश्य कोई शानदार डैशबोर्ड नहीं है—बल्कि एक सुरक्षित तरीका है एक सरल सवाल का जवाब देने का: "क्या हमें मिला, क्या हमने प्रोसेस किया, और अगर नहीं तो क्या हम बिना कुछ डुप्लीकेट किए फिर से कोशिश कर सकते हैं?"

एक साधारण पहला संस्करण:

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

जब यह काम करे, तो जोखिम स्तर के मुताबिक़ सुरक्षा जोड़ें। हाई-रिस्क ईवेंट्स के लिए सख्त परमिशन्स, स्पष्ट कन्फ़र्मेशन्स (उदा., "रिप्ले से fulfillment ट्रिगर हो सकता है। जारी रखें?"), और किसने कब रिप्ले किया उसकी पूरी ऑडिट ट्रेल चाहिए।

यदि आप बिना भारी कोडिंग के यह बनाना चाहते हैं, AppMaster (appmaster.io) इस पैटर्न के लिए व्यावहारिक फिट है: Data Designer में वेबहुक इवेंट्स स्टोर करें, Business Process Editor में आइडेम्पोटेंट वर्कफ़्लो जोड़ें, और UI बिल्डर से एक इंटरनल रिप्ले एडमिन पैनल शिप करें।

डिप्लॉयमेंट जल्दी तय करें क्योंकि यह ऑपरेशंस को प्रभावित करता है। चाहे आप क्लाउड में चलाएं या self-hosted, सुनिश्चित करें कि सपोर्ट सिक्योरली लॉग्स और रिप्ले स्क्रीन तक पहुँच सके, और आपकी रिटेंशन पॉलिसी चार्ज विवाद और ग्राहक प्रश्न हल करने के लिए पर्याप्त इतिहास रखे।

शुरू करना आसान
कुछ बनाएं अद्भुत

फ्री प्लान के साथ ऐपमास्टर के साथ प्रयोग करें।
जब आप तैयार होंगे तब आप उचित सदस्यता चुन सकते हैं।

शुरू हो जाओ