کیوب پس پنل همکاری کیوب پس ورود

مستندات API همکاری

این API امکان مشاهده‌ی محصولات با قیمت همکاری، ثبت سفارش از محل کیف پول و دریافت خودکار سفارش را فراهم می‌کند.

معرفی

نشانی پایهhttps://api.cubepass.ir/v1
قالب دادهapplication/json; UTF-8
واحد مبلغتومان
زمانISO 8601, UTC

پیش از شروع، در تنظیمات API نشانی IP سرور، توکن و نشانی وب‌هوک را ثبت کنید. سپس اتصال را از همان سرور بررسی کنید.

بررسی اتصال
curl https://api.cubepass.ir/v1/ping \
  -H "Authorization: Bearer YOUR_TOKEN"
پاسخJSON
{
  "success": true,
  "data": {
    "partner_id": 12,
    "your_ip": "203.0.113.10",
    "discount_percent": 10.0,
    "webhook_set": true
  }
}

احراز هویت

هر درخواست باید هر دو شرط زیر را داشته باشد.

توکندر هدر Authorization: Bearer YOUR_TOKEN ارسال شود. توکن تنها در زمان ساخت نمایش داده می‌شود و باید در سرور نگهداری شود.
IP مجازدرخواست باید از IP ثبت‌شده در پنل ارسال شود. برای هر حساب یک IP ثبت می‌شود و بازه‌ی IP پذیرفته نمی‌شود.

این API تنها برای ارتباط سرور با سرور طراحی شده است و از مرورگر قابل فراخوانی نیست.

محدودیت درخواست

گروهحداکثر در دقیقه
خواندن (محصولات، کیف پول، جزئیات سفارش)۱۲۰
سفارش (ثبت، فهرست، لغو)۳۰
رزرو موجودی۲۰

وضعیت مصرف در هدرهای X-RateLimit-Limit، X-RateLimit-Remaining و X-RateLimit-Reset بازگردانده می‌شود. در پاسخ 429، مدت انتظار در هدر Retry-After قرار دارد.

خطاها

در پاسخ ناموفق، مقدار code ثابت است و برای پردازش در برنامه مناسب است. مقدار message تنها برای نمایش است.

نمونه‌ی خطاJSON
{
  "success": false,
  "error": {
    "code": "insufficient_balance",
    "message": "موجودی کیف پول برای این سفارش کافی نیست.",
    "required": 450000,
    "balance": 120000
  }
}
HTTPcodeشرح
400bad_jsonبدنه‌ی درخواست JSON معتبر نیست.
401unauthorizedتوکن ارسال نشده یا معتبر نیست.
402insufficient_balanceموجودی کافی نیست؛ مبلغی کسر نشده است.
403ip_required، ip_not_allowedIP ثبت نشده یا مجاز نیست.
403webhook_requiredنشانی وب‌هوک ثبت نشده است.
403partner_inactiveحساب همکاری فعال نیست.
404product_not_found، order_not_found، hold_not_foundمنبع یافت نشد.
409product_unavailableمحصول قابل خرید نیست.
409price_changedقیمت با expected_total مطابقت ندارد.
409cannot_cancelسفارش قابل لغو نیست.
410hold_expiredمهلت رزرو به پایان رسیده است.
422bad_item، no_items، variant_required، inputs_required، client_order_id_requiredمقادیر درخواست معتبر نیست.
429rate_limited، hold_limitاز سقف مجاز عبور کرده‌اید.
503unavailableسرویس موقتاً در دسترس نیست.

کیف پول

GET/walletموجودی
درخواست
curl https://api.cubepass.ir/v1/wallet \
  -H "Authorization: Bearer YOUR_TOKEN"
پاسخJSON
{
  "success": true,
  "data": { "balance": 1250000, "currency": "IRT" }
}
GET/transactions?page=1&limit=50&kind=orderگزارش تراکنش‌ها

مقادیر kind: topup، order، refund، admin_add، admin_sub

پاسخJSON
{
  "success": true,
  "data": {
    "page": 1,
    "transactions": [
      {
        "id": 81,
        "amount": -450000,
        "balance_after": 800000,
        "kind": "order",
        "reason": "خرید Game Pass Ultimate 1 ماهه × 1 — سفارش CP-9F21A07C3D (ORD-1042)",
        "order_id": "CP-9F21A07C3D",
        "created_at": "2026-11-01T10:12:05+00:00"
      }
    ]
  }
}

محصولات

GET/products?page=1&limit=100فهرست محصولات
GET/products/{id}جزئیات محصول
درخواست
curl https://api.cubepass.ir/v1/products?page=1&limit=100 \
  -H "Authorization: Bearer YOUR_TOKEN"

محصولی که قابل خرید نیست تنها با available: false و علت آن در فهرست قرار می‌گیرد.

پاسخJSON
{
  "success": true,
  "data": {
    "page": 1,
    "total": 2,
    "products": [
      {
        "id": 17,
        "name": "Game Pass Ultimate",
        "available": true,
        "category": "gamepass",
        "brand": "Xbox",
        "variants": [
          {
            "id": 41,
            "name": "1 ماهه",
            "available": true,
            "price": 450000,
            "site_price": 500000,
            "delivery": "account",
            "in_stock": true,
            "required_fields": []
          }
        ]
      },
      {
        "id": 23,
        "name": "PS Plus",
        "available": false,
        "unavailable_reason": "out_of_stock"
      }
    ]
  }
}
فیلدشرح
availableقابل خرید بودن
unavailable_reasonhidden یا out_of_stock
priceقیمت شما پس از اعمال درصد همکاری
site_priceقیمت فروش در سایت
in_stocktrue: تحویل فوری. false: قابل خرید است و پس از تکمیل از طریق وب‌هوک تحویل می‌شود.
deliveryaccount، link، code یا customer
required_fieldsفیلدهای لازم در inputs برای تحویل customer

محصول بدون ظرفیت یک variant با id: 0 دارد.

رزرو موجودی

با این درخواست، تعداد موردنیاز به مدت 5 دقیقه برای شما رزرو می‌شود تا در این مدت خرید را نهایی کنید. پاسخ تنها مشخص می‌کند که تعداد درخواستی قابل رزرو است یا خیر. پس از پایان مهلت، رزرو خودکار آزاد می‌شود.

POST/holdsثبت رزرو
درخواست
curl -X POST https://api.cubepass.ir/v1/holds \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "product_id": 17,
        "variant_id": 41,
        "quantity": 14
      }
    ]
  }'
رزرو شد (201)JSON
{
  "success": true,
  "data": {
    "available": true,
    "hold_id": "hold_8c1f0e2ab45d6f7e90a1b2c3",
    "expires_in": 300,
    "expires_at": "2026-11-01T10:17:05+00:00",
    "total": 6300000,
    "wallet_sufficient": true
  }
}
قابل رزرو نیست (200)JSON
{
  "success": true,
  "data": { "available": false }
}
  • قیمت در مدت رزرو ثابت می‌ماند.
  • حداکثر 50 واحد به‌صورت هم‌زمان قابل رزرو است.
  • محصولات با تحویل customer قابل رزرو نیستند.
DELETE/holds/{hold_id}آزادسازی رزرو

سفارش

POST/ordersثبت سفارش
فیلدنوعشرح
client_order_idstringالزامیشناسه‌ی یکتای سفارش در سیستم شما. ارسال دوباره‌ی همین شناسه، همان سفارش را بازمی‌گرداند و خرید تکراری انجام نمی‌شود.
itemsarrayالزامی*حداکثر 20 قلم و هر قلم تا 50 عدد، شامل product_id، variant_id و quantity
hold_idstringاختیاری*به‌جای items، برای خرید یک رزرو
expected_totalintegerاختیاریاگر مبلغ نهایی با این مقدار برابر نباشد، سفارش ثبت نمی‌شود.
dry_runbooleanاختیاریبا true درخواست بررسی می‌شود بدون اینکه خریدی انجام شود یا مبلغی کسر گردد.
درخواست
curl -X POST https://api.cubepass.ir/v1/orders \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "client_order_id": "ORD-1042",
    "items": [
      {
        "product_id": 17,
        "variant_id": 41,
        "quantity": 1
      }
    ],
    "expected_total": 450000
  }'

مبلغ کل سفارش هنگام ثبت از کیف پول کسر می‌شود. سفارش یکی از دو حالت زیر را دارد:

completedهمه‌ی اقلام آماده است و در همین پاسخ تحویل می‌شود.
pendingسفارش در حال تکمیل است. پس از تکمیل، همه‌ی اقلام با هم از طریق وب‌هوک order.completed تحویل می‌شوند.
پاسخ سفارش تحویل‌شده (201)JSON
{
  "success": true,
  "data": {
    "order_id": "CP-9F21A07C3D",
    "client_order_id": "ORD-1042",
    "status": "completed",
    "status_label": "تحویل شده",
    "total": 450000,
    "created_at": "2026-11-01T10:12:05+00:00",
    "items": [
      {
        "product_id": 17,
        "variant_id": 41,
        "name": "Game Pass Ultimate",
        "variant": "1 ماهه",
        "quantity": 1,
        "unit_price": 450000,
        "delivery": "account",
        "accounts": [
          { "kind": "account", "login": "user@example.com", "password": "S3cret" }
        ]
      }
    ]
  }
}
ساختار اقلام تحویلی بر اساس kindJSON
{ "kind": "account",  "login": "...", "password": "..." }
{ "kind": "link",     "link": "https://..." }
{ "kind": "code",     "code": "XXXX-XXXX" }
{ "kind": "customer", "note": "..." }

برای محصول با تحویل customer، مشخصات اکانت مشتری را به تعداد quantity ارسال کنید.

قلم با تحویل customerJSON
{
  "product_id": 30,
  "variant_id": 0,
  "quantity": 1,
  "inputs": [{ "email": "customer@example.com", "password": "..." }]
}
GET/orders?page=1&limit=30فهرست سفارش‌ها
GET/orders/{order_id}جزئیات سفارش

این مسیر با order_id یا client_order_id کار می‌کند و وضعیت سفارش یکی از pending، completed یا cancelled است.

POST/orders/{order_id}/cancelلغو سفارش
درخواست
curl -X POST https://api.cubepass.ir/v1/orders/CP-9F21A07C3D/cancel \
  -H "Authorization: Bearer YOUR_TOKEN"

تنها سفارش pending قابل لغو است و مبلغ آن به کیف پول بازمی‌گردد.

وب‌هوک

وب‌هوک برای دریافت سفارش‌هایی که پس از ثبت تکمیل می‌شوند و اطلاع از تغییر محصولات الزامی است. نشانی باید https روی پورت ۴۴۳ و دارای IP عمومی باشد.

رویدادشرح
order.pendingسفارش ثبت شد و در حال تکمیل است.
order.completedسفارش تکمیل شد؛ اقلام تحویلی در accounts قرار دارد.
order.cancelledسفارش لغو و مبلغ به کیف پول بازگردانده شد.
product.unavailableمحصول یا ظرفیت از فروش خارج شد؛ علت در reason با مقدار out_of_stock یا hidden قرار دارد.
product.availableمحصول یا ظرفیت قابل خرید شد.
product.price_changedقیمت تغییر کرد.
pingپیام آزمایشی از پنل
بدنه‌ی پیامJSON
{
  "id": "evt_5b1c9e2f7a",
  "event": "order.completed",
  "created_at": 1793500000,
  "data": {
    "order_id": "CP-9F21A07C3D",
    "client_order_id": "ORD-1042",
    "status": "completed",
    "items": []
  }
}

تغییر محصولات

تغییرات محصولات حداکثر یک تا دو دقیقه پس از رخ دادن ارسال می‌شود. اقلام هر رویداد در آرایه‌ی items قرار دارد و هر ردیف مربوط به یک ظرفیت است. قیمت‌ها به تومان و price قیمت شما پس از اعمال درصد همکاری است.

product.price_changedJSON
{
  "id": "evt_8a3d1f6c02",
  "event": "product.price_changed",
  "created_at": 1793500000,
  "data": {
    "items": [
      {
        "product_id": 17,
        "variant_id": 41,
        "name": "Game Pass Ultimate",
        "variant": "1 ماهه",
        "old_price": 450000,
        "price": 495000,
        "old_site_price": 500000,
        "site_price": 550000
      }
    ]
  }
}
product.unavailableJSON
{
  "id": "evt_c41e7b9a35",
  "event": "product.unavailable",
  "created_at": 1793500000,
  "data": {
    "items": [
      {
        "product_id": 17,
        "variant_id": 41,
        "name": "Game Pass Ultimate",
        "variant": "1 ماهه",
        "reason": "out_of_stock"
      }
    ]
  }
}

پیام product.available همین ساختار را با فیلدهای price و site_price دارد. محصولی که in_stock: false شود همچنان قابل خرید است و پیامی برای آن ارسال نمی‌شود. تغییر درصد همکاری نیز پیام جداگانه ندارد و قیمت جدید از مسیر محصولات دریافت می‌شود.

بررسی امضا

هر پیام هدرهای X-Cube-Event، X-Cube-Timestamp و X-Cube-Signature را دارد. امضا برابر با HMAC-SHA256 رشته‌ی timestamp.body با کلید امضای پنل است و باید پیش از پردازش پیام بررسی شود.

بررسی امضا
$body = file_get_contents('php://input');
$ts   = $_SERVER['HTTP_X_CUBE_TIMESTAMP'] ?? '';
$sig  = $_SERVER['HTTP_X_CUBE_SIGNATURE'] ?? '';
$good = hash_hmac('sha256', $ts . '.' . $body, getenv('CUBE_WEBHOOK_SECRET'));

if (!hash_equals($good, $sig) || abs(time() - (int) $ts) > 300) {
    http_response_code(401);
    exit;
}

$event = json_decode($body, true);
http_response_code(200);

پاسخ و تلاش مجدد

سرور شما باید ظرف ۱۰ ثانیه با کد 2xx پاسخ دهد. در غیر این صورت، پیام تا ۲۴ ساعت حداکثر ۸ بار دوباره ارسال می‌شود. به همین دلیل ممکن است یک پیام بیش از یک بار برسد؛ با ذخیره‌ی مقدار id از پردازش تکراری جلوگیری کنید. سفارش تحویل‌شده همیشه از مسیر جزئیات سفارش و صفحه‌ی سفارش در پنل نیز قابل دریافت است.

نمونه‌ی کامل

رزرو ۱۴ عدد و سپس خرید همان رزرو:

رزرو و خرید
import uuid
import requests

API = "https://api.cubepass.ir/v1"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}

hold = requests.post(f"{API}/holds", headers=HEADERS, timeout=20, json={
    "items": [{"product_id": 17, "variant_id": 41, "quantity": 14}],
}).json()["data"]

if not hold["available"]:
    print("Not available")
elif not hold["wallet_sufficient"]:
    requests.delete(f"{API}/holds/{hold['hold_id']}", headers=HEADERS, timeout=20)
    print("Insufficient balance")
else:
    order = requests.post(f"{API}/orders", headers=HEADERS, timeout=30, json={
        "client_order_id": str(uuid.uuid4()),
        "hold_id": hold["hold_id"],
    }).json()["data"]
    print(order["status"], order["items"])