ایک کامیاب ادائیگی جو کبھی بکنگ میں تبدیل نہ ہو سکی
ایک صارف نے ادائیگی کی۔ Razorpay نے کامیابی دکھائی۔ Webhook نے HTTP 200 بھیجا۔ ادائیگی کیپچر (captured) ہو گئی۔
پھر بھی بکنگ "confirming" پر ہی رکی رہی۔
کوئی غلطی (error) ظاہر نہیں ہوئی۔ کوڈ میں کوئی استثنیٰ (exception) پیش نہیں آیا۔ کوئی الرٹ نہیں آیا۔ ہر میٹرک ایک صحت مند سسٹم کی نشاندہی کر رہا تھا۔
لیکن صارف کے پاس کچھ نہیں تھا۔ تخلیق کار (creator) کے پاس کوئی بکنگ نہیں تھی۔
رقم وصول کرنا آسان ہے۔ ہر ادائیگی کے نتیجے میں بکنگ یقینی بنانا اصل چیلنج ہے۔
زیادہ تر ٹیوٹوریلز اس بہاؤ (flow) کا مشورہ دیتے ہیں:
- Webhook ایونٹ وصول کرتا ہے
- Webhook بکنگ کو اپ ڈیٹ کرتا ہے
یہ خطرناک ہے۔ اگر بزنس لاجک (business logic) ویب ہک کے اندر ہو، تو آپ مکمل طور پر ڈیلیوری کی کامیابی پر منحصر ہوتے ہیں۔ Webhooks کو ری ٹرائیز (retries)، ڈپلیکیٹس (duplicates)، اور جزوی ناکامیوں کا سامنا کرنا پڑتا ہے۔
ہم نے ان کاموں کو الگ کرنے کے لیے اپنے آرکیٹیکچر (architecture) کو تبدیل کیا۔ اب Webhooks صرف ایونٹس ریکارڈ کرتے ہیں۔ وہ بزنس لاجک پر عمل درآمد نہیں کرتے۔
ہم نے تین ٹیبلز کے ساتھ ایک ایونٹ لیجر (event ledger) متعارف کرایا:
- payment_orders: فراہم کنندہ کی حقیقت (provider truth)
- payment_events: ناقابل تبدیلی ایونٹ لیجر (immutable event ledger)
- bookings: کاروباری حقیقت (business truth)
اب ویب ہک کا صرف ایک کام ہے:
- سگنیچر کی تصدیق کرنا
- ایونٹ کو محفوظ کرنا
- 200 واپس کرنا
یہ سسٹم کی حفاظت کرتا ہے۔ اگر ویب ہک ناکام ہو جائے، تب بھی ایونٹ محفوظ رہتا ہے۔
ہم نے یہ بھی سیکھا کہ ادائیگی کی حالت (payment state) اور بکنگ کی حالت (booking state) مختلف ہوتی ہے۔ ایک کیپچر شدہ ادائیگی ایک ان پٹ ہے۔ ایک کنفرم شدہ بکنگ اس کا نتیجہ ہے۔ انہیں الگ رکھنے سے توازن (reconciliation) برقرار رکھنے میں مدد ملتی ہے۔
تحقیقات کے دوران، ہمیں ایک بگ (bug) ملا۔ ایونٹس ڈیٹا بیس میں موجود تھے۔ پروسیسر (processor) ٹھیک کام کر رہا تھا۔ ویب ہک بھی ٹھیک تھا۔
لیکن پروسیسر کبھی چلا ہی نہیں۔ کوئی بھی فنکشن کو پینڈنگ ایونٹس پروسیس کرنے کے لیے ٹرگر نہیں کر رہا تھا۔
ڈیٹا وصول کرنے (ingestion) کو پروسیسنگ سے الگ کرنا ایک اچھا ڈیزائن ہے۔ لیکن یہ ایک نئی ضرورت پیدا کرتا ہے: کسی چیز کو پروسیسنگ کو ٹرگر کرنا ہوگا۔
ہم نے کئی کاموں کو چلانے کے لیے ایک شیڈولر (scheduler) نافذ کیا:
- ادائیگی کے ایونٹس کو پروسیس کرنا
- مس ہوئے ویب ہکس کو بحال کرنا
- سسٹم کے تسلسل (consistency) کی تصدیق کرنا
ری ٹرائیز کے دوران غلطیوں سے بچنے کے لیے، ہم یہ لاجک استعمال کرتے ہیں:
- غیر پروسیس شدہ ایونٹس کا انتخاب کرنا
- متعدد ورکرز کی اجازت دینے کے لیے "SKIP LOCKED" کا استعمال کرنا
- اس بات کو یقینی بنانا کہ ڈپلیکیٹ ڈیلیوریز سے کچھ نہ ہو
ایسا سسٹم جو صرف اس وقت کام کرتا ہے جب ہر ویب ہک وقت پر پہنچے، ایک کمزور (fragile) سسٹم ہے۔ اگر آپ کی قطار (queue) کو خالی کرنے والا کوئی نہیں ہے، تو کام ہمیشہ کے لیے انتظار کرتا رہے گا۔
بھروسہ مندی (Reliability) کا مطلب ہے اس صورتحال کے لیے تیاری کرنا جب چیزیں ناکام ہو جائیں۔