مستندات وبسرویس
ساخت، تمدید، ارتقا و حذف سرویس از ربات یا سایت خودتان — مبلغ هر عملیات از اعتبار حساب شما کم میشود.
اتصال و احراز هویت #
هر درخواست یک فیلد action دارد؛ بقیهی فیلدها در همان سطح بدنه میآیند.
| مورد | مقدار |
|---|---|
| آدرس | https://api.neshanpro.com/api/v1.php |
| متد | فقط POST |
| بدنه | application/json — فرم urlencoded هم پذیرفته میشود |
| احراز هویت | هدر X-API-Key — کلید را از مدیریت دریافت میکنید |
اگر امکان فرستادن هدر ندارید، کلید را در بدنه با نام key بفرستید؛ ولی هدر ترجیح دارد چون در لاگ وبسرور ثبت نمیشود.
ساختار پاسخ #
همهی پاسخها JSON و با یک الگوی ثابتاند — موفق یا ناموفق. همهی مبالغ تومان و عدد صحیحاند.
{
"success": true,
"data": {}
}{
"success": false,
"code": "insufficient_balance",
"message": "اعتبار کافی نیست."
}code شرط بگذارید، نه روی message. متن پیام فارسی و برای نمایش به کاربر است و ممکن است تغییر کند؛ code ثابت است.خطاها #
| HTTP | code | معنی |
|---|---|---|
| 400 | missing_field | فیلد الزامی (مثل action یا شناسهی سرویس) نیامده |
| 400 | bad_request | مقدار ارسالی نامعتبر است |
| 400 | name_taken | نام سرویس تکراری است |
| 401 | unauthorized | کلید نیامده یا نامعتبر/غیرفعال است |
| 402 | insufficient_balance | اعتبار کمتر از مبلغ سفارش است |
| 403 | forbidden | این دسترسی برای حساب شما فعال نیست |
| 403 | custom_disabled | سرویس دلخواه/ارتقا برای شما فعال نیست |
| 403 | needs_purchase | سرویس بهخاطر حجم/زمان بسته شده؛ باید تمدید شود |
| 404 | service_not_found | سرویسی با این شناسه برای شما نیست |
| 404 | unknown_action | مقدار action شناخته شده نیست |
| 409 | plan_unavailable | این پلن برای شما فعال نیست |
| 409 | duplicate_order | این order_id قبلاً برای عملیات دیگری ثبت شده |
| 422 | limit_reached | به سقف تعداد سرویس رسیدهاید |
| 423 | disabled | فروش/تمدید/ارتقا/حذف موقتاً توسط مدیریت بسته شده |
| 429 | rate_limited | تعداد درخواست بیش از سقف دقیقهای |
| 502 | gate_error | ساخت روی سرورها ناموفق بود — هیچ مبلغی کم نشده |
خطاهای 429 و 502 موقتیاند؛ با کمی فاصله دوباره تلاش کنید. بقیهی خطاهای 4xx با تکرار درست نمیشوند.
اطلاعات حساب account.info #
بدون پارامتر. موجودی، تخفیف، سقفها، دسترسیها و وضعیت کلیدهای فروش. قبل از ثبت سفارش، shop را چک کنید.
curl -X POST https://api.neshanpro.com/api/v1.php \
-H 'Content-Type: application/json' \
-H 'X-API-Key: YOUR_KEY' \
-d '{"action":"account.info"}'
$api = new WebserviceClient('https://api.neshanpro.com/api/v1.php', 'YOUR_KEY');
$res = $api->call('account.info', []);
import requests
r = requests.post(
'https://api.neshanpro.com/api/v1.php',
headers={'X-API-Key': 'YOUR_KEY'},
json={"action":"account.info"},
timeout=30,
)
data = r.json()
if not data['success']:
print(data['code'], data['message'])
const r = await fetch('https://api.neshanpro.com/api/v1.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'YOUR_KEY' },
body: JSON.stringify({"action":"account.info"}),
});
const data = await r.json();
{
"account": {
"type": "reseller",
"name": "فروشگاه شما",
"status": "active"
},
"balance": 2450000,
"discount_pct": 10,
"limits": {
"max_services": 200,
"rate_limit_per_min": 60
},
"services": {
"total": 42,
"active": 38,
"disabled": 4,
"expired": 3
},
"custom": {
"allowed": true,
"prices": {
"per_gb": 2000,
"per_day": 1000,
"per_device": 5000
}
},
"shop": {
"sell": true,
"renew": true,
"update": true,
"delete": false,
"custom": true
},
"currency": "IRT"
}
shop.sell برابر false باشد، services.create با خطای disabled برمیگردد.لیست پلنها plans.list #
پلنهایی که شما اجازهی فروششان را دارید، با قیمت اختصاصی شما.
curl -X POST https://api.neshanpro.com/api/v1.php \
-H 'Content-Type: application/json' \
-H 'X-API-Key: YOUR_KEY' \
-d '{"action":"plans.list"}'
$api = new WebserviceClient('https://api.neshanpro.com/api/v1.php', 'YOUR_KEY');
$res = $api->call('plans.list', []);
import requests
r = requests.post(
'https://api.neshanpro.com/api/v1.php',
headers={'X-API-Key': 'YOUR_KEY'},
json={"action":"plans.list"},
timeout=30,
)
data = r.json()
if not data['success']:
print(data['code'], data['message'])
const r = await fetch('https://api.neshanpro.com/api/v1.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'YOUR_KEY' },
body: JSON.stringify({"action":"plans.list"}),
});
const data = await r.json();
{
"rows": [
{
"id": 3,
"name": "یک ماهه ۵۰ گیگ",
"quota_gb": 50,
"duration_days": 30,
"max_devices": 2,
"price": 500000,
"discount_pct": 10,
"payable": 450000
}
],
"discount_pct": 10
}
payable را ملاک بگیرید؛ همان مبلغی است که واقعاً کم میشود.استعلام قیمت price.quote #
مبلغ را بدون ساختن چیزی حساب میکند — برای نمایش قیمت به مشتری قبل از خرید.
| پارامتر | نوع | الزامی | توضیح |
|---|---|---|---|
plan_id | عدد | یا | شناسهی پلن |
quota_gb | عدد | یا | حجم سرویس دلخواه |
duration_days | عدد | — | روز سرویس دلخواه |
max_devices | عدد | — | تعداد دستگاه (پیشفرض ۱) |
curl -X POST https://api.neshanpro.com/api/v1.php \
-H 'Content-Type: application/json' \
-H 'X-API-Key: YOUR_KEY' \
-d '{"action":"price.quote","quota_gb":20,"duration_days":30,"max_devices":2}'
$api = new WebserviceClient('https://api.neshanpro.com/api/v1.php', 'YOUR_KEY');
$res = $api->call('price.quote', {"quota_gb":20,"duration_days":30,"max_devices":2});
import requests
r = requests.post(
'https://api.neshanpro.com/api/v1.php',
headers={'X-API-Key': 'YOUR_KEY'},
json={"action":"price.quote","quota_gb":20,"duration_days":30,"max_devices":2},
timeout=30,
)
data = r.json()
if not data['success']:
print(data['code'], data['message'])
const r = await fetch('https://api.neshanpro.com/api/v1.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'YOUR_KEY' },
body: JSON.stringify({"action":"price.quote","quota_gb":20,"duration_days":30,"max_devices":2}),
});
const data = await r.json();
{
"base_price": 85000,
"discount_pct": 10,
"price": 76500,
"credit": 2450000
}
ثبت سفارش services.create #
سرویس جدید؛ مبلغ از اعتبار کم و سرویس روی سرورها ساخته میشود. یا plan_id بدهید، یا (اگر برایتان فعال است) حجم و مدت دلخواه.
| پارامتر | نوع | الزامی | توضیح |
|---|---|---|---|
name | متن | ✔ | نام یکتای سرویس |
plan_id | عدد | یا | شناسهی پلن |
quota_gb / duration_days / max_devices | عدد | یا | سرویس دلخواه |
order_id | متن | ✖ | شناسهی سفارش خودتان، حداکثر ۶۴ کاراکتر — بهشدت توصیه میشود |
note | متن | ✖ | یادداشت |
curl -X POST https://api.neshanpro.com/api/v1.php \
-H 'Content-Type: application/json' \
-H 'X-API-Key: YOUR_KEY' \
-d '{"action":"services.create","name":"reza-1404","plan_id":3,"order_id":"ORDER-1001"}'
$api = new WebserviceClient('https://api.neshanpro.com/api/v1.php', 'YOUR_KEY');
$res = $api->call('services.create', {"name":"reza-1404","plan_id":3,"order_id":"ORDER-1001"});
import requests
r = requests.post(
'https://api.neshanpro.com/api/v1.php',
headers={'X-API-Key': 'YOUR_KEY'},
json={"action":"services.create","name":"reza-1404","plan_id":3,"order_id":"ORDER-1001"},
timeout=30,
)
data = r.json()
if not data['success']:
print(data['code'], data['message'])
const r = await fetch('https://api.neshanpro.com/api/v1.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'YOUR_KEY' },
body: JSON.stringify({"action":"services.create","name":"reza-1404","plan_id":3,"order_id":"ORDER-1001"}),
});
const data = await r.json();
{
"service": {
"id": 812,
"name": "reza-1404",
"state": "active",
"volume_gb": 50,
"days_left": 30,
"subscription_url": "https://sub.example.com/sub?..."
},
"invoice": {
"price": 500000,
"discount_pct": 10,
"payable": 450000,
"balance": 2000000
}
}
502 gate_error است و مبلغ کسرشده خودکار برمیگردد.لیست سرویسها services.list #
سرویسهای خودتان، صفحهبندیشده.
| پارامتر | نوع | الزامی | توضیح |
|---|---|---|---|
page | عدد | ✖ | پیشفرض ۱ |
per | عدد | ✖ | ۱ تا ۱۰۰، پیشفرض ۲۵ |
q | متن | ✖ | جستوجو در نام |
status | متن | ✖ | active · disabled · expired |
curl -X POST https://api.neshanpro.com/api/v1.php \
-H 'Content-Type: application/json' \
-H 'X-API-Key: YOUR_KEY' \
-d '{"action":"services.list","page":1,"per":25}'
$api = new WebserviceClient('https://api.neshanpro.com/api/v1.php', 'YOUR_KEY');
$res = $api->call('services.list', {"page":1,"per":25});
import requests
r = requests.post(
'https://api.neshanpro.com/api/v1.php',
headers={'X-API-Key': 'YOUR_KEY'},
json={"action":"services.list","page":1,"per":25},
timeout=30,
)
data = r.json()
if not data['success']:
print(data['code'], data['message'])
const r = await fetch('https://api.neshanpro.com/api/v1.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'YOUR_KEY' },
body: JSON.stringify({"action":"services.list","page":1,"per":25}),
});
const data = await r.json();
{
"rows": [
{
"id": 812,
"name": "reza-1404",
"state": "active",
"volume_gb": 50,
"used_gb": 12.7,
"remaining_gb": 37.3,
"usage_pct": 25.4,
"days_left": 21,
"max_devices": 2,
"subscription_url": "https://sub.example.com/sub?..."
}
],
"total": 42,
"page": 1,
"pages": 2
}
وضعیت سرویس services.get #
با id یا name (یکی کافی است).
curl -X POST https://api.neshanpro.com/api/v1.php \
-H 'Content-Type: application/json' \
-H 'X-API-Key: YOUR_KEY' \
-d '{"action":"services.get","id":812}'
$api = new WebserviceClient('https://api.neshanpro.com/api/v1.php', 'YOUR_KEY');
$res = $api->call('services.get', {"id":812});
import requests
r = requests.post(
'https://api.neshanpro.com/api/v1.php',
headers={'X-API-Key': 'YOUR_KEY'},
json={"action":"services.get","id":812},
timeout=30,
)
data = r.json()
if not data['success']:
print(data['code'], data['message'])
const r = await fetch('https://api.neshanpro.com/api/v1.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'YOUR_KEY' },
body: JSON.stringify({"action":"services.get","id":812}),
});
const data = await r.json();
{
"service": {
"id": 812,
"name": "reza-1404",
"state": "active",
"volume_gb": 50,
"used_gb": 12.7,
"remaining_gb": 37.3,
"days_left": 21,
"subscription_url": "https://sub.example.com/sub?..."
}
}
state یکی از active، expired (زمان تمام)، drained (حجم تمام) یا disabled است.اطلاعات اتصال services.configs #
برای هر سرور: متن کانفیگ، لینک دانلود مستقیم، QR، و برای V2ray لینکهای تکی و لینک ساب.
curl -X POST https://api.neshanpro.com/api/v1.php \
-H 'Content-Type: application/json' \
-H 'X-API-Key: YOUR_KEY' \
-d '{"action":"services.configs","id":812}'
$api = new WebserviceClient('https://api.neshanpro.com/api/v1.php', 'YOUR_KEY');
$res = $api->call('services.configs', {"id":812});
import requests
r = requests.post(
'https://api.neshanpro.com/api/v1.php',
headers={'X-API-Key': 'YOUR_KEY'},
json={"action":"services.configs","id":812},
timeout=30,
)
data = r.json()
if not data['success']:
print(data['code'], data['message'])
const r = await fetch('https://api.neshanpro.com/api/v1.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'YOUR_KEY' },
body: JSON.stringify({"action":"services.configs","id":812}),
});
const data = await r.json();
{
"subscription_url": "https://sub.example.com/sub?...",
"configs": [
{
"title": "آلمان",
"location": "Germany",
"protocol": "wireguard",
"download_url": "https://sub.example.com/s_conf.php?...",
"qr_url": "https://sub.example.com/s_qr.php?..."
},
{
"title": "فنلاند",
"location": "Finland",
"protocol": "vless",
"links": [
"vless://..."
],
"sub_link": "https://..."
}
]
}
تمدید services.renew #
با پلن، یا (اگر فعال است) با روز و حجم دلخواه. اگر سرویس هنوز منقضی نشده، مدت تازه به انتهای مدت فعلی اضافه میشود.
curl -X POST https://api.neshanpro.com/api/v1.php \
-H 'Content-Type: application/json' \
-H 'X-API-Key: YOUR_KEY' \
-d '{"action":"services.renew","id":812,"plan_id":3,"order_id":"ORDER-1002"}'
$api = new WebserviceClient('https://api.neshanpro.com/api/v1.php', 'YOUR_KEY');
$res = $api->call('services.renew', {"id":812,"plan_id":3,"order_id":"ORDER-1002"});
import requests
r = requests.post(
'https://api.neshanpro.com/api/v1.php',
headers={'X-API-Key': 'YOUR_KEY'},
json={"action":"services.renew","id":812,"plan_id":3,"order_id":"ORDER-1002"},
timeout=30,
)
data = r.json()
if not data['success']:
print(data['code'], data['message'])
const r = await fetch('https://api.neshanpro.com/api/v1.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'YOUR_KEY' },
body: JSON.stringify({"action":"services.renew","id":812,"plan_id":3,"order_id":"ORDER-1002"}),
});
const data = await r.json();
{
"service": {
"id": 812,
"state": "active",
"days_left": 51
},
"invoice": {
"price": 500000,
"discount_pct": 10,
"payable": 450000,
"balance": 1550000
}
}
ارتقا services.update #
افزایش حجم، مدت یا دستگاه. فقط بابت افزایش پول کم میشود؛ کاهش برگشت پول ندارد.
curl -X POST https://api.neshanpro.com/api/v1.php \
-H 'Content-Type: application/json' \
-H 'X-API-Key: YOUR_KEY' \
-d '{"action":"services.update","id":812,"quota_gb":80}'
$api = new WebserviceClient('https://api.neshanpro.com/api/v1.php', 'YOUR_KEY');
$res = $api->call('services.update', {"id":812,"quota_gb":80});
import requests
r = requests.post(
'https://api.neshanpro.com/api/v1.php',
headers={'X-API-Key': 'YOUR_KEY'},
json={"action":"services.update","id":812,"quota_gb":80},
timeout=30,
)
data = r.json()
if not data['success']:
print(data['code'], data['message'])
const r = await fetch('https://api.neshanpro.com/api/v1.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'YOUR_KEY' },
body: JSON.stringify({"action":"services.update","id":812,"quota_gb":80}),
});
const data = await r.json();
{
"service": {
"id": 812,
"volume_gb": 80
},
"invoice": {
"payable": 54000,
"balance": 1496000
}
}
حذف، خاموش و روشن services.delete #
حذف برگشتناپذیر است. services.disable و services.enable سرویس را موقتاً قطع و وصل میکنند؛ سرویسی که بهخاطر حجم یا زمان بسته شده فقط با تمدید باز میشود.
curl -X POST https://api.neshanpro.com/api/v1.php \
-H 'Content-Type: application/json' \
-H 'X-API-Key: YOUR_KEY' \
-d '{"action":"services.delete","id":812}'
$api = new WebserviceClient('https://api.neshanpro.com/api/v1.php', 'YOUR_KEY');
$res = $api->call('services.delete', {"id":812});
import requests
r = requests.post(
'https://api.neshanpro.com/api/v1.php',
headers={'X-API-Key': 'YOUR_KEY'},
json={"action":"services.delete","id":812},
timeout=30,
)
data = r.json()
if not data['success']:
print(data['code'], data['message'])
const r = await fetch('https://api.neshanpro.com/api/v1.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'YOUR_KEY' },
body: JSON.stringify({"action":"services.delete","id":812}),
});
const data = await r.json();
{
"deleted": true,
"refunded": 0
}
تراکنشها reseller.transactions #
دفتر حساب: شارژ، خرید، تمدید، ارتقا و برگشت.
| پارامتر | نوع | الزامی | توضیح |
|---|---|---|---|
limit | عدد | ✖ | پیشفرض ۵۰، حداکثر ۲۰۰ |
curl -X POST https://api.neshanpro.com/api/v1.php \
-H 'Content-Type: application/json' \
-H 'X-API-Key: YOUR_KEY' \
-d '{"action":"reseller.transactions","limit":20}'
$api = new WebserviceClient('https://api.neshanpro.com/api/v1.php', 'YOUR_KEY');
$res = $api->call('reseller.transactions', {"limit":20});
import requests
r = requests.post(
'https://api.neshanpro.com/api/v1.php',
headers={'X-API-Key': 'YOUR_KEY'},
json={"action":"reseller.transactions","limit":20},
timeout=30,
)
data = r.json()
if not data['success']:
print(data['code'], data['message'])
const r = await fetch('https://api.neshanpro.com/api/v1.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'YOUR_KEY' },
body: JSON.stringify({"action":"reseller.transactions","limit":20}),
});
const data = await r.json();
{
"credit": 1496000,
"transactions": [
{
"amount": -54000,
"balance_after": 1496000,
"type": "upgrade",
"service_id": 812,
"created_at": 1790000000
}
]
}
جلوگیری از خرید تکراری #
اگر در services.create یا services.renew فیلد order_id بفرستید، آن سفارش یکتا میشود. اگر همان order_id دوباره بیاید، سفارش جدیدی ثبت نمیشود و پولی کم نمیشود؛ همان پاسخ قبلی با "is_duplicate": true برمیگردد.
قیمتگذاری #
| عملیات | مبلغ |
|---|---|
| خرید پلن | قیمت پلن برای حساب شما، منهای درصد تخفیف (payable) |
| سرویس دلخواه | حجم × قیمت هر گیگ + روز × قیمت هر روز + دستگاههای اضافه × قیمت هر دستگاه، منهای تخفیف — دستگاه اول رایگان |
| ارتقا | فقط بابت افزایش، با همان قیمتهای پایه |
| حذف | برگشتناپذیر؛ برگشت اعتبار فقط اگر برای حسابتان فعال باشد و سرویس اصلاً مصرف نشده باشد |
قیمتهای پایهی حساب خودتان در account.info زیر custom.prices است، و برای مبلغ دقیق از price.quote استفاده کنید.
محدودیت نرخ #
سقف درخواست در دقیقه برای کلید شما است (در account.info زیر limits.rate_limit_per_min). عبور از آن پاسخ 429 rate_limited و هدر Retry-After میدهد.
کلاینت آمادهی PHP #
این فایل را کنار پروژهتان بگذارید؛ خطاها را بهصورت استثنا با errorCode برمیگرداند.
<?php
require_once __DIR__ . '/webservice-client.php';
$api = new WebserviceClient('https://api.neshanpro.com/api/v1.php', 'YOUR_KEY');
try {
$acc = $api->account();
echo 'موجودی: ' . number_format($acc['balance']) . " تومان\n";
$order = $api->call('services.create', [
'name' => 'reza-1404',
'plan_id' => 3,
'order_id' => 'ORDER-1001',
]);
echo $order['service']['subscription_url'];
} catch (WebserviceException $e) {
if ($e->errorCode === 'insufficient_balance') {
echo 'حساب را شارژ کنید.';
} else {
echo $e->errorCode . ': ' . $e->getMessage();
}
}نکات عملیاتی #
| موضوع | توصیه |
|---|---|
| تایماوت | کمتر از ۳۰ ثانیه نگذارید؛ ساخت و تمدید منتظر سرورها میمانند. |
| تلاش مجدد | فقط با order_id امن است. |
| امنیت کلید | کلید را در کد ننویسید؛ در متغیر محیطی یا فایل تنظیمات بیرون از دسترس وب نگه دارید. اگر لو رفت، به مدیریت خبر دهید تا عوضش کنند. |