प्रॉम्प्ट और लागू संदर्भ
एक ई-कॉमर्स पेमेंट प्रोसेसिंग सिस्टम डिज़ाइन करें। खरीदार द्वारा ऑर्डर सबमिट करने के बाद, सिस्टम वन-टाइम कार्ड पेमेंट को प्रोसेस करने के लिए एक बाहरी पेमेंट सर्विस प्रोवाइडर का उपयोग करता है। यह चेकआउट पर ऑथराइज़ करता है, इन्वेंटरी रिज़र्व होने के बाद कैप्चर करता है, और यदि ऑर्डर रद्द हो जाता है तो ऑथराइज़ेशन को रिलीज़ कर देता है। कैप्चर के बाद, यह कई आंशिक रिफंड्स का समर्थन करता है, लेकिन उनकी संचयी (cumulative) राशि कभी भी कैप्चर की गई राशि से अधिक नहीं होनी चाहिए। एक पेमेंट मेथड को 3DS जैसे अतिरिक्त प्रमाणीकरण की आवश्यकता हो सकती है, और अंतिम परिणाम ब्राउज़र के वापस आने के बाद आ सकता है।
प्रतिदिन पचास लाख पेमेंट प्रयासों को मान लें, जो औसतन लगभग 58 TPS और पीक पर 500 TPS है। क्रिएट-पेमेंट API का p99 300 मिलीसेकंड से कम है, स्टेटस रीड्स का p99 200 मिलीसेकंड से कम है, और लोकल API का 99.99% मासिक उपलब्धता लक्ष्य है। वह उपलब्धता प्रोवाइडर के पूरा होने का वादा नहीं करती है। पैसा मुद्रा की माइनर यूनिट में एक पूर्णांक (integer) है, और एक पेमेंट में केवल एक ही मुद्रा होती है। प्रोवाइडर, नेटवर्क और लोकल प्रोसेस सभी विफल हो सकते हैं। ये संख्याएं और समय-सीमाएं इंटरव्यू की मान्यताएं हैं, किसी पेमेंट उत्पाद द्वारा किए गए वादे नहीं।
दायरे में पेमेंट क्रिएशन, अतिरिक्त प्रमाणीकरण, ऑथराइज़ेशन, कैप्चर, ऑथराइज़ेशन रद्दीकरण, आंशिक और पूर्ण रिफंड, मनी लेजर, प्रोवाइडर वेबहुक्स और रिकॉन्सिलीएशन शामिल हैं। चार्जबैक (chargebacks), एक फ्रॉड मॉडल, विदेशी मुद्रा (foreign exchange), मर्चेंट पेआउट, टैक्स और एक संपूर्ण PCI अनुपालन कार्यक्रम दायरे से बाहर हैं, लेकिन उत्तर में उन सीमाओं की पहचान होनी चाहिए। प्रोवाइडर का होस्टेड पेज या टोकनाइज़ेशन कंपोनेंट कार्ड विवरण एकत्र करता है। यह सिस्टम एक पेमेंट मेथड टोकन स्टोर करता है और इसे रॉ कार्ड नंबर या सुरक्षा कोड प्राप्त या लॉग नहीं करना चाहिए।
इंटरव्यूअर क्या मूल्यांकन करता है
पहला संकेत यह है कि क्या उम्मीदवार व्यावसायिक उद्देश्य (business intent), प्रोवाइडर प्रयासों और मनी फैक्ट्स (money facts) को अलग करता है। एक कार्ट एक आंतरिक payment_id में मैप होता है, लेकिन इसमें कई प्रमाणीकरण या प्रोवाइडर प्रयास हो सकते हैं। टाइम-आउट रिक्वेस्ट का मतलब यह भी नहीं है कि पेमेंट विफल हो गया है। एक मजबूत उत्तर पूरे लाइफसाइकिल को paid=true में संकुचित नहीं करता है। यह पेमेंट एग्रीगेट, प्रत्येक ऑपरेशन और अज्ञात परिणाम, प्रोवाइडर संदर्भ और लेजर प्रविष्टियों को अलग-अलग स्टोर करता है।
दूसरा संकेत एक वितरित सीमा (distributed boundary) के पार सटीक तर्क है। डेटाबेस ट्रांजेक्शन बाहरी पेमेंट प्रोवाइडर को परमाणु रूप से (atomically) शामिल नहीं कर सकता है। प्रोवाइडर तब कैप्चर कर सकता है जब उसकी प्रतिक्रिया खो जाती है, एक वेबहुक सिंक्रोनस प्रतिक्रिया से पहले आ सकता है, या एक प्रक्रिया लोकल कमिट के बाद क्रैश हो सकती है। कॉलर इडेम्पोटेन्सी कीज़, आंतरिक ऑपरेशन IDs, प्रोवाइडर इडेम्पोटेन्सी कीज़, एक ट्रांजेक्शनल आउटबॉक्स, वेबहुक डुप्लीकेशन और स्टेटस लुकअप बार-बार निष्पादन को कन्वर्ज (converge) करते हैं। वे एंड-टू-एंड बिल्कुल-एक-बार (exactly-once) ट्रांजेक्शन नहीं बनाते हैं।
तीसरा संकेत एक मोनोटोनिक, ऑडिट करने योग्य स्टेट मशीन है। ऑथराइज़ेशन और कैप्चर पैसे के अलग-अलग चरण हैं। REQUIRES_ACTION कोई विफलता नहीं है, और एक प्रोवाइडर टाइमआउट जो UNKNOWN ऑपरेशन उत्पन्न करता है, वह पेमेंट को तुरंत विफल नहीं कर सकता है। रिफंड को एक कैप्चर किए गए पेमेंट को संदर्भित करना चाहिए, सटीक पैसे का उपयोग करना चाहिए, और इस इनवेरिएंट को बनाए रखना चाहिए कि पुष्ट (confirmed) प्लस इन-फ्लाइट रिफंड समवर्तीता (concurrency) के तहत कैप्चर की गई राशि से अधिक न हों।
चौथा संकेत वर्कफ़्लो स्टेट और अकाउंटिंग के बीच का विभाजन है। पेमेंट टेबल उत्तर देती है कि उपयोगकर्ता आगे क्या कर सकता है। केवल-जोड़ने योग्य (append-only) लेजर उत्तर देता है कि शेष राशि का वर्तमान मूल्य क्यों है। पोस्ट किए गए फैक्ट्स को कभी भी यथास्थान (in place) संपादित नहीं किया जाता है; रिफंड और सुधार रिवर्सिंग या क्षतिपूर्ति प्रविष्टियां जोड़ते हैं। प्रत्येक जर्नल के डेबिट, क्रेडिट, मुद्रा और व्यावसायिक संदर्भ को ट्रांजेक्शनल रूप से मान्य किया जाता है और फिर प्रोवाइडर रिपोर्ट और बैंक जमा के साथ रिकॉन्साइल किया जाता है।
अंतिम संकेत सुरक्षा और असत्यता-परीक्षण क्षमता (falsifiability) है। उत्तर में कार्ड-डेटा एक्सपोज़र को कम करना चाहिए, वेबहुक हस्ताक्षरों को सत्यापित करना चाहिए, प्रोवाइडर सीक्रेट्स की रक्षा करनी चाहिए, अनुमतियों और लॉग को बाधित करना चाहिए, और खोई हुई प्रतिक्रियाओं, डुप्लीकेट या क्रम-रहित (out-of-order) वेबहुक्स, समवर्ती कैप्चर और रिफंड, असंतुलित जर्नल्स और रिकॉन्सिलीएशन विसंगतियों को इंजेक्ट करना चाहिए। बिना इनवेरिएंट्स, रिकवरी पाथ्स और सत्यापन के एक सर्विस आरेख शुद्धता का प्रदर्शन नहीं करता है।
उत्तर देने से पहले स्पष्ट करने योग्य प्रश्न
- कार्ड डेटा कौन एकत्र करता है? यह प्रॉम्प्ट प्रोवाइडर के होस्टेड पेज या टोकनाइज़ेशन कंपोनेंट का उपयोग करता है। बिजनेस बैकएंड केवल एक पेमेंट मेथड टोकन प्राप्त करता है और रॉ कार्ड नंबर, ट्रैक डेटा, पिन या सुरक्षा कोड स्टोर नहीं करता है। एक कंप्लायंस टीम को अभी भी वास्तविक PCI दायरे की पुष्टि करनी होगी।
- ऑथराइज़ेशन और कैप्चर कब होते हैं? ऑर्डर सबमिशन पर ऑथराइज़ करें और इन्वेंटरी रिज़र्वेशन के बाद कैप्चर करें। यदि इन्वेंटरी विफल हो जाती है तो समाप्ति से पहले रद्द करें। एक कैपेबिलिटी टेबल यह निर्धारित करती है कि क्या कोई पेमेंट मेथड विलंबित कैप्चर का समर्थन करता है; डिज़ाइन यह नहीं मान सकता कि सभी मेथड ऐसा करते हैं।
- सफलता क्या स्थापित करती है? ब्राउज़र रीडायरेक्ट केवल एक उपयोगकर्ता-अनुभव संकेत है और पूर्ति (fulfillment) को अधिकृत नहीं कर सकता है। एक प्रमाणित प्रोवाइडर प्रतिक्रिया, वेबहुक, या सक्रिय क्वेरी आधिकारिक प्रमाण की आपूर्ति करती है, जिसे व्यावसायिक कार्रवाई होने से पहले लोकल स्टेट मशीन को स्वीकार करना होगा।
- रिफंड अनुबंध (contract) क्या है? कई आंशिक रिफंड और एक पूर्ण रिफंड का समर्थन करें, जो कभी भी कैप्चर से अधिक न हो। मूल पेमेंट के बिना कोई स्टैंडअलोन रिफंड नहीं है। एक रिफंड एसिंक्रोनस रूप से पूरा हो सकता है या प्रोवाइडर द्वारा अस्वीकार किया जा सकता है।
- क्या हमें कई प्रोवाइडर्स की आवश्यकता है? संस्करण एक में एक प्रोवाइडर है, लेकिन इंटरफ़ेस एक आंतरिक ऑपरेशन ID और प्रोवाइडर संदर्भ स्टोर करता है। परिणाम अज्ञात होने पर कभी भी स्वचालित रूप से फ़ेलओवर न करें, क्योंकि दोनों प्रोवाइडर्स चार्ज कर सकते हैं।
- लेजर में क्या शामिल है? यह प्रॉम्प्ट प्रोसेसर प्राप्य (receivable) और मर्चेंट देय (payable) रिकॉर्ड करता है। प्रोवाइडर फीस, मर्चेंट पेआउट और टैक्स दायरे से बाहर हैं। प्रत्येक मुद्रा स्वतंत्र रूप से संतुलित होती है; लेजर में किसी फ़्लोटिंग-पॉइंट मनी या अंतर्निहित विनिमय दर की अनुमति नहीं है।
- प्रतिधारण (retention) और ऑडिट आवश्यकताएं क्या हैं? संवेदनशील पेलोड तक पहुंच को कम करने, एन्क्रिप्ट करने और ऑडिट करने के साथ-साथ नियामक और कंपनी नीति के अनुसार पेमेंट्स, ऑपरेशन्स, वेबहुक प्राप्तियों और लेजर संदर्भों को बनाए रखें। PCI SSC ऑथराइज़ेशन के बाद संवेदनशील प्रमाणीकरण डेटा को संग्रहीत करने से रोकता है, भले ही वह एन्क्रिप्टेड हो।
- उपलब्धता और निरंतरता में क्या ट्रेड-ऑफ़ है? यदि प्रोवाइडर अनुपलब्ध है, तो सिस्टम काम स्वीकार कर सकता है और "प्रोसेसिंग" दिखा सकता है, लेकिन यह गलत सफलता नहीं दिखा सकता है। पैसे की शुद्धता और ट्रैसेबिलिटी एक त्वरित टर्मिनल प्रतिक्रिया पर प्राथमिकता लेती है।
30-सेकंड उत्तर रूपरेखा
"मैं एक पेमेंट इंटेंट के लिए एक स्थिर payment_id का उपयोग करूंगा और पेमेंट स्टेट को ऑथराइज़, कैप्चर और रिफंड ऑपरेशन्स से अलग करूंगा। कॉलर इडेम्पोटेन्सी कीज़ परमाणु रूप से रिक्वेस्ट डाइजेस्ट, ऑपरेशन और आउटबॉक्स को स्टोर करती हैं; वर्कर प्रोवाइडर पर ऑपरेशन ID का पुन: उपयोग करता है। एक टाइमआउट UNKNOWN बन जाता है और एक नए चार्ज के बजाय सत्यापित वेबहुक्स, लुकअप और रिकॉन्सिलीएशन के माध्यम से कन्वर्ज होता है। आधिकारिक परिणाम एक मोनोटोनिक स्टेट मशीन को आगे बढ़ाते हैं और परमाणु रूप से एक संतुलित जर्नल और बिजनेस इवेंट जोड़ते हैं। रिफंड निर्माण सशर्त रूप से शेष रिफंडेबल मूल्य को रिज़र्व करता है। प्रोवाइडर रिपोर्ट और बैंक जमा फिर आंतरिक लेजर को रिकॉन्साइल करते हैं। प्रोवाइडर टोकनाइज़ेशन कार्ड डेटा को बैकएंड से बाहर रखता है, और ब्राउज़र सफलता पृष्ठ पूर्ति को ट्रिगर नहीं कर सकता है।"
चरण-दर-चरण गहन विश्लेषण
चरण 1: क्षमता, इनवेरिएंट्स और स्वामित्व से शुरू करें
पचास लाख को 86,400 सेकंड से विभाजित करने पर लगभग 58 TPS प्राप्त होता है। 500 TPS पीक के लिए पहले दिन प्रत्येक टेबल को शार्ड करने की आवश्यकता नहीं होती है। एक बाहरी सीमा के पार शुद्धता, ऑडिटेबिलिटी और रिकवरी इस डिज़ाइन पर हावी हैं। पेमेंट API क्षैतिज रूप से (horizontally) स्केल करता है, एक रिलेशनल डेटाबेस आधिकारिक स्टेट रखता है, और payment_id द्वारा रूट की गई एक ड्यूरेबल कतार पीक को अवशोषित करती है और प्रोवाइडर लेटेंसी को अलग करती है। पहले इनवेरिएंट्स बताएं:
amount > 0
currency is immutable after the first provider attempt
captured_amount <= authorized_amount
refunded_amount + pending_refund_amount <= captured_amount
for every journal: sum(debits) == sum(credits), per currency
one merchant + one idempotency_key describes one immutable request intent
one successful business operation produces at most one journal referenceइस पैमाने पर, एक राइट क्षेत्र और फ़ेलओवर वाला एक रिलेशनल डेटाबेस एक्टिव-एक्टिव मल्टी-रीजन राइट्स की तुलना में इडेम्पोटेन्सी कीज़, स्टेट वर्जन्स और लेजर ऑर्डरिंग को संरक्षित करना आसान बनाता है। एक्टिव-एक्टिव क्षेत्रीय फ़ेलओवर समय को कम कर सकता है, लेकिन इसे एक ही की के समवर्ती उपयोग और परस्पर विरोधी मनी ऑपरेशन्स को हल करना होगा; यह केवल एक स्पष्ट क्षेत्रीय उपलब्धता आवश्यकता द्वारा उचित है। पूर्ण इवेंट सोर्सिंग भी इतिहास को संरक्षित करती है लेकिन पेमेंट वर्कफ़्लो में रीप्ले, स्कीमा माइग्रेशन और क्वेरी जटिलता फैलाती है। यह डिज़ाइन केवल मनी जर्नल्स को अपेंड-ओनली रखता है और वर्कफ़्लो स्टेट के लिए एक वर्ज़न किए गए वर्तमान एग्रीगेट का उपयोग करता है, जो ऑडिट लाभ को परिचालन लागत से मिलाता है।
ऑर्डर सर्विस इन्वेंटरी और पूर्ति का मालिक है। पेमेंट सर्विस पेमेंट स्टेट, ऑपरेशन्स और मनी फैक्ट्स के संदर्भों की मालिक है। प्रोवाइडर कार्ड-नेटवर्क स्टेट का मालिक है। लेजर आंतरिक मनी फैक्ट्स का मालिक है। ऑर्डर सर्विस सीधे पेमेंट पंक्तियाँ नहीं लिख सकती है, और एक पेमेंट वेबहुक सीधे किसी ऑर्डर को शिप्ड के रूप में चिह्नित नहीं कर सकता है। पेमेंट सर्विस स्थिर बिजनेस इवेंट्स प्रकाशित करती है जिन्हें ऑर्डर सर्विस payment_id द्वारा इडेम्पोटेंट तरीके से उपभोग करती है।
चरण 2: APIs, इडेम्पोटेन्सी सेशन और डेटा मॉडल को परिभाषित करें
कोर इंटरफ़ेस हो सकता है:
POST /payments create one payment for an order
POST /payments/{id}/capture capture an authorized amount
POST /payments/{id}/cancel cancel an uncaptured authorization
POST /payments/{id}/refunds request a partial or full refund
GET /payments/{id} return current status and allowed next actions
POST /provider/webhooks persist a verified provider eventपैसे बदलने वाले प्रत्येक कॉल के लिए कॉलर द्वारा प्रदान की गई इडेम्पोटेन्सी की की आवश्यकता होती है। (merchant_id, operation_type, idempotency_key) पर एक यूनीक कंस्ट्रेंट एक सामान्यीकृत रिक्वेस्ट डाइजेस्ट, इन-प्रोग्रेस स्टेट और रीप्ले करने योग्य प्रतिक्रिया की रक्षा करता है। पहला अनुरोध एक डेटाबेस ट्रांजेक्शन में payments, payment_operations, और एक आउटबॉक्स रिकॉर्ड बनाता है। वही की और डाइजेस्ट ज्ञात प्रतिक्रिया को रीप्ले करते हैं। एक अलग राशि, मुद्रा, पेमेंट या ऑपरेशन प्रकार के साथ समान की एक संघर्ष (conflict) लौटाती है। Amazon का फर्स्ट-पार्टी इंजीनियरिंग मार्गदर्शन भी कॉलर द्वारा प्रदान की गई रिक्वेस्ट ID और एक ACID सीमा की सिफारिश करता है जिसमें ID और म्यूटेशन दोनों शामिल हैं; भिन्न इंटेंट वाली पुन: उपयोग की गई ID को अस्वीकार कर दिया जाता है।
जिम्मेदारियों को अलग-अलग स्टोर करें:
payments: ऑर्डर संदर्भ, राशि, मुद्रा, एग्रीगेट स्टेट, अधिकृत/कैप्चर किए गए/रिफंड किए गए कुल, और वर्ज़न;payment_operations: प्रकार, ऑपरेशन ID, अनुरोधित राशि, स्टेट, प्रोवाइडर, प्रोवाइडर संदर्भ, प्रयास, और अज्ञात कारण;provider_events: प्रोवाइडर इवेंट ID, हस्ताक्षर परिणाम, प्राप्त समय, एन्क्रिप्टेड पेलोड संदर्भ, और प्रोसेसिंग स्टेट;journal_entries: जर्नल ID, खाता, डेबिट या क्रेडिट, राशि, मुद्रा, और ऑपरेशन संदर्भ;outbox_events: स्थानीय रूप से कमिट किया गया और प्रकाशन की प्रतीक्षा कर रहा एक बिजनेस इवेंट।
आंतरिक ऑपरेशन ID प्रोवाइडर इडेम्पोटेन्सी की बन सकती है। Adyen पेमेंट टाइमआउट के बाद उसी की के साथ सुरक्षित रिट्राई का दस्तावेजीकरण करता है, साथ ही की स्कोप, प्रतिधारण और क्रॉस-रीजन सीमाओं का भी दस्तावेजीकरण करता है। इसलिए सिस्टम UUID को स्थायी, वैश्विक गारंटी के रूप में मानने के बजाय वास्तविक प्रोवाइडर अनुबंध को मॉडल करता है।
चरण 3: पेमेंट और ऑपरेशन को दो स्टेट मशीनों के रूप में मॉडल करें
पेमेंट एग्रीगेट ऑर्डर- और यूजर-फेसिंग लाइफसाइकिल है:
CREATED -> REQUIRES_ACTION -> AUTHORIZED -> CAPTURED
\-> FAILED \-> CANCELED
CAPTURED -> PARTIALLY_REFUNDED -> REFUNDEDप्रत्येक ऑथराइज़, कैप्चर, कैंसल या रिफंड का एक स्वतंत्र ऑपरेशन लाइफसाइकिल होता है:
PENDING -> SUCCEEDED | FAILED | UNKNOWN
UNKNOWN -> SUCCEEDED | FAILED (after query, webhook, or reconciliation)FAILED का अर्थ है कि आधिकारिक साक्ष्य कहते हैं कि यह ऑपरेशन बाद में सफल नहीं होगा। नेटवर्क टाइमआउट, 5xx, या खोई हुई प्रतिक्रिया UNKNOWN है। एग्रीगेट केवल वैध मोनोटोनिक ट्रांज़िशन स्वीकार करता है। एक पुरानी स्टेट की रिपोर्ट करने वाले वेबहुक को ऑडिट के लिए बनाए रखा जाता है, लेकिन यह एग्रीगेट को पीछे नहीं ले जा सकता है। जब एक वेबहुक और सक्रिय क्वेरी में रेस होती है, तो एक पंक्ति वर्ज़न या सशर्त अपडेट केवल एक बार ट्रांज़िशन को कमिट करता है। Stripe एक पेमेंट इंटेंट को निर्माण से लेकर चेकआउट तक फैले एक संसाधन के रूप में प्रलेखित करता है, जिसमें अतिरिक्त प्रमाणीकरण शामिल है, और एक मैनुअल-कैप्चर पेमेंट कैप्चर से पहले कैप्चर करने योग्य बन जाता है। यह पेमेंट को एक HTTP प्रतिक्रिया के बराबर मानने के बजाय एक दीर्घकालिक पेमेंट संसाधन का समर्थन करता है।
ऑर्डर ऑथराइज़ेशन इन्वेंटरी पुष्टिकरण से अलग है। इन्वेंटरी की सफलता कैप्चर को ट्रिगर करती है, जबकि विफलता रद्दीकरण को ट्रिगर करती है। वे ऑपरेशन्स रेस कर सकते हैं, इसलिए एक सशर्त डेटाबेस अपडेट केवल एक को वर्तमान AUTHORIZED वर्ज़न का दावा करने की अनुमति देता है। प्रोवाइडर कॉल वापस आने से पहले एक वेबहुक आ सकता है। सिंक्रोनस प्रतिक्रिया और वेबहुक दोनों को दो ट्रांज़िशन पथों को लागू करने के बजाय एक ही स्टेट-एप्लिकेशन फ़ंक्शन में प्रवेश करना होगा।
चरण 4: बाहरी गैर-परमाणुता (non-atomicity) को स्वीकार करें और वर्कफ़्लो को कन्वर्ज करें
एक लोकल ट्रांजेक्शन आउटबॉक्स के साथ ऑपरेशन स्टेट को कमिट करता है। रिले कम से कम एक बार प्रकाशित होता है, और एक वर्कर ऑपरेशन ID द्वारा दावा करता है। वर्कर प्रोवाइडर इडेम्पोटेन्सी की के रूप में उस ID का पुन: उपयोग करता है और बाउंडेड कनेक्शन, रिक्वेस्ट और कुल समय-सीमा लागू करता है। एक निश्चित परिणाम प्रोवाइडर संदर्भ और एक प्रतिक्रिया डाइजेस्ट को सहेजता है। खोई हुई प्रतिक्रिया UNKNOWN को चिह्नित करती है और स्टेटस लुकअप को शेड्यूल करती है। यह कभी भी नया ऑपरेशन नहीं बनाता है या आँख मूंदकर प्रोवाइडर को स्विच नहीं करता है।
तीन महत्वपूर्ण क्रैश विंडो हैं:
- लोकल ट्रांजेक्शन कमिट होने से पहले एक क्रैश कोई दृश्यमान ऑपरेशन नहीं छोड़ता है, इसलिए कॉलर उसी की के साथ पुन: प्रयास करता है।
- आउटबॉक्स कमिट के बाद खोई हुई प्रकाशन पावती रिले को फिर से प्रकाशित करने के लिए मजबूर करती है; वर्कर उसी ऑपरेशन का दावा करता है।
- खोई हुई प्रतिक्रिया के साथ प्रोवाइडर की सफलता कन्वर्ज करने के लिए उसी प्रोवाइडर की, प्रोवाइडर-संदर्भ लुकअप, या वेबहुक का उपयोग करती है।
यह एक इंटेंट की रिट्राई करने योग्य और ऑडिट करने योग्य अभिव्यक्ति की आपूर्ति करता है, कंपनियों के बीच ट्रांजेक्शन की नहीं। यदि प्रोवाइडर की इडेम्पोटेन्सी प्रतिधारण विंडो के बाद भी परिणाम अज्ञात है, तो स्वचालित रिट्राइज़ बंद हो जाते हैं। प्रोवाइडर रिपोर्ट और एक ऑपरेटर को परिणाम स्थापित करना होगा; केवल बीता हुआ समय विफलता साबित नहीं करता है।
चरण 5: एसिंक्रोनस वेबहुक्स को सुरक्षित रूप से प्राप्त करें और पुन: व्यवस्थित करने (reordering) को सहन करें
एंडपॉइंट रॉ रिक्वेस्ट बॉडी को बनाए रखता है और वर्तमान और रोटेशन-अवधि के पुराने सीक्रेट्स के साथ इसके हस्ताक्षर और टाइमस्टैम्प विंडो को सत्यापित करता है। यह अमान्य हस्ताक्षरों को अस्वीकार करता है। एक यूनीक (provider, provider_event_id) रसीद बनी रहती है, जिसके बाद एंडपॉइंट जल्दी से 2xx लौटाता है और एसिंक्रोनस प्रोसेसिंग को कतारबद्ध करता है। लॉग्स में इवेंट IDs, प्रोवाइडर संदर्भ और कारण कोड होते हैं, पूर्ण संवेदनशील पेलोड या सीक्रेट्स नहीं।
वेबहुक्स डुप्लीकेट, विलंबित और पुन: व्यवस्थित हो सकते हैं। Stripe स्पष्ट रूप से स्वचालित लाइव-मोड रिट्राइज़ और किसी इवेंट ऑर्डरिंग गारंटी का दस्तावेजीकरण नहीं करता है। एक हैंडलर यह नहीं मान सकता कि ऑथराइज़ेशन हमेशा कैप्चर से पहले आता है। यह इवेंट के ऑब्जेक्ट संदर्भ के माध्यम से प्रोवाइडर के वर्तमान संसाधन को पुनः प्राप्त कर सकता है, या बाहरी फैक्ट को अनुमत लोकल ट्रांज़िशन में मैप कर सकता है। प्रत्येक इवेंट उसी ऑपरेशन ID या प्रोवाइडर संदर्भ के माध्यम से डुप्लीकेट हटाता है। एक पोस्ट किया गया कैप्चर दो बार पोस्ट नहीं किया जा सकता है, और एक पुराना ऑथराइज़ेशन CAPTURED को AUTHORIZED में डिमोट नहीं कर सकता है।
ब्राउज़र केवल लोकल पेमेंट स्टेट को पोल करता है या सब्सक्राइब करता है। रिटर्न URL पर एक "सफलता" पैरामीटर किसी ऑर्डर को पूरा नहीं कर सकता है, और क्लाइंट CAPTURED सबमिट नहीं कर सकता है। आधिकारिक कैप्चर सफलता और लेजर कमिट के बाद, पेमेंट सर्विस आउटबॉक्स के माध्यम से PaymentCaptured प्रकाशित करती है। ऑर्डर सर्विस इवेंट ID द्वारा इडेम्पोटेंट तरीके से पूरा करती है।
चरण 6: एक अपेंड-ओनली लेजर के साथ मनी फैक्ट्स व्यक्त करें
पेमेंट स्टेट एक परिचालन दृश्य है; लेजर मनी ऑडिट रिकॉर्ड है। यह प्रॉम्प्ट अकाउंटिंग को दो खातों में सरल बनाता है: प्रोसेसर प्राप्य एक संपत्ति (asset) है और मर्चेंट देय एक दायित्व (liability) है। एक CNY 100.00 कैप्चर, जहां माइनर यूनिट fen है, पोस्ट करता है:
journal capture-<operation_id>, CNY
debit processor_receivable 10000
credit merchant_payable 10000एक CNY 30.00 रिफंड एक रिवर्सिंग जर्नल जोड़ता है:
journal refund-<operation_id>, CNY
debit merchant_payable 3000
credit processor_receivable 3000प्रत्येक जर्नल में कम से कम दो प्रविष्टियाँ और प्रति मुद्रा समान डेबिट और क्रेडिट कुल होते हैं। इसका journal_id और व्यावसायिक ऑपरेशन संदर्भ अद्वितीय हैं। ट्रांजेक्शन जो आधिकारिक स्टेट को CAPTURED या एक सफल रिफंड में आगे बढ़ाता है, वह जर्नल और आउटबॉक्स इवेंट भी सम्मिलित करता है। यदि शुल्क, चार्जबैक या मर्चेंट पेआउट दायरे में आते हैं, तो स्पष्ट खाते और नई प्रविष्टियां जोड़ें; पुरानी प्रविष्टियों को कभी दोबारा न लिखें। शेष प्रविष्टियों से प्राप्त होते हैं या पुनर्निर्माण योग्य प्रोजेक्शन द्वारा त्वरित होते हैं। प्रोजेक्शन मनी सोर्स ऑफ ट्रुथ नहीं बन सकता।
समवर्ती रिफंड पहले पेमेंट पंक्ति पर सशर्त रूप से क्षमता का दावा करते हैं। एक नया ऑपरेशन और इन-फ्लाइट राशि में वृद्धि की अनुमति केवल तभी दी जाती है जब captured_amount - refunded_amount - pending_refund_amount पर्याप्त हो। सफलता राशि को पेंडिंग से रिफंडेड में ले जाती है, निश्चित विफलता इसे रिलीज़ करती है, और अज्ञात रिज़र्वेशन को बरकरार रखता है। यह दूसरे रिफंड को सीमा से अधिक होने से रोकता है। एक प्रोवाइडर अपनी खुद की रिफंड सीमा लागू कर सकता है, लेकिन लोकल इनवेरिएंट उस बाहरी बैकस्टॉप पर निर्भर नहीं हो सकता है।
चरण 7: मौन विसंगतियों को रिकॉन्साइल करें और उन्हें सुरक्षित रूप से ठीक करें
रीयल-टाइम पाथ यह साबित नहीं कर सकता कि कभी कुछ छूटा ही नहीं। पहली रिकॉन्सिलीएशन लेयर प्रोवाइडर संदर्भ या इडेम्पोटेन्सी की द्वारा UNKNOWN ऑपरेशन्स को हल करती है और राशि, मुद्रा, ऑपरेशन प्रकार और टर्मिनल स्टेट की तुलना करती है। दूसरा दैनिक रूप से इम्यूटेबल प्रोवाइडर ट्रांजेक्शन या सेटलमेंट रिपोर्ट लोड करता है और पेमेंट, ऑपरेशन, जर्नल और ऑर्डर संदर्भों का मिलान करता है। तीसरा प्रोवाइडर सेटलमेंट बैचों का वास्तविक बैंक जमाओं से मिलान करता है और अनसेटल राशि, शुल्क, रिफंड और चार्जबैक को अलग करता है।
विसंगतियों को केवल-बाहरी (external-only), आंतरिक-सफलता/बाहरी-गायब, गलत राशि या मुद्रा, पुरानी स्टेट, डुप्लीकेट संदर्भ, असंतुलित लेजर, या गायब सेटलमेंट आइटम के रूप में वर्गीकृत करें। एक उच्च-जोखिम वाली विसंगति प्रभावित मर्चेंट बैलेंस की रिलीज़ को रोकती है और अलर्ट करती है। रिपेयरर इडेम्पोटेंट है: पहले से पुष्टि किए गए प्रोवाइडर ऑपरेशन को इम्पोर्ट करने से ऑडिट कारण के साथ एक नया जर्नल जुड़ जाता है, जबकि अकाउंटिंग सुधार इतिहास पर UPDATE के बजाय क्षतिपूर्ति जर्नल का उपयोग करता है। Stripe का रिपोर्टिंग दस्तावेज़ बैलेंस ट्रांज़ेक्शन को इम्यूटेबल बताता है, जिसमें एक नया रिफंड ट्रांज़ेक्शन मूल फैक्ट को नकारता है, और पेमेंट्स, पेआउट बैचों और बैंक प्राप्तियों को अलग से रिकॉन्साइल करता है।
मेट्रिक्स API सफलता और p99, पेमेंट-स्टेट वितरण, UNKNOWN ऑपरेशन्स की संख्या और आयु, प्रोवाइडर त्रुटियां और थ्रॉटलिंग, वेबहुक हस्ताक्षर विफलताएं/डुप्लीकेट्स/देरी, ऑथराइज़ेशन-टू-कैप्चर समय, रिज़र्व रिफंड क्षमता, आउटबॉक्स और कतार बैकलॉग, अस्वीकृत असंतुलित जर्नल्स, विसंगति गणना, और सबसे पुरानी अनसुलझी विसंगति को अलग करते हैं। बिजनेस रिपोर्टिंग ऑथराइज़ेशन, कैप्चर, रिफंड और सेटलमेंट दरों को अलग रखती है। "अनुरोध स्वीकृत" को "प्राप्त धन" के रूप में नहीं गिना जाना चाहिए।
चरण 8: संवेदनशील सतह को कम करें और विफलताएं इंजेक्ट करें
प्रोवाइडर का टोकनाइज़ेशन कंपोनेंट सीधे कार्ड डेटा एकत्र करता है। बैकएंड केवल एक अपरिवर्तनीय प्रोवाइडर टोकन और स्वीकृत प्रदर्शन फ़ील्ड जैसे ब्रांड और अंतिम चार अंक स्टोर करता है। क्लाइंट सीक्रेट्स कभी भी URLs या लॉग्स में प्रवेश नहीं करते हैं। प्रोवाइडर कीज़ को एक नियंत्रित सीक्रेट सिस्टम में रखा और घुमाया (rotated) जाता है। वेबहुक सीक्रेट्स अलग हैं, और सैंडबॉक्स और प्रोडक्शन अलग-थलग हैं। पेमेंट्स देखना, रिफंड शुरू करना, लेजर पढ़ना और मैनुअल मरम्मत करना अलग-अलग अनुमतियों का उपयोग करता है। प्रत्येक उच्च-जोखिम वाली कार्रवाई ऑपरेटर और कारण को रिकॉर्ड करती है।
PCI SSC ऑथराइज़ेशन के बाद कार्ड सत्यापन कोड, पिन और पिन ब्लॉक को बनाए रखने से स्पष्ट रूप से रोकता है, भले ही वे एन्क्रिप्टेड हों। होस्ट किया गया संग्रह इस प्रॉम्प्ट के एक्सपोज़र को कम करता है, लेकिन एक औपचारिक मूल्यांकन अभी भी अनुपालन निर्धारित करता है। एक साक्षात्कार उत्तर यह दावा नहीं कर सकता कि "टोकन का उपयोग करने से PCI हट जाता है।"
स्वीकृति परीक्षणों में एक ही की का पुन: प्रयास करने वाला क्लाइंट और उस की के तहत राशि बदलना शामिल है; खोई हुई प्रतिक्रिया के साथ प्रोवाइडर की सफलता; API प्रतिक्रिया से पहले वेबहुक का आगमन; डुप्लीकेट, पुन: व्यवस्थित और विलंबित वेबहुक्स; डुप्लीकेट आउटबॉक्स प्रकाशन; ऑथराइज़ेशन रद्दीकरण के साथ रेस करना; समान क्षमता के लिए प्रतिस्पर्धा करने वाले दो रिफंड; आंशिक रिफंड के बाद पूर्ण रिफंड; प्रोवाइडर इडेम्पोटेन्सी समाप्ति; वेबहुक-सीक्रेट रोटेशन; एकतरफा जर्नल की अस्वीकृति; रिकॉन्सिलीएशन द्वारा पाया गया केवल-बाहरी ट्रांजेक्शन; बार-बार रिपेयर निष्पादन; और लंबे समय तक कतार या प्रोवाइडर आउटेज के बाद कैच-अप। प्रत्येक परिदृश्य पेमेंट स्टेट, ऑपरेशन स्टेट, जर्नल गणना, ऑर्डर साइड इफेक्ट्स और अलर्ट का दावा करता है।
उच्च गुणवत्ता वाला नमूना उत्तर
"मैं पेमेंट को एक HTTP कॉल के बजाय एक दीर्घकालिक व्यावसायिक संसाधन के रूप में मॉडल करूंगा। एक ऑर्डर का एक स्थिर payment_id होता है। एग्रीगेट राशि, मुद्रा और ऑथराइज़ेशन/कैप्चर/रिफंड स्टेट स्टोर करता है। प्रत्येक ऑथराइज़, कैप्चर, कैंसल और रिफंड एक अलग ऑपरेशन ID और PENDING, SUCCEEDED, FAILED, या UNKNOWN का उपयोग करता है। एक बाहरी टाइमआउट UNKNOWN बन जाता है; यह तुरंत विफल नहीं हो सकता या प्रोवाइडर स्विच नहीं कर सकता।
पेमेंट निर्माण और प्रत्येक मनी ऑपरेशन के लिए कॉलर इडेम्पोटेन्सी की की आवश्यकता होती है। मर्चेंट, ऑपरेशन प्रकार और की अद्वितीय हैं। पहला अनुरोध परमाणु रूप से इसके डाइजेस्ट, पेमेंट या ऑपरेशन और आउटबॉक्स को स्टोर करता है; वही अनुरोध अपने परिणाम को रीप्ले करता है, जबकि की के तहत एक अलग राशि या मुद्रा संघर्ष करती है। एक वर्कर आंतरिक ऑपरेशन ID का उपयोग प्रोवाइडर की के रूप में करता है। आउटबॉक्स, कतार और वर्कर सभी कम से कम एक बार हैं, और वही ऑपरेशन एक आधिकारिक ट्रांज़िशन लागू करता है।
प्रोवाइडर की सिंक्रोनस प्रतिक्रिया, एक हस्ताक्षर-सत्यापित वेबहुक, और सक्रिय लुकअप उसी स्टेट-एप्लिकेशन फ़ंक्शन में प्रवेश करते हैं। वेबहुक रॉ पेलोड को सत्यापित करता है, इसके इवेंट ID को डिडुप्लीकेट करता है, 2xx लौटाने से पहले बनी रहती है, और डुप्लीकेट्स और पुन: व्यवस्थित करने को सहन करती है। एक पुराना इवेंट पेमेंट को पीछे नहीं ले जा सकता है। ब्राउज़र केवल स्थानीय स्थिति प्रदर्शित करता है और पूर्ति को ट्रिगर नहीं कर सकता है। केवल एक संतुलित जर्नल और बिजनेस आउटबॉक्स के साथ कमिट की गई आधिकारिक कैप्चर सफलता ही ऑर्डर सर्विस को इडेम्पोटेंट तरीके से पूरा करने की अनुमति देती है।
एक कैप्चर जर्नल प्रोसेसर प्राप्य को डेबिट करता है और मर्चेंट देय को क्रेडिट करता है। एक रिफंड एक रिवर्सिंग जर्नल जोड़ता है; इतिहास अपरिवर्तनीय है। रिफंड निर्माण सशर्त रूप से उपलब्ध रिफंडेबल मूल्य को रिज़र्व करता है, इसलिए पुष्ट प्लस इन-फ्लाइट रिफंड कभी भी कैप्चर से अधिक नहीं होते हैं। पैसा पूर्णांक माइनर यूनिट्स का उपयोग करता है, मुद्रा पहले प्रयास के बाद अपरिवर्तनीय होती है, और प्रत्येक मुद्रा स्वतंत्र रूप से संतुलित होती है।
रिकवरी की तीन परतें हैं: अज्ञात ऑपरेशन्स प्रोवाइडर की का पुन: उपयोग करते हैं या स्टेटस क्वेरी करते हैं, दैनिक प्रोवाइडर रिपोर्ट पेमेंट्स, ऑपरेशन्स और जर्नल्स को रिकॉन्साइल करती हैं, और सेटलमेंट बैच बैंक जमाओं से मेल खाते हैं। विसंगतियों को क्वारंटाइन किया जाता है और सतर्क किया जाता है; मरम्मत केवल एक इडेम्पोटेंट आयात या क्षतिपूर्ति जर्नल जोड़ती है। एक होस्टेड प्रोवाइडर कंपोनेंट कार्ड एकत्र करता है, इसलिए बैकएंड न तो कार्ड नंबर और न ही सुरक्षा कोड स्टोर करता है। खोई हुई प्रतिक्रियाएं, डुप्लीकेट या पुन: व्यवस्थित वेबहुक्स, समवर्ती कैप्चर और रिफंड, प्रोवाइडर आउटेज, एक असंतुलित जर्नल, और केवल-बाहरी रिकॉन्सिलीएशन आइटम तब साबित करते हैं कि प्रत्येक बाहरी परिणाम एक ऑडिट करने योग्य मनी फैक्ट में कन्वर्ज होता है।"
सामान्य गलतियाँ
- ब्राउज़र सफलता पृष्ठ को पेमेंट सफलता के रूप में मानना → रीडायरेक्ट जाली हो सकता है, और पेमेंट अभी भी प्रमाणीकरण या एसिंक्रोनस पुष्टिकरण की प्रतीक्षा कर सकता है → केवल लोकल स्टेट मशीन द्वारा स्वीकार किए गए आधिकारिक प्रोवाइडर साक्ष्य ही पूर्ति को ट्रिगर करते हैं।
- पूरे लाइफसाइकिल के लिए एक
paidफ़ील्ड का उपयोग करना → यह अतिरिक्त प्रमाणीकरण, ऑथराइज़ेशन, कैप्चर, आंशिक रिफंड, या अज्ञात परिणाम को व्यक्त नहीं कर सकता है → पेमेंट एग्रीगेट को ऑपरेशन प्रयासों से अलग करें। - टाइमआउट के बाद एक नई ID या किसी अन्य प्रोवाइडर के साथ पुन: प्रयास करना → पहले प्रयास में चार्ज हो सकता है, जिससे दोहरा चार्ज बन सकता है → ऑपरेशन और प्रोवाइडर की का पुन: उपयोग करें, फिर अज्ञात परिणामों को क्वेरी या रिकॉन्साइल करें।
- केवल इडेम्पोटेन्सी की की तुलना करना, मापदंडों की नहीं → बदली हुई राशि के साथ की का पुन: उपयोग करने वाले कॉलर को गलत व्यावसायिक परिणाम मिलता है → एक सामान्यीकृत रिक्वेस्ट डाइजेस्ट को बनाए रखें और बदले हुए इंटेंट पर संघर्ष करें।
- वेबहुक क्रम पर निर्भर होना → प्रोवाइडर इवेंट्स को पुन: प्रयास, विलंबित और पुन: व्यवस्थित कर सकता है → डिडुप्लीकेट करें और वर्तमान स्थिति पुनः प्राप्त करें या केवल कानूनी मोनोटोनिक ट्रांज़िशन लागू करें।
- पेमेंट-टेबल बैलेंस को लेजर के रूप में मानना → यथास्थान अपडेट पैसे में बदलाव का कारण खो देते हैं और उन्हें स्वतंत्र रूप से रिकॉन्साइल नहीं किया जा सकता है → संतुलित जर्नल्स जोड़ें; बैलेंस को पुनर्निर्माण योग्य प्रोजेक्शन के रूप में रखें।
- समवर्ती रूप से रिफंडेबल बैलेंस को पढ़ना और फिर लिखना → दो कॉलर्स दोनों क्षमता देख सकते हैं और कैप्चर से अधिक हो सकते हैं → ऑपरेशन से विशिष्ट रूप से बंधे ट्रांजेक्शनल सशर्त अपडेट के साथ क्षमता रिज़र्व करें।
- केवल API 200 प्रतिक्रियाओं की निगरानी करना → स्वीकृत, अधिकृत, कैप्चर किए गए और सेटल किए गए के अलग-अलग अर्थ हैं → प्रत्येक स्थिति, अज्ञात आयु, और रिकॉन्सिलीएशन विसंगतियों को मापें।
- यह दावा करना कि टोकनाइज़ेशन स्वचालित रूप से PCI जिम्मेदारी को हटा देता है → पृष्ठ, लॉग, स्क्रिप्ट और परिचालन प्रक्रियाएं दायरे में रह सकती हैं → कार्ड डेटा को कम करें और कंप्लायंस से वास्तविक सीमा की पुष्टि करवाएं।
- विसंगति को ठीक करने के लिए ऐतिहासिक प्रविष्टियों को संपादित करना → ऑडिट श्रृंखला टूट जाती है और ऐतिहासिक रिपोर्ट रीप्ले नहीं हो सकती हैं → एक स्पष्ट आयात या क्षतिपूर्ति जर्नल जोड़ें।
फॉलो-अप प्रश्न और उत्तर
फॉलो-अप 1: प्रोवाइडर ने कैप्चर किया, लेकिन सिंक्रोनस प्रतिक्रिया और वेबहुक दोनों खो गए। क्या होता है?
ऑपरेशन UNKNOWN बना रहता है, संबंधित ऑथराइज़ेशन या रिफंड रिज़र्वेशन को बनाए रखता है और उसी इंटेंट के लिए किसी अन्य ऑपरेशन को रोकता है। पहले मूल प्रोवाइडर इडेम्पोटेन्सी की के साथ समर्थित लुकअप या कॉल का पुन: प्रयास करें, फिर सक्रिय रूप से प्रोवाइडर संदर्भ द्वारा क्वेरी करें। यदि यह अनिश्चित रहता है, तो ट्रांजेक्शन-रिपोर्ट रिकॉन्सिलीएशन की प्रतीक्षा करें। पुष्ट सफलता उसी स्टेट-एप्लिकेशन फ़ंक्शन में प्रवेश करती है और जर्नल और आउटबॉक्स पोस्ट करती है; केवल पुष्ट विफलता ही क्षमता को रिलीज़ करती है। बिना किसी साक्ष्य के प्रोवाइडर की प्रतिधारण समाप्त होने के बाद, बीते हुए समय से विफलता का अनुमान लगाने के बजाय मामले को ऑपरेटरों को भेजें।
फॉलो-अप 2: दो CNY 60 रिफंड समवर्ती रूप से CNY 100 कैप्चर को लक्षित करते हैं। आप ओवर-रिफंड को कैसे रोकते हैं?
पेमेंट या समर्पित रिफंडेबल-बैलेंस पंक्ति पर सशर्त अपडेट का उपयोग करें। यह pending_refund_amount को CNY 60 बढ़ाता है और ऑपरेशन केवल तभी बनाता है जब कम से कम CNY 60 रहता है। दोनों ट्रांजेक्शन एक ही वर्ज़न के लिए प्रतिस्पर्धा (contend) करते हैं, इसलिए एक सफल होता है और दूसरा अपर्याप्त क्षमता को दोबारा पढ़ता है। एक अज्ञात रिफंड अपने रिज़र्वेशन को बरकरार रखता है, एक निश्चित विफलता इसे रिलीज़ करती है, और एक सफलता पेंडिंग को रिफंडेड में ले जाती है। प्रोवाइडर प्रवर्तन केवल रक्षा की दूसरी पंक्ति है।
फॉलो-अप 3: CAPTURED, AUTHORIZED से पहले वेबहुक द्वारा आता है। इसे कैसे प्रोसेस किया जाता है?
दोनों प्राप्तियों को बनाए रखें और डिडुप्लीकेट करें। यदि CAPTURED हस्ताक्षर, राशि, मुद्रा और प्रोवाइडर संदर्भ मेल खाते हैं, तो कैप्चर ट्रांज़िशन और जर्नल लागू करें। बाद का AUTHORIZED इवेंट एक पुराना फैक्ट है। स्टेट मशीन रोलबैक को अस्वीकार करती है और केवल वेबहुक ऑडिट और देरी मेट्रिक्स को अपडेट करती है। यदि पेलोड में पर्याप्त वर्ज़न साक्ष्य का अभाव है, तो आगमन क्रम से ओवरराइट करने के बजाय प्रोवाइडर के वर्तमान पेमेंट संसाधन को पुनः प्राप्त करें।
फॉलो-अप 4: पेमेंट टेबल और लेजर दोनों क्यों हैं?
पेमेंट टेबल एक वर्कफ़्लो एग्रीगेट है जो यह उत्तर देने के लिए उपयुक्त है कि कैप्चर, रद्दीकरण या रिफंड की अनुमति है या नहीं। अपेंड-ओनली लेजर एक मनी रिकॉर्ड है जो यह समझाने के लिए उपयुक्त है कि शेष राशि कैसे बनी और किस व्यावसायिक घटना के कारण प्रत्येक परिवर्तन हुआ। पेमेंट CAPTURED से PARTIALLY_REFUNDED में जा सकता है, जबकि लेजर मूल कैप्चर और प्रत्येक स्वतंत्र संतुलित रिफंड जर्नल को बरकरार रखता है। एक यूनीक ऑपरेशन संदर्भ उन्हें जोड़ता है, और एक आधिकारिक ट्रांज़िशन एक स्थानीय ट्रांजेक्शन में दोनों को कमिट करता है। कोई भी जिम्मेदारी दूसरे की जगह नहीं लेती है।
फॉलो-अप 5: आप कैसे साबित करते हैं कि एक रिकॉन्सिलीएशन रिपेयरर दो बार पोस्ट नहीं कर सकता है?
प्रत्येक बाहरी रिपोर्ट पंक्ति को एक स्थिर स्रोत की (source key) दें जैसे कि प्रोवाइडर, रिपोर्ट प्रकार और ट्रांजेक्शन संदर्भ। रिपेयर को विसंगति ID से बांधें और एक यूनीक (source_key, repair_type) कंस्ट्रेंट जोड़ें। पहला ट्रांजेक्शन जर्नल जोड़ता है, विसंगति को चिह्नित करता है, और आउटबॉक्स लिखता है। एक क्रैश और दोबारा चलना उसी रिपेयर को ढूंढता है और इसके परिणाम को रीप्ले करता है। प्रक्रिया को कमिट से पहले, कमिट के बाद और इवेंट प्रकाशन के बाद समाप्त करें; जर्नल गणना, शेष राशि और डाउनस्ट्रीम इवेंट गणना कभी भी दूसरी बार नहीं बढ़नी चाहिए।
फॉलो-अप 6: यदि बाद में कोई दूसरा प्रोवाइडर जोड़ा जाता है, तो फ़ेलओवर की अनुमति कब होती है?
दूसरे प्रोवाइडर पर एक ऑपरेशन केवल तभी बनाएं जब पहला स्पष्ट रूप से कहे कि ऑपरेशन कभी नहीं बनाया गया था या निश्चित रूप से विफल रहा था, और स्थानीय ऑपरेशन में कोई मनी फैक्ट नहीं है। कनेक्शन टाइमआउट, 5xx, और अज्ञात उस शर्त को पूरा नहीं करते हैं। रूटिंग विकल्प, प्रोवाइडर क्षमता, राशि, मुद्रा और कारण का ऑडिट करें। यदि दोनों परिणाम मौजूद हो सकते हैं, तो पूर्ति और बैलेंस रिलीज़ को फ्रीज करें जबकि क्वेरी और रिकॉन्सिलीएशन दोहरे चार्ज को समाप्त करते हैं। एक स्वचालित रिफंड अज्ञात परिणाम को छुपा नहीं सकता है।