نسخه ۱.۰ — پایدار

مستندات اتصال عامل‌های فروش

با این API می‌توانید سرویس‌های فروش باز تعاونی‌های تاکسی بین‌شهری را در پلتفرم خود نمایش دهید، صندلی رزرو کنید و بلیط صادر کنید. ارتباط از طریق REST API برای عملیات اصلی و WebSocket برای دریافت به‌روزرسانی لحظه‌ای ظرفیت انجام می‌شود.

آدرس پایه REST

https://api.example-coop.ir/v1

آدرس WebSocket

wss://ws.example-coop.ir/v1

احراز هویت

تمام درخواست‌ها با توکن Bearer احراز هویت می‌شوند. ابتدا کلید و رمز عامل فروش خود را از پنل تعاونی دریافت کنید، سپس با اندپوینت /auth/token توکن دسترسی بگیرید و آن را در هدر همه درخواست‌ها قرار دهید.

نکته امنیتی

رمز عامل فروش (agent_secret) را هرگز در کد سمت کلاینت (مرورگر یا اپلیکیشن موبایل) قرار ندهید. دریافت توکن فقط باید از سرور شما انجام شود.

هدر احراز هویت
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json

جریان فروش بلیط

فروش هر بلیط در چهار مرحله انجام می‌شود. مرحله رزرو موقت تضمین می‌کند که در زمان پرداخت مسافر، صندلی توسط عامل دیگری فروخته نشود.

  1. ۱. دریافت توکن

    با کلید عامل فروش، توکن دسترسی ۲۴ ساعته بگیرید.

  2. ۲. جستجوی سرویس

    سرویس‌های باز را بر اساس مبدأ، مقصد و تاریخ پیدا کنید.

  3. ۳. رزرو موقت

    صندلی‌ها را ۱۰ دقیقه قفل کنید و وجه را از مسافر بگیرید.

  4. ۴. صدور بلیط

    رزرو را تأیید کنید تا بلیط صادر و پیامک شود.

دریافت توکن دسترسی

POST/auth/token

با ارسال کلید و رمز عامل فروش، یک توکن دسترسی (JWT) دریافت می‌کنید. این توکن باید در هدر Authorization تمام درخواست‌های بعدی ارسال شود. اعتبار توکن ۲۴ ساعت است و پیش از انقضا باید تمدید شود.

هدرها

نامنوعتوضیحات
Content-Typestringهمیشه application/json

بدنه درخواست

نامنوعتوضیحات
agent_keystringکلید اختصاصی عامل فروش (از پنل تعاونی دریافت می‌شود)
agent_secretstringرمز اختصاصی عامل فروش

فیلدهای مهم پاسخ

نامنوعتوضیحات
access_tokenstringتوکن JWT برای احراز هویت درخواست‌ها
expires_innumberمدت اعتبار توکن به ثانیه (۸۶۴۰۰ = ۲۴ ساعت)
POSThttps://api.example-coop.ir/v1/auth/token
curl -X POST https://api.example-coop.ir/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "agent_key": "AGT-724-XXXX",
    "agent_secret": "your-secret-key"
  }'
نمونه پاسخ 200
{
  "success": true,
  "data": {
    "access_token": "eyJhbGciOiJIUzI1NiIs...",
    "token_type": "Bearer",
    "expires_in": 86400
  }
}

فهرست شهرها

GET/cities

فهرست تمام شهرهای فعال در شبکه تعاونی را برمی‌گرداند. از شناسه شهرها (city_id) برای جستجوی سرویس‌ها استفاده کنید. این فهرست به‌ندرت تغییر می‌کند؛ توصیه می‌شود آن را کش کنید.

هدرها

نامنوعتوضیحات
Authorizationstringتوکن دسترسی به‌صورت Bearer {access_token}
Content-Typestringهمیشه application/json

پارامترهای کوئری

نامنوعتوضیحات
searchstringجستجوی نام شهر (حداقل ۲ کاراکتر)
province_idintegerفیلتر بر اساس شناسه استان
GEThttps://api.example-coop.ir/v1/cities
curl "https://api.example-coop.ir/v1/cities?search=تهران" \
  -H "Authorization: Bearer {access_token}"
نمونه پاسخ 200
{
  "success": true,
  "data": [
    {
      "city_id": 101,
      "name": "تهران",
      "province": "تهران",
      "terminals": [
        { "terminal_id": 5, "name": "پایانه بیهقی" },
        { "terminal_id": 8, "name": "پایانه جنوب" }
      ]
    }
  ]
}

جستجوی سرویس‌ها

GET/services

سرویس‌های فروش باز تعاونی را بر اساس مبدأ، مقصد و تاریخ حرکت جستجو می‌کند. نتایج شامل ظرفیت لحظه‌ای، قیمت و مشخصات خودرو است. برای دریافت به‌روزرسانی لحظه‌ای ظرفیت، به بخش WebSocket مراجعه کنید.

هدرها

نامنوعتوضیحات
Authorizationstringتوکن دسترسی به‌صورت Bearer {access_token}
Content-Typestringهمیشه application/json

پارامترهای کوئری

نامنوعتوضیحات
origin_city_idintegerشناسه شهر مبدأ
destination_city_idintegerشناسه شهر مقصد
datestringتاریخ حرکت به فرمت YYYY-MM-DD (میلادی)
vehicle_typestringنوع خودرو: sedan | van | bus
pageintegerشماره صفحه (پیش‌فرض: 1)
limitintegerتعداد نتایج در هر صفحه (پیش‌فرض: 20، حداکثر: 100)

فیلدهای مهم پاسخ

نامنوعتوضیحات
service_idstringشناسه یکتای سرویس — در رزرو استفاده می‌شود
priceintegerقیمت هر صندلی به ریال
capacity.availableintegerتعداد صندلی خالی در لحظه پاسخ
statusstringوضعیت سرویس: open | full | departed | cancelled
GEThttps://api.example-coop.ir/v1/services
curl "https://api.example-coop.ir/v1/services?origin_city_id=101&destination_city_id=205&date=2026-07-20" \
  -H "Authorization: Bearer {access_token}"
نمونه پاسخ 200
{
  "success": true,
  "data": {
    "services": [
      {
        "service_id": "SRV-84213",
        "origin": { "city_id": 101, "name": "تهران", "terminal": "پایانه بیهقی" },
        "destination": { "city_id": 205, "name": "اصفهان", "terminal": "پایانه کاوه" },
        "departure_at": "2026-07-20T08:30:00+03:30",
        "vehicle": { "type": "sedan", "model": "پژو پارس", "plate": "۱۲ب۳۴۵-۱۰" },
        "price": 2500000,
        "currency": "IRR",
        "capacity": { "total": 4, "available": 3 },
        "cooperative": { "id": 12, "name": "تعاونی شماره ۴" },
        "status": "open"
      }
    ],
    "pagination": { "page": 1, "limit": 20, "total": 8 }
  }
}

جزئیات سرویس

GET/services/{service_id}

اطلاعات کامل یک سرویس شامل مشخصات راننده، خودرو، قوانین استرداد و نقشه صندلی‌ها را برمی‌گرداند.

هدرها

نامنوعتوضیحات
Authorizationstringتوکن دسترسی به‌صورت Bearer {access_token}
Content-Typestringهمیشه application/json

پارامترهای مسیر

نامنوعتوضیحات
service_idstringشناسه سرویس (از خروجی جستجو)

فیلدهای مهم پاسخ

نامنوعتوضیحات
seats[].statusstringوضعیت صندلی: available | locked | sold
refund_policyobjectدرصد بازگشت وجه بر اساس زمان لغو
GEThttps://api.example-coop.ir/v1/services/{service_id}
curl "https://api.example-coop.ir/v1/services/SRV-84213" \
  -H "Authorization: Bearer {access_token}"
نمونه پاسخ 200
{
  "success": true,
  "data": {
    "service_id": "SRV-84213",
    "departure_at": "2026-07-20T08:30:00+03:30",
    "driver": { "name": "ع. محمدی", "rating": 4.8 },
    "vehicle": { "type": "sedan", "model": "پژو پارس", "year": 1402 },
    "price": 2500000,
    "refund_policy": {
      "before_24h_percent": 90,
      "before_2h_percent": 50,
      "after_2h_percent": 0
    },
    "seats": [
      { "seat_number": 1, "status": "sold" },
      { "seat_number": 2, "status": "available" },
      { "seat_number": 3, "status": "available" },
      { "seat_number": 4, "status": "locked" }
    ]
  }
}

رزرو موقت صندلی

POST/reservations

صندلی‌های انتخابی را به مدت ۱۰ دقیقه برای مسافر قفل می‌کند. در این بازه باید رزرو را با اندپوینت تأیید، نهایی کنید؛ در غیر این صورت رزرو منقضی و صندلی‌ها آزاد می‌شوند. رویداد seat.locked از طریق WebSocket به سایر عامل‌ها اطلاع‌رسانی می‌شود.

هدرها

نامنوعتوضیحات
Authorizationstringتوکن دسترسی به‌صورت Bearer {access_token}
Content-Typestringهمیشه application/json

بدنه درخواست

نامنوعتوضیحات
service_idstringشناسه سرویس
seat_numbersinteger[]آرایه شماره صندلی‌های درخواستی
passengersobject[]اطلاعات مسافران — هم‌طول با seat_numbers
passengers[].full_namestringنام کامل مسافر
passengers[].national_idstringکد ملی ۱۰ رقمی
passengers[].phonestringشماره موبایل با فرمت 09xxxxxxxxx
passengers[].genderstringmale | female

فیلدهای مهم پاسخ

نامنوعتوضیحات
reservation_idstringشناسه رزرو — برای تأیید نهایی لازم است
expires_atstringزمان انقضای قفل صندلی (۱۰ دقیقه بعد)
total_amountintegerمبلغ کل قابل پرداخت به ریال
POSThttps://api.example-coop.ir/v1/reservations
curl -X POST https://api.example-coop.ir/v1/reservations \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "service_id": "SRV-84213",
    "seat_numbers": [2, 3],
    "passengers": [
      { "full_name": "علی رضایی", "national_id": "0012345678", "phone": "09121234567" },
      { "full_name": "مریم رضایی", "national_id": "0087654321", "phone": "09121234567" }
    ]
  }'
نمونه پاسخ 200
{
  "success": true,
  "data": {
    "reservation_id": "RSV-55102",
    "status": "pending",
    "expires_at": "2026-07-15T10:42:00+03:30",
    "total_amount": 5000000,
    "currency": "IRR"
  }
}

تأیید رزرو و صدور بلیط

POST/reservations/{reservation_id}/confirm

پس از دریافت وجه از مسافر در سمت عامل فروش، این اندپوینت را فراخوانی کنید تا بلیط صادر شود. شماره پیگیری پرداخت خودتان را برای تطبیق مالی ارسال کنید. پس از صدور، بلیط از طریق پیامک نیز برای مسافر ارسال می‌شود.

هدرها

نامنوعتوضیحات
Authorizationstringتوکن دسترسی به‌صورت Bearer {access_token}
Content-Typestringهمیشه application/json

پارامترهای مسیر

نامنوعتوضیحات
reservation_idstringشناسه رزرو موقت

بدنه درخواست

نامنوعتوضیحات
payment_referencestringشماره پیگیری پرداخت در سیستم عامل فروش
send_smsbooleanارسال پیامک بلیط به مسافر (پیش‌فرض: true)
POSThttps://api.example-coop.ir/v1/reservations/{reservation_id}/confirm
curl -X POST https://api.example-coop.ir/v1/reservations/RSV-55102/confirm \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{ "payment_reference": "PAY-998877" }'
نمونه پاسخ 200
{
  "success": true,
  "data": {
    "tickets": [
      {
        "ticket_number": "TKT-2026-771001",
        "passenger": "علی رضایی",
        "seat_number": 2,
        "qr_code_url": "https://api.example-coop.ir/v1/tickets/TKT-2026-771001/qr"
      },
      {
        "ticket_number": "TKT-2026-771002",
        "passenger": "مریم رضایی",
        "seat_number": 3,
        "qr_code_url": "https://api.example-coop.ir/v1/tickets/TKT-2026-771002/qr"
      }
    ],
    "issued_at": "2026-07-15T10:38:12+03:30"
  }
}

استعلام بلیط

GET/tickets/{ticket_number}

وضعیت و جزئیات یک بلیط صادرشده را برمی‌گرداند. برای نمایش بلیط به مسافر یا بررسی وضعیت پیش از استرداد استفاده می‌شود.

هدرها

نامنوعتوضیحات
Authorizationstringتوکن دسترسی به‌صورت Bearer {access_token}
Content-Typestringهمیشه application/json

پارامترهای مسیر

نامنوعتوضیحات
ticket_numberstringشماره بلیط

فیلدهای مهم پاسخ

نامنوعتوضیحات
statusstringوضعیت بلیط: issued | used | refunded | cancelled
GEThttps://api.example-coop.ir/v1/tickets/{ticket_number}
curl "https://api.example-coop.ir/v1/tickets/TKT-2026-771001" \
  -H "Authorization: Bearer {access_token}"
نمونه پاسخ 200
{
  "success": true,
  "data": {
    "ticket_number": "TKT-2026-771001",
    "status": "issued",
    "service_id": "SRV-84213",
    "passenger": { "full_name": "علی رضایی", "national_id": "001*****78" },
    "seat_number": 2,
    "price": 2500000,
    "departure_at": "2026-07-20T08:30:00+03:30"
  }
}

استرداد بلیط

POST/tickets/{ticket_number}/refund

درخواست استرداد بلیط را ثبت می‌کند. مبلغ قابل بازگشت بر اساس قوانین استرداد سرویس (refund_policy) و فاصله تا زمان حرکت محاسبه می‌شود. تسویه مالی با عامل فروش به‌صورت دوره‌ای انجام می‌شود.

هدرها

نامنوعتوضیحات
Authorizationstringتوکن دسترسی به‌صورت Bearer {access_token}
Content-Typestringهمیشه application/json

پارامترهای مسیر

نامنوعتوضیحات
ticket_numberstringشماره بلیط

بدنه درخواست

نامنوعتوضیحات
reasonstringدلیل استرداد (برای گزارش‌گیری تعاونی)

فیلدهای مهم پاسخ

نامنوعتوضیحات
refund_amountintegerمبلغ بازگشتی به ریال پس از کسر جریمه
refund_percentintegerدرصد بازگشت اعمال‌شده طبق قوانین سرویس
POSThttps://api.example-coop.ir/v1/tickets/{ticket_number}/refund
curl -X POST https://api.example-coop.ir/v1/tickets/TKT-2026-771001/refund \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "انصراف مسافر" }'
نمونه پاسخ 200
{
  "success": true,
  "data": {
    "ticket_number": "TKT-2026-771001",
    "status": "refunded",
    "refund_amount": 2250000,
    "refund_percent": 90,
    "refunded_at": "2026-07-15T11:02:45+03:30"
  }
}

اتصال لحظه‌ای با WebSocket

برای نمایش ظرفیت لحظه‌ای صندلی‌ها بدون نیاز به فراخوانی مکرر REST، به سرور WebSocket متصل شوید و در سرویس‌های موردنظر مشترک شوید. توکن دسترسی را به‌صورت پارامتر کوئری ارسال کنید. سرور هر ۳۰ ثانیه یک پیام ping می‌فرستد که باید با pong پاسخ دهید؛ در غیر این صورت اتصال قطع می‌شود.

رویدادها

  • subscribeاز کلاینت

    اشتراک در به‌روزرسانی‌های یک یا چند سرویس

  • seat.lockedاز سرور

    یک صندلی توسط عامل دیگری به‌صورت موقت قفل شد

  • seat.releasedاز سرور

    قفل صندلی منقضی یا رزرو لغو شد و صندلی آزاد است

  • ticket.issuedاز سرور

    بلیط یک صندلی صادر شد و صندلی به فروش رفت

  • service.updatedاز سرور

    تغییر در وضعیت سرویس (لغو، تغییر ساعت، تکمیل ظرفیت)

اتصال و اشتراک
const ws = new WebSocket(
  "wss://ws.example-coop.ir/v1?token={access_token}"
);

ws.onopen = () => {
  ws.send(JSON.stringify({
    action: "subscribe",
    service_ids: ["SRV-84213"],
  }));
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  if (message.event === "ping") {
    ws.send(JSON.stringify({ action: "pong" }));
    return;
  }
  // seat.locked | seat.released | ticket.issued | service.updated
  handleRealtimeUpdate(message);
};
نمونه رویداد دریافتی
{
  "event": "ticket.issued",
  "service_id": "SRV-84213",
  "seat_number": 2,
  "capacity_available": 1
}

کدهای خطا

همه خطاها با ساختار یکسان برگردانده می‌شوند. فیلد error.code برای مدیریت برنامه‌ای خطا و error.message پیام قابل نمایش به فارسی است.

کدنامتوضیحات
400BAD_REQUESTپارامترهای ارسالی نامعتبر یا ناقص است
401UNAUTHORIZEDتوکن ارسال نشده یا منقضی شده است
403FORBIDDENعامل فروش به این منبع دسترسی ندارد
404NOT_FOUNDسرویس، رزرو یا بلیط موردنظر یافت نشد
409SEAT_UNAVAILABLEصندلی درخواستی قفل یا فروخته شده است
410RESERVATION_EXPIREDمهلت ۱۰ دقیقه‌ای رزرو موقت به پایان رسیده است
422REFUND_NOT_ALLOWEDطبق قوانین سرویس، استرداد در این بازه مجاز نیست
429RATE_LIMITEDتعداد درخواست‌ها از سقف مجاز عبور کرده است
500INTERNAL_ERRORخطای داخلی سرور — با پشتیبانی تعاونی تماس بگیرید
ساختار پاسخ خطا
{
  "success": false,
  "error": {
    "code": 409,
    "name": "SEAT_UNAVAILABLE",
    "message": "صندلی شماره ۴ هم‌اکنون توسط عامل دیگری رزرو شده است",
    "details": {
      "service_id": "SRV-84213",
      "seat_number": 4
    }
  }
}

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

هر عامل فروش به‌صورت پیش‌فرض مجاز به ارسال ۱۲۰ درخواست در دقیقه است. وضعیت لحظه‌ای سهمیه شما در هدرهای پاسخ برگردانده می‌شود. در صورت عبور از سقف، خطای 429 دریافت می‌کنید و باید تا زمان مشخص‌شده در هدر Retry-After صبر کنید.

برای کاهش تعداد درخواست، از WebSocket برای به‌روزرسانی ظرفیت و از کش برای فهرست شهرها استفاده کنید. در صورت نیاز به سقف بالاتر با پشتیبانی تعاونی تماس بگیرید.

هدرهای سهمیه
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1752562980
Retry-After: 24