রিট্রাই আর ডুপ্লিকেট সুরক্ষাসহ সার্ভার-সাইড পেমেন্ট প্রক্রিয়া।
1. ID আর অ্যাক্সেস প্রস্তুত করো
চালু স্টোর আর পরীক্ষিত পেমেন্ট পদ্ধতি দিয়ে শুরু করো। সেটিংস → API accessথেকে শুধু দরকারি প্রজেক্টে সীমিত পড়া/লেখার ক্রেডেনশিয়াল বানাও। টোকেন ব্যাকএন্ডে রাখো, ব্রাউজার কোড বা পাবলিক রিপোজিটরিতে কখনো নয়।
কপি করো প্রজেক্ট API ID এবং স্টোর API ID স্টোরের বেসিক → API ID বক্স থেকে। এগুলো UUID, পড়ার মতো প্রজেক্ট পরিচয়সূচক বা অর্ডার নম্বর নয়। নিজের API হোস্টনেম ব্যবহার করো।
এখানে স্টোর → IPNথেকে স্বাক্ষরের সিক্রেট তৈরি করো, এটি দেওয়ার আগে: ipn_url। মার্চেন্ট VPS থেকে তোমার HTTPS রিসিভারে পৌঁছানো যেতে হবে।
2. ইনভয়েস তৈরি করো
প্লেসহোল্ডার বদলে ব্যাকএন্ড থেকে অনুরোধ পাঠাও। পরিমাণ দশমিক স্ট্রিং, ফ্লোটিং-পয়েন্ট হিসাব নয়।
curl --fail-with-body --request POST \
'https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/invoices' \
--header 'Authorization: Bearer YOUR_MERCHANT_API_TOKEN' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: order-1042-attempt-1' \
--data '{
"amount": "10.00",
"currency": "EUR",
"order_id": "order-1042",
"description": "Example order",
"ipn_url": "https://shop.example.com/payments/wholly-ipn",
"metadata": {
"cart_id": "cart-1042"
}
}'সেভ করো data.invoice_id অর্ডারের সঙ্গে, তারপর গ্রাহককে পাঠাও links.checkout। নতুন পেমেন্ট চেষ্টায় আলাদা আইডেম্পোটেন্সি কী দাও। টাইমআউটে আবার চেষ্টা করো একই ক্রেডেনশিয়াল, কী আর বডির হুবহু একই বাইট দিয়ে.
বাদ দিলে payment_methods স্টোরের গৃহীত পদ্ধতি ব্যবহার হয়। চেইন স্লাগ আর টিকার দিয়ে প্রতি ইনভয়েসে সীমিত করতে পারো; এতে গ্রহণ করা হয়নি এমন অ্যাসেট কখনো চালু হয় না। সব অনুরোধ ফিল্ড আর রেসপন্সের উদাহরণ →
3. IPN, ওয়েবহুক বা দুটোই বেছে নাও
IPN ইনভয়েসের জীবনচক্র অনুসরণ করে। স্টোরের ডিফল্ট IPN URL দাও বা ওভাররাইড করো ipn_url দিয়ে একটি ইনভয়েসের জন্য। ওয়েবহুক নির্বাচিত ইভেন্টে এন্ডপয়েন্ট সাবস্ক্রাইব করে, যেমন invoice.settled.
স্বাক্ষরের ফরম্যাট একই, কিন্তু সিক্রেট আলাদা: IPN স্টোরের IPN সিক্রেট ব্যবহার করে; প্রতি ওয়েবহুক এন্ডপয়েন্টের নিজস্ব সিক্রেট। কোনোটিই স্বাক্ষরে API বেয়ারার টোকেন ব্যবহার করে না।
দুটোই অ্যাপে পাঠালে একই বিষয়ের একাধিক নোটিফিকেশন আসতে পারে। অর্ডারে দুবার ক্রেডিট দিও না।
4. নোটিফিকেশন যাচাই করে সেভ করো
- JSON পার্স করার আগে হুবহু র অনুরোধ বডি পড়ো। যাচাই করো
Wholly-Signatureসঠিক সিক্রেট আর টাইমস্ট্যাম্প/রিপ্লে চেক দিয়ে। অফিসিয়াল SDK-তে ভেরিফায়ার আছে। - স্বাক্ষরিত বডির প্রজেক্ট, স্টোর, ইনভয়েস আর ইভেন্ট পরিচয় যাচাই করো। স্বাক্ষরহীন ডেলিভারি হেডার পরিচয় যাচাইয়ের উৎস নয়।
- ইভেন্ট স্থায়ীভাবে সেভ করো একটি অনন্য
event_idদিয়ে, তারপর দ্রুত HTTP 2xx ফেরত দাও। ব্যাকগ্রাউন্ড ওয়ার্কারে অর্ডার প্রসেস করো। - কনফিগার করা API হোস্ট থেকে বর্তমান ইনভয়েস নাও, অনুরোধে দেওয়া যেকোনো হোস্ট থেকে নয়। সেভ করা প্রজেক্ট, স্টোর, পরিমাণ, মুদ্রা আর অর্ডার রেফারেন্স মেলাও।
PHP · Python · JavaScript / TypeScript · স্বাক্ষরের নিয়ম আর রিসিভারের উদাহরণ
5. নিষ্পত্তির পরে একবারই অর্ডার পূরণ করো
একটি ইভেন্টভিত্তিক রিসিভারে সামলাও event_type = invoice.settled, তারপর বর্তমানটি যাচাই করো: status = settled আর তোমার ব্যতিক্রম নীতি। ডেটাবেস ট্রান্স্যাকশন/অনন্য অর্ডারের বাধার মধ্যে একবারই অর্ডার পূরণ করো।
দ্রুত চূড়ান্ত হওয়া চেইন দুটোই পাঠাতে পারে: payment.received এবং invoice.settled এর সঙ্গে status = settled। অন্য চেইনে payment.received তখনো processing বলতে পারে। কোনোটিই ত্রুটি নয়।
ইভেন্টের ডুপ্লিকেট বাদ দাও event_idদিয়ে, শুধু সিকোয়েন্স দিয়ে নয়: আলাদা ইভেন্টের একই সিকোয়েন্স হতে পারে। স্টেটভিত্তিক SDK হ্যান্ডলার বরং ইনভয়েস রিভিশন এক করে আর ইভেন্টের ধরন না দেখে স্টেট দেখে। এই এক করার পদ্ধতির সঙ্গে ইভেন্ট-টাইপ ফিল্টার মেশিও না। দুই পদ্ধতিতেই অর্ডার স্তরে ডুপ্লিকেট সুরক্ষা দরকার।
দেখো requires_review আর ম্যানুয়াল সিদ্ধান্ত, অর্ডার পূরণের আগে। amount_status = paid একা কনফার্মেশনের প্রমাণ নয়। উপরের স্তরের পেইড অ্যাসেট ফিল্ড নিষ্পত্তির সারাংশ দেয়; payment_info বিস্তারিত প্রাপ্তি আর কোটের ডেটা রাখে। সব স্ট্যাটাস, ইভেন্ট আর ব্যতিক্রমের নিয়ম →
6. আবার চেষ্টা আর পুনরুদ্ধার পরীক্ষা করো
ছোট পেমেন্ট, ডুপ্লিকেট ডেলিভারি, মেয়াদোত্তীর্ণ ইনভয়েস আর সাময়িক বন্ধ রিসিভার পরীক্ষা করো। ইভেন্ট আবার চালালে দ্বিতীয়বার অর্ডার ক্রেডিট হওয়া চলবে না। এলোমেলো ক্রমে ইভেন্ট এলেও নতুন স্টেটের ওপর পুরোনোটি লিখো না।
দেখো স্টোর → IPN / ওয়েবহুক → ইতিহাস → বিস্তারিত, অথবা ইনভয়েসের বিস্তারিততে ডেলিভারি অংশ। আবার পাঠালে রেকর্ড করা ইভেন্টই যায়, নতুন নিষ্পত্তি নয়।
কম প্রসেসিং ক্রেডিটে পেমেন্ট চললেও IPN/ওয়েবহুক থামে। API দিয়ে বাকি অর্ডার মেলাও আর পুনরুদ্ধারের পরে রাখা ডেলিভারি সামলাও। ব্রাউজার রিডাইরেক্ট বা গ্রাহকের স্ক্রিনশট দেখে কখনো অর্ডার পূরণ কোরো না।