আপনি যদি WHMCS ব্যবহার করেন, তবে পরিবর্তে WHMCS মডিউলটি ব্যবহার করুন — এই পৃষ্ঠাটি অন্যান্য সবকিছুর জন্য। এখানে দুটি বিকল্প রয়েছে, দুটিই বিনামূল্যে এবং দুটিই GPL-2.0-or-later লাইসেন্সযুক্ত।
HostBill
একটি হোস্টিং মডিউল যাতে WHMCS মডিউলের মতোই একই ছয়টি অ্যাকশন রয়েছে।
- এটি ডাউনলোড করুন এবং আনজিপ করুন।
zinn ডিরেক্টরিটি includes/modules/Hosting/-এ আপলোড করুন যাতে ফাইলগুলি includes/modules/Hosting/zinn/class.zinn.php এবং includes/modules/Hosting/zinn/ZinnHostBillClient.php-এ পৌঁছে যায়।
- Settings → Modules → Hosting-এ যান, Zinn Digital® সক্রিয় করুন এবং একটি সংযোগ যুক্ত করুন:
- API address:
https://api.zinndigital.com
- API key: আপনার Zinn® API কী (একটি
password ফিল্ড, তাই HostBill এটি এনক্রিপ্ট করে সংরক্ষণ করে)
- পণ্যটিতে Product line (যেমন
mainstream), Stack (ডিফল্টভাবে wordpress), এবং ঐচ্ছিকভাবে Application ও PHP version সেট করুন।
- Test connection চাপুন।
⛔ zinn ডিরেক্টরিটির নাম পরিবর্তন করবেন না। HostBill-এর লোডার যে ক্লাসটি সন্ধান করে তা ডিরেক্টরির নাম থেকেই নির্ধারণ করে, তাই নাম পরিবর্তন করলে এমন একটি মডিউল তৈরি হয় যা প্যানেল তালিকায় দেখায় কিন্তু কখনই কল করে না।
অন্য যেকোনো কিছুর জন্য — PHP ক্লায়েন্ট
একটি ফাইল, কোনো নির্ভরতা নেই, কোনো প্যানেল সংক্রান্ত অনুমান নেই। আপনার নিজস্ব কোডবেসে ZinnProvisioning.php যুক্ত করুন এবং ছয়টি মেথড কল করুন।
require_once 'ZinnProvisioning.php';
$zinn = new ZinnProvisioning(getenv('ZINN_API_KEY'));
// When an order is paid — once per CUSTOMER, then once per SERVICE:
$orgId = $zinn->account('customer-4211', 'Acme Ltd');
$siteId = $zinn->provision('service-9915', $orgId, 'acme.com', 'mainstream', 'wordpress');
// Store $orgId against your customer and $siteId against your service.
$zinn->suspend($siteId, 'INV-2026-114 unpaid'); // an invoice goes unpaid
$zinn->unsuspend($siteId); // they pay
$zinn->terminate($siteId); // they cancel — schedules a deletion
// When they click "log in to my hosting" — mint it on the CLICK, never on page render:
header('Location: ' . $zinn->signInLink($siteId));
PHP-তে কোড লিখছেন না? একই কলগুলি API রেফারেন্সে রয়েছে এবং আপনি যেকোনো কিছু থেকেই সেগুলি করতে পারেন।
API কী
সাতটি অনুমতি, এবং এর বেশি নয়: org.create, org.read, sites.create, sites.view, sites.delete, reseller.view, reseller.provision।
⛔ reseller.manage নয়। আপনি একটি বিলিং প্যানেলে যে কী পেস্ট করেন তা অর্থ প্রদান না করার কারণে একজন গ্রাহককে স্থগিত রাখতে এবং তাদের সাইন ইন করাতে সক্ষম হওয়া উচিত; এটি আপনার নিজস্ব পেমেন্ট-গেটওয়ে ক্রেডেনশিয়াল পুনর্লিখন করতে সক্ষম হওয়া উচিত নয়।
যে দুটি নিয়ম ভঙ্গ করলে অর্থ অপচয় হয়
- অ্যাকাউন্টটি আপনার CUSTOMER-এর সাথে এবং সাইটটি আপনার SERVICE-এর সাথে যুক্ত করুন। একজন গ্রাহকের দ্বিতীয় অর্ডারটি অবশ্যই তাদের ইতিমধ্যে থাকা অ্যাকাউন্টে প্রবেশ করতে হবে। উভয়কেই সার্ভিসের সাথে যুক্ত করলে একজন গ্রাহক তিনটি অসম্পর্কিত অ্যাকাউন্ট এবং তিনটি পৃথক কন্ট্রোল প্যানেল পেয়ে যাবেন।
- প্রত্যেকটি তৈরির সময় একটি আইডেমপোটেন্সি কী পাঠান, যা বিষয়টির জন্য আপনার নিজস্ব আইডি থেকে প্রাপ্ত। প্রতিটি বিলিং সিস্টেম পুনরায় চেষ্টা করে — একটি গেটওয়ে কলব্যাক দুবার আসে, একজন অ্যাডমিন ব্যর্থ প্রোভিশন পুনরায় চালু করেন, একজন গ্রাহক ডাবল-ক্লিক করেন। এটি ছাড়া দ্বিতীয় প্রচেষ্টা একটি দ্বিতীয় সাইট তৈরি করে এবং এর জন্য আপনার কাছ থেকে বিল নেওয়া হয়। উভয় মডিউল এবং PHP ক্লায়েন্ট আপনার জন্য এটি করে; আপনি যদি সরাসরি API কল করেন, তবে
Idempotency-Key পাঠান।
তিনটি ফিল্ড যা সহজেই বাদ পড়ে যায়
প্রতিটি ফিল্ড একটি সম্পূর্ণ ক্রিয়াকলাপ নষ্ট করে দেয়, এবং বৈধতা ত্রুটি ছাড়া অন্য কোনো ত্রুটি হিসেবে প্রদর্শিত হয় না — কেবল প্রথমটি ছাড়া, যা একেবারেই কিছুই না হিসেবে প্রদর্শিত হয়:
- ⛔⛔ একজন ক্লায়েন্টের প্রথম সাইট প্রোভিশন করার আগেই তাকে একটি প্ল্যানের আওতাভুক্ত করতে হবে, যা
POST /v1/reseller/clients/{orgId}/plan-এর মাধ্যমে করতে হবে, এবং এর subscription_id POST /v1/sites-এ পাঠাতে হবে। এটি এমন একটি ক্ষেত্র যেখানে পড়ার মতো কোনো ত্রুটি থাকে না। একটি নতুন ক্লায়েন্ট অ্যাকাউন্টে কোনো সাবস্ক্রিপশন থাকে না এবং POST /v1/sites-এ কোনো প্ল্যান ফিল্ড নেই, তাই কোনো প্ল্যান ছাড়া প্রোভিশন করা সাইটে একেবারেই কোনো প্ল্যান থাকে না: আপনার হোলসেল স্টেটমেন্ট আপনার ক্লায়েন্টদের কার্যকর সাবস্ক্রিপশন থেকে তৈরি হয়, তাই কোনো লাইন যোগ হয় না এবং হোস্টিং চলাকালীন Zinn® আপনার কাছ থেকে কোনো অর্থ চার্জ করে না; আপনার ক্লায়েন্ট কোনো অ্যালাউন্স পান না, তাই তাদের সাইটে কোনো কোটা প্রয়োগ করা হয় না; এবং কোনো আপগ্রেডের মাধ্যমে পরিবর্তন করার মতো কিছু থাকে না। অর্ডারটি 201 প্রদান করে, সাইটটি প্রোভিশন হয়, এবং এটি ত্রুটিহীনভাবে কাজ করে। কোনো প্রান্তেই এর কোনোটির বিবরণ রিপোর্ট করা হয় না।
ক্রমটি অত্যন্ত গুরুত্বপূর্ণ: POST /v1/sites কার্যকর হওয়ার মুহূর্তে যে সাবস্ক্রিপশন বিদ্যমান থাকে কেবল সেটিই রেকর্ড করে, তাই পরবর্তীতে সেট করা কোনো প্ল্যান পেছনের তারিখ থেকে প্রযোজ্য হয় না।
POST /v1/sites-এর জন্য stack_type আবশ্যক। এটি বাদ দিলে কোনো অর্ডারই সফল হতে পারে না।
DELETE /v1/sites/{siteId}-এর জন্য {"confirm_domain": "<the site's own domain>"} বডি প্রয়োজন — একটি টাইপ করা নিশ্চিতকরণ, কারণ এটি একটি ধ্বংসাত্মক ভার্ব। এটি বাদ দিলে কোনো বাতিলকরণ সফল হতে পারে না, ফলে সার্ভিসটি চলতেই থাকবে এবং এর জন্য আপনার কাছ থেকে বিল নেওয়া অব্যাহত থাকবে। আপনার নিজস্ব রেকর্ড ব্যবহারের পরিবর্তে GET /v1/reseller/services/{siteId} থেকে ডোমেনটি রিড করুন: এটি সাইটের নিজস্ব প্রাথমিক ডোমেনের সাথে তুলনা করা হয় এবং কোনো উপনামের (alias) সাথে কখনো নয়।
পুরো ত্রুটিটি পড়ুন, কেবল বাক্যটি নয়
যাচাইকরণ প্রত্যাখ্যানের বার্তাটি ইচ্ছাকৃতভাবেই সাধারণ রাখা হয়েছে — "The request was well-formed but failed validation." — কারণ কার্যকর পদক্ষেপ গ্রহণের অংশটি থাকে details-এ, যা ফিল্ডের নাম এবং কারণ উল্লেখ করে। উভয় মডিউল এবং PHP ক্লায়েন্ট আপনার অ্যাডমিনকে দেখানো বার্তার সাথে এটি যুক্ত করে। আপনি নিজে API কল করলে error.details পড়ুন; কিছু এন্ট্রিতে একটি বাক্যের পরিবর্তে কেবল একটি মান থাকে, যার ফলেই আপনার রিসেলার প্ল্যানে খালি জায়গা না থাকলে max_sites: 0 আপনার কাছে পৌঁছায়।
আপনার প্রথম অর্ডারের আগে
আপনার ক্লায়েন্টদের কেনা সাইটগুলি আপনার রিসেলার প্ল্যানের সাইট অ্যালাউন্সের বিপরীতে গণ্য হয়, তাই আপনার এমন একটি প্ল্যান প্রয়োজন যাতে খালি জায়গা রয়েছে। একটি সংযোগ পরীক্ষা এটি সনাক্ত করতে পারে না — এটি কেবল আপনার প্রোগ্রাম রিড করে এবং কিছুই প্রোভিশন করে না — তাই এটি একটি সুস্থ অ্যাকাউন্ট রিপোর্ট করে যা এখনও বিক্রি করতে পারে না। অ্যালাউন্স ছাড়া করা একটি অর্ডার স্পষ্টভাবে সেই কারণটি উল্লেখ করে প্রত্যাখ্যান করা হয়।
আপনার ডাউনলোড যাচাই করুন
উভয় আর্কাইভই আমাদের নিজস্ব হোস্টনেম থেকে TLS-এর মাধ্যমে সরবরাহ করা হয়, অন্য কোথাও কখনো পুনঃনির্দেশিত (redirect) হয় না, এবং downloads page-এ ডাউনলোড লিঙ্কগুলির পাশে তাদের SHA-256 চেকসাম মুদ্রিত থাকে।