प्रतिनिधि इंटरव्यू विषय

सिस्टम डिज़ाइन इंटरव्यू: एक सब्सक्रिप्शन बिलिंग सिस्टम डिज़ाइन करें

सिस्टम डिज़ाइनकठिन
Offer.cc संपादकीय टीमप्रकाशित अपडेट किया गया

प्रश्न

मासिक और वार्षिक प्लान, ट्रायल, अपग्रेड, डाउनग्रेड, प्रो-रेशन, रिन्यूअल, असफल भुगतान पुनः प्रयास (retries), इनवॉइस और वेबहुक के लिए एक सब्सक्रिप्शन बिलिंग सिस्टम डिज़ाइन करें। स्टेट मशीन, बिलिंग इंजन, भुगतान आइडेम्पोटेंसी, इवेंट ऑर्डरिंग, क्षमता, समाधान और विफलताओं से रिकवरी की व्याख्या करें।

प्रॉम्प्ट और दायरा

एक ऐसी सर्विस डिज़ाइन करें जो किसी SaaS, मीडिया या मेंबरशिप उत्पाद के लिए आवर्ती (recurring) सब्सक्रिप्शन का प्रबंधन करती हो। ग्राहक मासिक या वार्षिक प्लान चुन सकते हैं, ट्रायल से सशुल्क एक्सेस में बदल सकते हैं, साइकिल के बीच में प्लान बदल सकते हैं और असफल रिन्यूअल से रिकवर कर सकते हैं। सिस्टम को ऑडिट करने योग्य इनवॉइस तैयार करने होंगे, उत्पाद को एंटाइटेलमेंट्स के बारे में सूचित करना होगा और भुगतान प्रदाता (payment provider) से एसिंक्रोनस इवेंट्स को प्रोसेस करना होगा।

सार्वजनिक इंटरव्यू सामग्री "एक सब्सक्रिप्शन बिलिंग सिस्टम डिज़ाइन करें" को सब्सक्रिप्शन-निर्मित और ट्रायल-समाप्त इवेंट्स, बॉटलनेक्स, ग्राहक मेट्रिक्स और सिस्टम मॉनिटरिंग के बारे में एक सिस्टम-डिज़ाइन प्रश्न के रूप में प्रस्तुत करती है। Stripe का दस्तावेज़ीकरण सब्सक्रिप्शन, इनवॉइस, PaymentIntents, ट्रायल, प्रो-रेशन, राजस्व रिकवरी और वेबहुक को एक ही जीवनचक्र में रखता है। यह लेख यह दावा नहीं करता है कि कोई विशेष कंपनी हमेशा यही प्रश्न पूछती है।

मान लें कि 1 मिलियन सक्रिय सब्सक्रिप्शन हैं, औसतन प्रति दिन प्रति सब्सक्रिप्शन एक बिलिंग-संबंधित इवेंट होता है, रिन्यूअल पीक सामान्य ट्रैफ़िक से 10 गुना तक होता है, राशियाँ सबसे छोटी मुद्रा इकाई (smallest currency unit) में संग्रहीत होती हैं, और एक ऐसा प्रदाता है जो टाइम आउट हो सकता है, इवेंट्स की डुप्लीकेट कॉपी बना सकता है, या स्थानीय स्थिति बदलने के बाद इवेंट्स वितरित कर सकता है। सिस्टम को डुप्लीकेट शुल्कों से बचना चाहिए, इनवॉइस को ट्रेस करने योग्य रखना चाहिए और पुनः प्रयासों के बाद एंटाइटेलमेंट स्थिति को कन्वर्ज करना चाहिए।

इंटरव्यूअर क्या मूल्यांकन करता है

एक मजबूत उत्तर प्लान, सब्सक्रिप्शन, इनवॉइस, भुगतान प्रयासों और एंटाइटेलमेंट्स को अलग करता है। किसी ग्राहक पंक्ति पर केवल paid=true लिखने से प्रो-रेशन, ग्रेस पीरियड, रिफंड या एक इनवॉइस के लिए कई प्रयासों को व्यक्त नहीं किया जा सकता है।

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

इंटरव्यूअर समय और लेखांकन सिमेंटिक्स का भी परीक्षण करता है: बिलिंग एंकर, ट्रायल की समाप्ति, समय क्षेत्र, लीप माह, तत्काल अपग्रेड, अवधि के अंत में रद्दीकरण (end-of-period cancellation), और अपरिवर्तनीय (immutable) राशियाँ। जब किसी प्लान की कीमत बदलती है तो ऐतिहासिक इनवॉइस नहीं बदलने चाहिए।

अंत में, उम्मीदवार को पीक, असफल भुगतान, आउट-ऑफ-ऑर्डर इवेंट्स, मैन्युअल रिफंड, समाधान अंतर (reconciliation gaps) और मरम्मत की व्याख्या करनी चाहिए। उपयोगी परिणाम यह जानना है कि क्या चार्ज किया जाना चाहिए था, क्या चार्ज किया गया था और रिकवरी के बाद कौन से एंटाइटेलमेंट्स मान्य हैं।

उत्तर देने से पहले स्पष्ट करने वाले प्रश्न

  • बिलिंग एंकर क्या है? कैलेंडर माह या कोई रोलिंग तिथि? यह अवधि-अंत की गणना और फरवरी या 31वें दिन की हैंडलिंग को बदल देता है।
  • अपग्रेड कब चार्ज होता है? तुरंत, अगली अवधि में, या ग्राहक की पसंद से? यह प्रो-रेशन और लंबित-भुगतान स्थितियों को बदलता है।
  • डाउनग्रेड कैसे काम करता है? तत्काल रिफंड, अगली अवधि का प्रभाव, या खाता क्रेडिट? यह इनवॉइस लाइनों और रिफंड हैंडलिंग को बदलता है।
  • असफल भुगतान एक्सेस कब हटाता है? केवल-पढ़ने के लिए (read-only) ग्रेस पीरियड और तत्काल निलंबन के अलग-अलग एंटाइटेलमेंट नियम होते हैं।
  • क्या टैक्स, छूट या उपयोग शुल्क दायरे में हैं? यदि हाँ, तो इनवॉइस को अंतिम रूप देने से पहले मूल्य निर्धारण इनपुट का संस्करण (versioning) तय किया जाना चाहिए।
  • एंटाइटेलमेंट का ट्रुथ सोर्स क्या है? उत्पाद प्रदाता इवेंट्स का सीधे उपभोग कर सकता है, या बिलिंग सिस्टम entitlement.changed इवेंट्स प्रकाशित कर सकता है। यह विकल्प रीप्ले और निरंतरता को बदलता है।
  • क्या कई मुद्राओं, रिफंड या मैन्युअल समायोजन की आवश्यकता है? यदि हाँ, तो पूर्णांक लघु इकाइयों (integer minor units) का उपयोग करें और कभी भी ऐतिहासिक इनवॉइस को अधिलेखित (overwrite) न करें।

30-सेकंड का उत्तर

"मैं प्लान, सब्सक्रिप्शन, इनवॉइस, भुगतान प्रयासों और एंटाइटेलमेंट्स को अलग रखूँगा। एक सब्सक्रिप्शन स्टेट मशीन वर्तमान अवधि और अगली कार्रवाई तय करती है; एक बिलिंग इंजन प्रत्येक सीमा पर एक इम्यूटेबल इनवॉइस स्नैपशॉट बनाता है और भुगतान आइडेम्पोटेंसी कुंजी के रूप में invoice_id का उपयोग करता है। हस्ताक्षरित वेबहुक और प्रदाता क्वेरी के माध्यम से भुगतान की पुष्टि करें, इवेंट आईडी द्वारा डुप्लीकेशन हटाएँ, और इवेंट्स को आउट-ऑफ़-ऑर्डर आने की अनुमति दें। अपग्रेड और डाउनग्रेड को स्पष्ट सकारात्मक और नकारात्मक इनवॉइस लाइनों के रूप में दर्शाएँ। असफल भुगतान एक सीमित, जिटर-युक्त पुनः प्रयास स्टेट मशीन में प्रवेश करते हैं, और एंटाइटेलमेंट्स पुष्ट भुगतान स्थिति के साथ-साथ एक दस्तावेज़ित ग्रेस नीति का पालन करते हैं। मैं समाधान, स्टेट इनवेरिएंट्स और विफलता इंजेक्शन के साथ डिज़ाइन को प्रमाणित करूँगा।"

चरण-दर-चरण समाधान

चरण 1: ऑब्जेक्ट और इनवेरिएंट्स को परिभाषित करें।

text
Plan(id, version, currency, interval, unit_amount, trial_days)
Subscription(id, customer_id, plan_version, status, period_start, period_end)
Invoice(id, subscription_id, period_start, period_end, currency, total, status)
InvoiceLine(id, invoice_id, source, description, quantity, unit_amount, amount)
PaymentAttempt(id, invoice_id, attempt_no, provider_key, status, provider_id)
Entitlement(id, customer_id, feature, valid_until, source_invoice_id)

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

चरण 2: स्टेट मशीन के साथ कार्य संचालित करें।

text
trialing --trial_end--> active
active --renewal--> invoice_open
invoice_open --payment_succeeded--> paid
invoice_open --payment_failed--> past_due
past_due --retry_succeeded--> paid
past_due --retries_exhausted--> canceled
active --cancel_at_period_end--> canceling
canceling --period_end--> canceled

संस्करण वाले कमांड या इवेंट्स ट्रांज़िशन निष्पादित करते हैं; मनमाने वेब अनुरोधों को सीधे स्थिति में परिवर्तन नहीं करना चाहिए। active, past_due और canceled के लिए एंटाइटेलमेंट नीति परिभाषित करें: उदाहरण के लिए, past_due तीन दिनों के लिए केवल-पढ़ने का एक्सेस बनाए रख सकता है जबकि canceled सशुल्क सुविधाओं को हटा देता है। प्रत्येक ट्रांज़िशन के लिए कारण, स्रोत इवेंट, कर्ता (actor) और समय रिकॉर्ड करें।

चरण 3: इनवॉइस जनरेट करें और प्लान परिवर्तनों को संभालें।

period_end द्वारा एक बिलिंग वर्कर को विभाजित (partition) करें। पहले (subscription_id, period_start) जैसे यूनिक कंस्ट्रेंट के तहत एक इनवॉइस बनाएं, फिर उसकी लाइनों की गणना करें। 15वें दिन अपग्रेड के लिए, अप्रयुक्त पुराने प्लान को एक नकारात्मक लाइन के रूप में और शेष नए प्लान को एक सकारात्मक लाइन के रूप में रिकॉर्ड करें। पूर्णांक लघु इकाइयों और एक स्पष्ट सेकंड-या-दिन नियम का उपयोग करें; कभी भी राउंडेड फ्लोटिंग-पॉइंट मानों को न घटाएं।

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

चरण 4: नेटवर्क टाइमआउट से भुगतान आइडेम्पोटेंसी को अलग करें।

text
provider_key = "invoice:" + invoice_id + ":attempt:" + attempt_no
POST payment-provider/charges
  Idempotency-Key: provider_key

प्रदाता को कॉल करने से पहले एक स्थानीय PaymentAttempt लिखें। टाइमआउट के बाद, विफलता का अनुमान न लगाएं; उसी कुंजी के साथ पुनः प्रयास करें या प्रदाता से क्वेरी करें। Stripe दस्तावेज़ बताता है कि बार-बार किए गए आइडेम्पोटेंट अनुरोध पहला परिणाम लौटाते हैं और आकस्मिक कुंजी पुनर्चक्रण को रोकने के लिए मापदंडों की तुलना करते हैं। इसलिए कुंजी को एक व्यावसायिक संचालन का प्रतिनिधित्व करना चाहिए, न कि एक नेटवर्क प्रयास का।

सफलता पर, एक वेबहुक या प्रदाता क्वेरी provider_id, राशि, मुद्रा और पूरा होने का समय रिकॉर्ड करती है। एक सशर्त डेटाबेस अपडेट केवल open या past_due को paid में जाने की अनुमति देता है; देर से आया payment_failed ऑडिट रिकॉर्ड में जाता है और पुष्टि किए गए भुगतान को वापस (roll back) नहीं कर सकता है। पैसे या मुद्रा का बेमेल होना स्वचालित रूप से एक्सेस देने या हटाने के बजाय समाधान (reconciliation) में प्रवेश करता है।

चरण 5: इनबॉक्स के साथ वेबहुक डुप्लिकेट्स और रीऑर्डरिंग को संभालें।

text
WebhookInbox(event_id PRIMARY KEY, received_at, payload_hash, processed_at)
Outbox(id, aggregate_id, event_type, payload, published_at)

हस्ताक्षर सत्यापित करें, रॉ इवेंट और हैश को WebhookInbox में संग्रहीत करें, और एक डुप्लिकेट event_id को स्वीकार (acknowledge) करें। प्रोसेसर यह तय करने के लिए ऑब्जेक्ट संस्करण, प्रदाता स्थिति और स्थानीय इनवॉइस स्थिति का उपयोग करता है कि क्या आगे बढ़ना है; आगमन का समय ऑर्डरिंग की गारंटी नहीं है। Stripe एसिंक्रोनस गतिविधि और एंटाइटेलमेंट परिवर्तनों के लिए सब्सक्रिप्शन वेबहुक की सिफारिश करता है, इसलिए आंतरिक प्रोसेसिंग भी रीप्ले करने योग्य होनी चाहिए।

एक स्थानीय ट्रांज़िशन बिलिंग स्थिति, एक एंटाइटेलमेंट-परिवर्तन आशय और एक आउटबॉक्स रिकॉर्ड एक साथ लिख सकता है। एक प्रकाशक तब रिकॉर्ड को एंटाइटेलमेंट सेवा को भेजता है। उपभोक्ता (aggregate_id, version) द्वारा डुप्लीकेशन हटाते हैं, इसलिए प्रदाता पुनः प्रयास, कतार पुनः प्रयास और उपभोक्ता पुनरारंभ एक दूसरा प्रभावी ऑथराइजेशन नहीं बनाते हैं।

चरण 6: क्षमता का अनुमान लगाएं और पीक को अलग करें।

1 मिलियन सक्रिय सब्सक्रिप्शन और प्रति दिन प्रति सब्सक्रिप्शन एक बिलिंग इवेंट के साथ, स्थिर दर लगभग 11.6 इवेंट्स/सेकंड है; 10x रिन्यूअल पीक लगभग 116 इवेंट्स/सेकंड है। अधिक कठिन लोड एक साथ होने वाली इनवॉइस लाइनें, भुगतान कॉल, वेबहुक और सूचनाएं हैं। अवधि के कार्य को समय के अनुसार बकेट करें, प्रत्येक बैच को सीमित करें, और शीर्ष-घंटे (top-of-hour) के एकल स्पाइक से बचने के लिए जिटर जोड़ें।

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

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

चरण 7: समाधान, मरम्मत और निरीक्षण करें।

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

अवधि-स्कैन अंतराल, इनवॉइस विलंबता, अज्ञात भुगतान परिणाम, पुनः प्रयास गणना, past_due आयु, वेबहुक डुप्लीकेट दर और प्रोसेसिंग अंतराल, एंटाइटेलमेंट प्रसार विलंब, समाधान डॉलर अंतर, और प्रति-किरायेदार भुगतान विफलताओं को ट्रैक करें। ऑडिट रिकॉर्ड को subscription_id, invoice_id, payment_attempt_id, इवेंट आईडी और ट्रेस आईडी को लिंक करना चाहिए ताकि किसी शिकायत का प्रदाता प्रतिक्रिया तक पता लगाया जा सके।

चरण 8: विफलता मैट्रिक्स के साथ सीमाओं को प्रमाणित करें।

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

स्वीकृति जांचें हैं: प्रति (subscription_id, period_start) एक प्रभावी इनवॉइस; एक provider_key के लिए कोई दूसरा शुल्क नहीं; पुष्टि किया गया भुगतान देर से हुई विफलता से अधिलेखित नहीं होता है; रीप्ले किए गए एंटाइटेलमेंट इवेंट समान संस्करण उत्पन्न करते हैं; प्रत्येक समाधान अंतर का एक ट्रेस करने योग्य समायोजन होता है; और प्रत्येक स्वचालित कार्रवाई को ऑडिट रिकॉर्ड से फिर से बनाया जा सकता है।

उच्च गुणवत्ता वाला नमूना उत्तर

"मैं प्लान, सब्सक्रिप्शन, इनवॉइस, भुगतान प्रयासों और एंटाइटेलमेंट्स को अलग रखूँगा, और इनवॉइस बनाए जाने पर प्लान की कीमत का स्नैपशॉट लूँगा। एक सब्सक्रिप्शन स्टेट मशीन ट्रायल, रिन्यूअल, ग्रेस पीरियड और रद्दीकरण को संभालती है। एक अवधि वर्कर एक अद्वितीय कुंजी के तहत एक इनवॉइस बनाता है; प्लान परिवर्तन पूर्णांक लघु इकाइयों और एक स्पष्ट प्रो-रेशन नियम का उपयोग करके सकारात्मक और नकारात्मक इनवॉइस लाइनें बन जाते हैं।

प्रदाता को कॉल करने से पहले, मैं एक प्रयास लिखता हूँ और एक स्थिर invoice_id + attempt_no आइडेम्पोटेंसी कुंजी प्राप्त करता हूँ। टाइमआउट उसी कुंजी या प्रदाता क्वेरी का उपयोग करता है; यह कभी भी नई कुंजी नहीं बनाता है। वेबहुक सत्यापित किए जाते हैं, इनबॉक्स में संग्रहीत होते हैं, और इवेंट आईडी द्वारा डीडुप्लिकेट किए जाते हैं। सशर्त संस्करण अपडेट एक आउट-ऑफ़-ऑर्डर विफलता को पुष्ट भुगतान को अधिलेखित करने से रोकते हैं। एक आउटबॉक्स एंटाइटेलमेंट आशय को डाउनस्ट्रीम मज़बूती से भेजता है।

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

सामान्य गलतियाँ

  • गलती: सब्सक्रिप्शन पर केवल paid स्टोर करना → यह क्यों विफल होता है: इनवॉइस, प्रयास, ग्रेस पीरियड और रिफंड गायब हो जाते हैं → समाधान: इनवॉइस, भुगतान प्रयासों और एंटाइटेलमेंट्स को अलग से मॉडल करें।
  • गलती: प्रत्येक टाइमआउट पुनः प्रयास के लिए एक नया भुगतान आईडी बनाना → यह क्यों विफल होता है: एक व्यावसायिक शुल्क दो बार निष्पादित हो सकता है → समाधान: प्रति ऑपरेशन एक आइडेम्पोटेंसी कुंजी रखें और अज्ञात परिणामों के लिए क्वेरी करें।
  • गलती: आगमन समय के आधार पर इवेंट्स लागू करना → यह क्यों विफल होता है: वेबहुक डुप्लिकेट, पुनर्व्यवस्थित या विलंबित हो सकते हैं → समाधान: एक इनबॉक्स संग्रहीत करें और ऑब्जेक्ट संस्करणों के साथ-साथ सशर्त ट्रांज़िशन का उपयोग करें।
  • गलती: आज के प्लान मूल्य से पुराने इनवॉइस की पुनर्गणना करना → यह क्यों विफल होता है: मूल्य परिवर्तन इतिहास को फिर से लिखता है → समाधान: इनवॉइस पर मूल्य, टैक्स, छूट, उपयोग और प्लान संस्करण को फ्रीज करें।
  • गलती: एक विफलता के बाद तुरंत रद्द करना → यह क्यों विफल होता है: एक क्षणिक प्रदाता आउटेज एक एंटाइटेलमेंट आउटेज बन जाता है → समाधान: past_due ग्रेस नीति और सीमित डनिंग स्टेट मशीन का उपयोग करें।
  • गलती: रद्दीकरण पर अवधि रिकॉर्ड हटाना → यह क्यों विफल होता है: ऑडिट, रिफंड और समाधान साक्ष्य खो देते हैं → समाधान: इतिहास को बनाए रखते हुए रद्दीकरण और समायोजन रिकॉर्ड जोड़ें।
  • गलती: डेटाबेस ट्रांज़िशन को भुगतान ट्रांज़िशन के रूप में मानना → यह क्यों विफल होता है: प्रदाता स्थानीय ट्रांज़िशन के बाहर है → समाधान: आइडेम्पोटेंट कॉल, वेबहुक, प्रश्नों और समाधान के साथ लूप को बंद करें।
  • गलती: एक ही सटीक समय पर प्रत्येक सब्सक्रिप्शन को स्कैन करना → यह क्यों विफल होता है: लॉक, भुगतान कॉल और सूचनाएं एक साथ स्पाइक करती हैं → समाधान: कार्य को बकेट, जिटर, कतार और कोटा में विभाजित करें।

फॉलो-अप और उत्तर

फॉलो-अप 1: अपग्रेड भुगतान विफल हो जाता है। एक्सेस का क्या होता है?

पुराना एंटाइटेलमेंट बनाए रखें, एक pending_update और एक नया इनवॉइस बनाएं, और पुष्ट भुगतान के बाद ही प्लान बदलें। यदि उत्पाद संग्रह-से-पहले-अपग्रेड (upgrade-before-collection) की अनुमति देता है, तो नए एंटाइटेलमेंट को स्पष्ट समाप्ति के साथ ग्रेस-सीमित के रूप में चिह्नित करें। दोनों नीतियों में, इनवॉइस और एंटाइटेलमेंट संस्करण ट्रेस करने योग्य रहते हैं; केवल plan_id बदलना अपर्याप्त है।

फॉलो-अप 2: तीन दिनों तक कोई प्रदाता वेबहुक नहीं आता है। आप इसका पता कैसे लगाते हैं?

स्थानीय इनवॉइस स्थिति और प्रदाता प्रश्नों से एक समाधान कार्य चलाएँ। पुराने open, past_due, या टर्मिनल इवेंट के बिना समाप्त हो चुके इनवॉइस पर अलर्ट करें; यदि क्वेरी अभी भी अज्ञात है, तो स्वचालित रद्दीकरण रोकें और इसे मैन्युअल समीक्षा के लिए रूट करें। एक वेबहुक कम-विलंबता वाली अधिसूचना है, एकमात्र ट्रुथ सोर्स नहीं।

फॉलो-अप 3: रद्दीकरण और रिन्यूअल एक साथ आते हैं। कौन जीतता है?

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

फॉलो-अप 4: आप दोहरी गिनती (double-counting) के बिना उपयोग बिलिंग कैसे जोड़ते हैं?

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

सार्वजनिक स्रोत

संबंधित प्रश्न

संबंधित इंटरव्यू टूल

सिस्टम डिज़ाइन उत्तर के लिए हल करें का उपयोग करें

पहले आवश्यकताओं को स्पष्ट करें, फिर स्केल, आर्किटेक्चर, कंपोनेंट चयन और ट्रेड-ऑफ की ओर बढ़ें।

टूल देखें