পেমেন্ট সিস্টেম ডিজাইন
সমস্যাটি বোঝা
যখনই আপনি কোনো অ্যাপে "Pay" বাটনে ট্যাপ করেন, তখন আড়ালে অনেকগুলো জটিল কাজ একসাথে ঘটতে থাকে। একটি পেমেন্ট সিস্টেম (যেমন Stripe) এর মূল কাজ হলো অ্যাকাউন্টগুলোর মধ্যে নির্ভরযোগ্য, সুরক্ষিত এবং ঠিক একবার টাকা লেনদেন নিশ্চিত করা — এমনকি নেটওয়ার্ক ফেল করলে, সার্ভিস ক্র্যাশ করলে বা ব্যবহারকারী দুইবার "Pay" বাটনে চাপ দিলেও।
ফাংশনাল রিকয়ারমেন্টস:
- পেমেন্ট প্রসেসিং: টাকার পরিমাণ, কারেন্সি (মুদ্রা), পেমেন্টের ধরন এবং মার্চেন্টের তথ্যসহ পেমেন্ট রিকোয়েস্ট গ্রহণ করা। কাস্টমারকে চার্জ করা এবং মার্চেন্টের অ্যাকাউন্টে টাকা জমা করা।
- রিফান্ড বা ফেরত: একটি সম্পন্ন হওয়া പেমেন্ট ফেরত দেওয়া — আংশিক বা সম্পূর্ণ — এবং লেজারের (হিসাবের খাতা) দুই পাশেই তা আপডেট করা।
- পেমেন্ট স্ট্যাটাস ট্র্যাক করা: প্রতিটি পেমেন্ট কয়েকটি ধাপে পার হয়:
created → processing → succeeded/failed। ক্লায়েন্টরা স্ট্যাটাস আপডেটের জন্য পোল করতে পারে বা ওয়েবহুক পেতে পারে। - ওয়েবহুকস (Webhooks): পেমেন্টের বিভিন্ন ইভেন্ট (পেমেন্ট সফল, রিফান্ড দেওয়া, ডিসপিউট হওয়া) সম্পর্কে মার্চেন্টদের HTTP কলব্যাকের মাধ্যমে জানানো, সাথে রিট্রাই লজিক থাকা।
নন-ফাংশনাল রিকয়ারমেন্টস:
- ঠিক-একবার (Exactly-once) প্রসেসিং: এটি সবচেয়ে গুরুত্বপূর্ণ রিকয়ারমেন্ট। যদি নেটওয়ার্ক টাইমআউটের কারণে ক্লায়েন্ট আবার চেষ্টা (retry) করে, সিস্টেম কোনোভাবেই কাস্টমারকে দুবার চার্জ করবে না। এটি ইডেমপোটেন্সি কি (idempotency keys) এর মাধ্যমে নিশ্চিত করা হয়।
- হাই অ্যাভেইলেবিলিটি (High availability): ৯৯.৯৯৯% আপটাইম — এমনকি কয়েক মিনিটের ডাউনটাইম মানে লাখ লাখ টাকার ক্ষতি।
- ডেটা কনসিস্টেন্সি: টাকা কখনোই নিজ থেকে তৈরি বা ধ্বংস হতে পারবে না। প্রতিটি ডেবিটের জন্য একটি সমান ক্রেডিট থাকতে হবে (ডাবল-এন্ট্রি বুককিপিং)।
- PCI-DSS কমপ্লায়েন্স: কার্ডের নম্বরগুলোকে অবশ্যই টোকেনাইজড এবং এনক্রিপ্ট করে রাখতে হবে, কখনোই প্লেইনটেক্সট হিসেবে সেভ করা যাবে না।
- অডিট ট্রেইল (Audit trail): নিয়মকানুন মেনে চলা এবং যেকোনো বিতর্ক এড়ানোর জন্য প্রতিটি কাজ অপরিবর্তনীয়ভাবে রেকর্ড করা থাকতে হবে।
প্রাথমিক একটা হিসাব-নিকাশ
চলুন একটি মাঝারি থেকে বড় পেমেন্ট প্রসেসরের সাইজ বের করি:
- প্রতিদিনের লেনদেন: দিনে ১০ লাখ পেমেন্ট
- গড় লেনদেনের পরিমাণ: ৫০ ডলার → প্রতিদিন ৫০ মিলিয়ন ডলার ভলিউম
- পিক থ্রুপুট: পিক আওয়ারে প্রতি সেকেন্ডে ~১০০ লেনদেন (TPS) (গড়ের ২-৩ গুণ)
- লেনদেন প্রতি স্টোরেজ: ~১ KB (পেমেন্ট রেকর্ড + লেজার এন্ট্রি + অডিট লগ) → প্রতিদিন ~১ GB, বছরে ~৩৬৫ GB
- আপটাইম রিকয়ারমেন্ট: ৯৯.৯৯৯% ("ফাইভ নাইনস") — বছরে মাত্র ~৫ মিনিট ডাউনটাইম হতে পারে
- ওয়েবহুক ডেলিভারি: প্রতিদিন ~৩ মিলিয়ন ওয়েবহুক ইভেন্ট (প্রতি পেমেন্টে একাধিক ইভেন্ট: created, processing, succeeded)
সোশ্যাল মিডিয়া সিস্টেমের তুলনায় এর থ্রুপুট বেশ কম, কিন্তু সঠিকতার রিকয়ারমেন্ট হলো চরম লেভেলের। কোনো সোশ্যাল মিডিয়ার পোস্ট দুবার দেখালে হয়তো একটু বিরক্তি লাগে; কিন্তু একবার পেমেন্ট করে দুবার বিল কাটা গেলে তা একটি বড় আইনি ও আর্থিক ঝামেলার ব্যাপার।
API ডিজাইন
পরিচ্ছন্ন, ইডেমপোটেন্ট (idempotent) এপিআই হলো একটি নির্ভরযোগ্য পেমেন্ট সিস্টেমের মূল ভিত্তি।
পেমেন্ট তৈরি করা
POST /api/v1/payments
Headers:
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer sk_live_...
Body:
{
"amount": 4999, // কিসে হিসাব হচ্ছে — ভগ্নাংশের ঝামেলা এড়াতে সবসময় পূর্ণসংখ্যা (integer) ব্যবহার করুন
"currency": "usd",
"payment_method": "pm_card_visa_4242",
"merchant_id": "merch_abc123",
"description": "Order #7892",
"metadata": { "order_id": "7892" }
}
Response: 201 Created
{
"id": "pay_1234567890",
"status": "processing",
"amount": 4999,
"currency": "usd",
"created_at": "2026-03-10T14:30:00Z"
}পেমেন্ট স্ট্যাটাস দেখা
GET /api/v1/payments/pay_1234567890
Response: 200 OK
{
"id": "pay_1234567890",
"status": "succeeded",
"amount": 4999,
"currency": "usd"
}পেমেন্ট রিফান্ড করা
POST /api/v1/payments/pay_1234567890/refund
Headers:
Idempotency-Key: 660e9500-f30c-52e5-b827-557766551111
Body:
{
"amount": 4999, // সম্পূর্ণ রিফান্ড; আংশিক হলে সেই পরিমাণ দিন
"reason": "customer_request"
}
Response: 201 Created
{
"id": "ref_0987654321",
"payment_id": "pay_1234567890",
"status": "processing",
"amount": 4999
}মূল ডিজাইনের সিদ্ধান্তগুলো হলো: পরিমাণগুলো সেন্ট (cents) এ রাখা (পূর্ণসংখ্যা ভগ্নাংশের বাগ এড়ায়), প্রতিটি মিউটেটিং এন্ডপয়েন্টে ইডেমপোটেন্সি কি (idempotency keys) রাখা, এবং অ্যাসিঙ্ক্রোনাস আপডেটের জন্য স্ট্যাটাস পোলিং + ওয়েবহুক ব্যবহার করা।
ইডেমপোটেন্সি এবং ডাবল-এন্ট্রি বুককিপিং
ইডেমপোটেন্সি (Idempotency) হলো পেমেন্ট সিস্টেম ডিজাইনের সবচেয়ে ইম্পর্ট্যান্ট একটি কনসেপ্ট। এটি যেভাবে কাজ করে:
- ক্লায়েন্ট রিকোয়েস্ট করার আগে একটি UUID (ইডেমপোটেন্সি কি) তৈরি করে।
- সার্ভার যখন রিকোয়েস্ট পায়, তখন সে চেক করে এই কি-টি আগে থেকেই ইডেমপোটেন্সি স্টোরে (একটি Redis ক্যাশ বা ডাটাবেস টেবিল) আছে কিনা।
- যদি কি-টি থাকে, তবে ক্যাশ করা রেজাল্টটি ফেরত দেয় — পেমেন্টটি দ্বিতীয়বার প্রসেস করে না।
- যদি কি-টি নতুন হয়, তবে পেমেন্টটি স্বাভাবিকভাবে প্রসেস করে এবং সেই UUID দিয়ে রেজাল্টটি সেভ করে রাখে।
এর মানে হলো, ক্লায়েন্ট যদি (নেটওয়ার্ক টাইমআউটের কারণে) ১০ বারও রিট্রাই করে, পেমেন্ট শুধুমাত্র একবারই প্রসেস হবে।
ডাবল-এন্ট্রি বুককিপিং (Double-Entry Bookkeeping): প্রতিটি লেনদেন ঠিক দুটি লেজার এন্ট্রি তৈরি করে — একটি ডেবিট এবং একটি ক্রেডিট — যেগুলোর যোগফল শূন্য হয়। ৪৯.৯৯ ডলারের একটি পেমেন্টের জন্য:
- ডেবিট: কাস্টমার অ্যাকাউন্ট −$৪৯.৯৯
- ক্রেডিট: মার্চেন্ট অ্যাকাউন্ট +$৪৯.৯৯
রিফান্ডের ক্ষেত্রে এন্ট্রিগুলো উল্টে যায়:
- ডেবিট: মার্চেন্ট অ্যাকাউন্ট −$৪৯.৯৯
- ক্রেডিট: কাস্টমার অ্যাকাউন্ট +$৪৯.৯৯
লেজারটি অ্যাপেন্ড-অনলি (append-only) — এন্ট্রিগুলো কখনো আপডেট বা ডিলিট করা হয় না, শুধুমাত্র নতুন এন্ট্রি যোগ করা হয়। এটি একটি অপরিবর্তনীয় অডিট ট্রেইল তৈরি করে।
রিকনসিলিয়েশন (Reconciliation): একটি ব্যাকগ্রাউন্ড ওয়ার্কার নিয়মিত অভ্যন্তরীণ লেজারের হিসাবের সাথে এক্সটার্নাল পেমেন্ট প্রসেসরের রেকর্ডের তুলনা করে। কোনো অমিল পাওয়া গেলে তা তদন্তের জন্য মার্ক করা হয়। এটি বাগ, ফ্রড এবং প্রসেসরের এরর ধরতে সাহায্য করে।
লেজার ডিজাইন এবং ফেইলিউর হ্যান্ডলিং
অ্যাপেন্ড-অনলি লেজার: লেজার হলো সমস্ত টাকার লেনদেনের চূড়ান্ত সত্য। এটি ইভেন্ট-সোর্সিং (event-sourcing) প্যাটার্ন ব্যবহার করে — বর্তমান ব্যালেন্স স্টোর করার বদলে (যা ভুল হতে পারে), প্রতিটি লেনদেনকে অপরিবর্তনীয় ইভেন্ট হিসেবে স্টোর করা হয়। ইভেন্টগুলো রিপ্লে করেই বর্তমান ব্যালেন্স বের করা হয়।
লেজার এন্ট্রির স্কিমা:
{
"entry_id": "led_abc123",
"payment_id": "pay_1234567890",
"account_id": "acct_merchant_xyz",
"type": "credit",
"amount": 4999,
"currency": "usd",
"created_at": "2026-03-10T14:30:00Z",
"description": "Payment for Order #7892"
}এক্সটার্নাল প্রসেসর ফেইলিউর সামলানো:
- টাইমআউট: যদি এক্সটার্নাল প্রসেসর (Visa, Mastercard) রেসপন্স না করে, তবে সাথে সাথে ফেইল করবেন না। এক্সপোনেনশিয়াল ব্যাকঅফ (exponential backoff) (১সে, ২সে, ৪সে, ৮সে...) ব্যবহার করে সর্বোচ্চ ৫ বার পর্যন্ত রিট্রাই করুন।
- প্রসেসর ডাউন: যদি প্রাইমারি প্রসেসর অ্যাভেইলেবল না থাকে, তবে একটি ব্যাকআপ প্রসেসরে রিকোয়েস্ট রাউট করুন। বড় পেমেন্ট সিস্টেমগুলো একাধিক প্রসেসরের সাথে সম্পর্ক বজায় রাখে।
- আংশিক ফেইলিউর: যদি প্রসেসরে চার্জ সফল হয় কিন্তু লেজারে রাইট করতে ফেইল করে, তবে সাগা প্যাটার্ন (saga pattern) ব্যবহার করুন — প্রসেসর লেভেলে একটি ভয়েড/রিফান্ড দিয়ে চার্জটি রোলব্যাক করুন।
- আটকে থাকা পেমেন্ট: একটি রিকনসিলিয়েশন ওয়ার্কার এমন পেমেন্টগুলো শনাক্ত করে যেগুলো অনেকক্ষণ ধরে "processing" অবস্থায় আটকে আছে এবং সেগুলো হয় সম্পন্ন করে নতুবা রিভার্স করে দেয়।