प्लेबुक
चेकआउट स्थिति मशीन डिज़ाइन: चेकआउट और भुगतान एक ही चीज़ क्यों नहीं हैं? (Payment State Machine Design)
भुगतान सफल होने का मतलब यह नहीं है कि ऑर्डर पूरा हो गया है। यदि आप चेकआउट और भुगतान जीवनचक्र को अलग नहीं करते हैं, तो उत्पादन में दोनों वास्तविकताएं ओवरलैप हो जाती हैं।
वितरित भुगतान इंजन
भाग 2 का 22
वितरित भुगतान आर्किटेक्चर की एक श्रृंखला जो कैप्चर और पूर्ण के बीच के अंतर को पाटती है।
दो कैलेंडर, एक स्क्रीन
ग्राहक को स्क्रीन पर एकल "ऑर्डर स्थिति" दिखाई देती है; लेकिन कम से कम दो स्वतंत्र राज्य मशीनें पृष्ठभूमि में चलती हैं: चेकआउट जीवनचक्र और भुगतान जीवनचक्र। इन दो मशीनों को एक ही फ़ील्ड (status) के माध्यम से प्रबंधित करने का प्रयास "एकल सत्य" भ्रम का राज्य मशीन संस्करण है जिसके बारे में हमने पहले खंड में बात की थी।```text
Checkout: Init → Processing → FinalizePending → Completed
↘ Failed / Expired
Payment: Init → Processing → Captured → Completed ↘ Failed / Expired
## पहले उल्लेख पर अवधारणाएँ```text
📦 Checkout Lifecycle
Siparişin müşteri gözünden geçtiği aşamalar: başlatıldı, işleniyor, tamamlanma bekliyor, tamamlandı.
📦 Payment Lifecycle
Para hareketinin PSP gözünden geçtiği aşamalar: başlatıldı, işleniyor, çekildi (captured), tamamlandı.
📦 Terminal Durum
Geriye dönüşü olmayan, makinenin o dal için sonlandığı durum (Completed, Failed, Expired).
📦 Transition Guard
Bir durumdan diğerine geçişe izin vermeden önce kontrol edilen ön koşul.
📦 State Drift
İki ilişkili durum makinesinin, senkronize olması gereken noktada birbirinden kopması.
````Captured` क्या PSP कह रहा है "मुझे पैसे मिल गए"। `Completed` आपका कहना है "मैंने ऑर्डर पूरा कर दिया"। ये दोनों एक ही घटना नहीं हैं; उनके बीच एक प्रतीक्षा स्थिति होती है जिसे `FinalizePending` कहा जाता है और यह स्थिति सेकंड नहीं बल्कि कभी-कभी मिनटों तक रह सकती है।
## क्यों एक `status` फ़ील्ड पर्याप्त नहीं है
कई प्रणालियों में, ऑर्डर तालिका में एक एकल `status` कॉलम होता है, और "भुगतान स्थिति" और "ऑर्डर स्थिति" दोनों को इस कॉलम में निचोड़ा जाता है। यह दो अलग-अलग जिम्मेदारियों को एक ही क्षेत्र में समेटने का क्लासिक लक्षण है: भुगतान वेबहुक आने पर स्थिति `Completed` वाली एक पंक्ति ऑर्डर को "समाप्त" के रूप में दिखाती है, जबकि वास्तव में स्टॉक आरक्षित या चालान नहीं किया गया है।```text
Orders
id | status
1 | Completed ← webhook geldi, ama finalization saga'sı henüz çalışmadı
```## दो मशीनों को अलग करना
सही मॉडल चेकआउट और भुगतान को अलग-अलग राज्य मशीनों के रूप में परिभाषित करता है और उनके बीच केवल एक-तरफ़ा ट्रिगरिंग संबंध स्थापित करता है: भुगतान का राज्य `Captured` में संक्रमण चेकआउट के राज्य `FinalizePending` में संक्रमण को ट्रिगर करता है; लेकिन चेकआउट का `Completed` होना अपनी गाथा के अंत पर निर्भर करता है।```text
Payment.Captured --(tetikler)--> Checkout.FinalizePending
|
stok, finans, bildirim, sepet temizliği tamamlanınca
↓
Checkout.Completed
```इस अंतर के लिए धन्यवाद, "भुगतान सफल है लेकिन ऑर्डर अभी भी संसाधित हो रहा है" अब कोई त्रुटि नहीं है, बल्कि एक अपेक्षित और प्रदर्शन योग्य मध्यवर्ती स्थिति है। ग्राहक को यह बताना कि "आपका भुगतान प्राप्त हो गया है, आपका ऑर्डर तैयार किया जा रहा है" सिस्टम की वास्तविक स्थिति को सटीक रूप से दर्शाता है।
## कौन ट्रिगर विफल और समाप्त हो गया
दोनों मशीनों की अपनी `Failed` और `Expired` शाखाएँ हैं, जिन्हें एक-दूसरे से स्वतंत्र रूप से चालू किया जा सकता है। भुगतान पक्ष पर, `Expired` का अर्थ है कि PSP एक निश्चित अवधि के भीतर प्रतिक्रिया नहीं देता है (उदाहरण के लिए 3D सुरक्षित पुष्टिकरण पूरा नहीं हुआ है)। चेकआउट पक्ष पर, `Expired` का अर्थ है कि अंतिम रूप देने की गाथा एक निर्दिष्ट समय के भीतर समाप्त नहीं होती है - भले ही भुगतान `Captured` हो।```text
Payment.Captured + Checkout finalization 30 dakika içinde bitmedi
↓
Checkout.Expired (ama Payment.Captured hâlâ geçerli — para geri iade edilmeli mi, saga retry mi edilmeli, karar operasyonel bir konudur)
```यह परिदृश्य दो मशीनों को अलग करने का वास्तविक लाभ दिखाता है: आप चेकआउट पक्ष पर `Payment.Captured` स्थिति बरकरार रखते हुए एक अलग पुनर्प्राप्ति प्रक्रिया शुरू कर सकते हैं। यदि एक `status` फ़ील्ड होती, तो आप एक ही समय में इन दो तथ्यों का प्रतिनिधित्व नहीं कर सकते।
## गार्ड: पास की रखवाली करना
प्रत्येक पास पर एक गार्ड अवश्य होना चाहिए। उदाहरण के लिए, `Checkout.Processing → Checkout.FinalizePending` में परिवर्तन यह सत्यापित करने के बाद ही होना चाहिए कि संबंधित भुगतान रिकॉर्ड `Captured` स्थिति में है। यदि वेबहुक क्रम से बाहर आ जाते हैं (जिसके बारे में हम इस श्रृंखला के छठे भाग में विस्तार से बताएंगे) तो गार्ड के बिना एक राज्य मशीन अमान्य स्थिति में आ सकती है।```text
Guard: Checkout.FinalizePending'e geçiş
→ İlişkili Payment kaydı var mı?
→ Payment.Status == Captured mı?
→ Payment.Amount, Checkout snapshot'ıyla eşleşiyor mu?
Hepsi doğruysa geçiş serbest; değilse geçiş reddedilir ve olay bir “beklemede” kuyruğuna düşer.
इस एपिसोड में सबसे भ्रमित करने वाला मैचअप```text
❌ Payment.Succeeded = Checkout.Completed ✓ Payment.Succeeded, Checkout.FinalizePending'i tetikler; Completed ayrı bir karardır
❌ Tek bir status alanı hem ödeme hem sipariş durumunu taşıyabilir ✓ İki bağımsız yaşam döngüsü, iki bağımsız alan (veya tablo) gerektirir
❌ Failed durumu her zaman “para geri gitti” anlamına gelir ✓ Checkout.Failed, Payment.Captured'ı geçersiz kılmaz; ayrı bir telafi süreci gerekir
❌ Guard'sız bir geçiş, sadece “fazladan kontrol”dür ✓ Guard, sırasız veya tekrarlı olaylara karşı tek savunma hattıdır
## अपनी राज्य मशीन की जाँच करें
1. क्या आपके ऑर्डर तालिका में भुगतान स्थिति और ऑर्डर स्थिति को एक ही कॉलम में रखा गया है? अलग करना।
2. कौन से गार्ड उस कोड द्वारा नियंत्रित होते हैं जो `Captured` और `Completed` के बीच संक्रमण को ट्रिगर करता है?
3. यदि चेकआउट गाथा भुगतान `Captured` के बाद 30 मिनट के भीतर समाप्त नहीं होती है तो क्या होगा? क्या कोई अलार्म है?
4. क्या आप स्पष्ट रूप से सूचीबद्ध कर सकते हैं कि `Failed` और `Expired` राज्यों में किसने और किस घटना के साथ प्रवेश किया?
5. यदि एक ही भुगतान के लिए दो वेबहुक ऑर्डर से बाहर आ जाते हैं, तो क्या गार्ड इसका पता लगाता है या यह अमान्य संक्रमण की अनुमति देता है?
यदि आपके पास इन पाँच प्रश्नों के विश्वसनीय उत्तर नहीं हैं, तो संभवतः आपने दो राज्य मशीनों को एक में जोड़ दिया है।
## इस अनुभाग से याद रखने योग्य बातें
1. चेकआउट और भुगतान दो संबंधित लेकिन स्वतंत्र राज्य मशीनें हैं; एकल `status` फ़ील्ड में संपीड़ित नहीं किया जा सकता.
2. भुगतान.सफल चेकआउट.पूर्ण की गारंटी नहीं देता; उनके बीच `FinalizePending` की मापने योग्य और प्रदर्शित करने योग्य सीमा है।
3. प्रत्येक पास एक गार्ड से जुड़ा होना चाहिए; बिना गार्ड के पास से आउट-ऑफ़-ऑर्डर या दोहराव वाली घटनाओं में अमान्य स्थिति पैदा होती है।
4. `Failed` और `Expired` को दो मशीनों पर स्वतंत्र रूप से चालू किया जा सकता है; कोई स्वचालित रूप से दूसरे को ओवरराइड नहीं करता है.
> जिस दिन आप भुगतान स्थिति और ऑर्डर स्थिति एक ही कॉलम में लिखते हैं, आप दो अलग-अलग सच को एक झूठ में बदल देते हैं।
FAQ
Frequently asked questions
चेकआउट जीवनचक्र क्या है?
ऑर्डर ग्राहक की नजरों से गुजरने वाले चरणों में शामिल हैं: आरंभ, प्रक्रिया में, पूरा होने की प्रतीक्षा में, पूरा।
भुगतान जीवनचक्र क्या है?
पीएसपी के नजरिए से धन की आवाजाही जिन चरणों से गुजरती है: शुरू किया गया, संसाधित किया गया, पकड़ा गया, पूरा किया गया।
क्या "भुगतान.सफल = चेकआउट.पूर्ण" सही है?
भुगतान। सफल ट्रिगर चेकआउट। अंतिम रूप देना लंबित; पूर्ण होना एक अलग निर्णय है
यह अनुभाग क्या ठीक करता है?
यह अनुभाग बताता है कि आपको इन दोनों मशीनों को अलग-अलग क्यों डिज़ाइन करना चाहिए और उनके बीच की देरी को डिज़ाइन निर्णय के रूप में मानना चाहिए, बग के रूप में नहीं। चेकआउट और भुगतान दो संबंधित लेकिन स्वतंत्र राज्य मशीनें हैं; एकल `status` फ़ील्ड में संपीड़ित नहीं किया जा सकता. ग्राहक को स्क्रीन पर एकल "ऑर्डर स्थिति" दिखाई देती है; लेकिन कम से कम दो स्वतंत्र राज्य मशीनें पृष्ठभूमि में चलती हैं: चेकआउट जीवनचक्र और भुगतान जीवनचक्र। इन दो मशीनों को एक ही क्षेत्र (`status`) के माध्यम से प्रबंधित करने का प्रयास "एकल सत्य" भ्रम का राज्य मशीन संस्करण है जिसके बारे में हमने पहले खंड में बात की थी।
इंजीनियरिंग सिद्धांत सीखे गए
- चेकआउट और भुगतान जीवनचक्र संबंधित लेकिन स्वतंत्र हैं; एक ही क्षेत्र में प्रतिनिधित्व नहीं किया जा सकता.
- भुगतान।सफल होना एक ट्रिगर है, परिणाम नहीं; चेकआउट.पूरा होना उसकी अपनी गाथा के पूरा होने पर निर्भर करता है।
- किसी आउट-ऑफ-ऑर्डर या दोहराव वाली घटना का सामना करने पर बिना गार्ड वाला पास अमान्य स्थिति में दरवाजा खुला छोड़ देता है।
जारी रखें पढ़ रहे हैं
जारी रखें पढ़ रहे हैं
श्रृंखला में अगला
संग्रहण (कब्जा करना) आसान लेकिन अंतिम रूप देना कठिन क्यों है?
पीएसपी के लिए पैसा प्राप्त करना बस एक कदम है। आदेश समाप्त करें; यह एक ऐसी गाथा है जिसके सफल होने के लिए इन्वेंट्री, वित्त, रिपोर्टिंग और सफाई कदमों की…
श्रृंखला में अगला
भुगतान प्रणालियाँ वितरित प्रणालियाँ क्यों हैं?
भुगतान किसी एक सेवा का काम नहीं है: बास्केट, स्टॉक, प्रदाता गेटवे और वित्त को एक ही तथ्य पर सहमत होना चाहिए। तुल्यकालिक श्रृंखला क्यों टूटती है?
वही सिलसिला
अपरिवर्तनीय चेकआउट स्नैपशॉट डिज़ाइन: वह निर्णय जो कार्ट को फ़्रीज़ कर देता है
भुगतान शुरू होते ही कार्ट को लाइव पढ़ने से राशि और मुद्रा अनिर्णीत रह जाती है। इरादे के क्षण में रुक जाने वाले स्नैपशॉट के बिना अंतिम रूप देना विश्वसनीय…