رفتن به محتوای اصلی
REST · JSON API v1 X-API-Key

محصولات واریا را از طریق سیستم خودت بفروش

سایت، ربات تلگرام یا پنل همکاری‌ات را به واریا وصل کن. محصولات و قیمت‌ها را به مشتری خودت نشان بده، سفارش او را ثبت کن و نتیجهٔ نهایی را خودکار تحویل بگیر — با یک API از نوع REST که فقط با هدر X-API-Key احراز هویت می‌شود.

Base URL https://api.waryashop.org/api/v1
01

API واریا چه کاری انجام می‌دهد؟

این یک API همکاری (عمده) است. مشتری داخل سایت یا ربات خودت می‌ماند؛ سرور تو در پس‌زمینه با یک کلید با واریا حرف می‌زند و کاتالوگ، قیمت‌ها، سفارش و تحویل را مدیریت می‌کند. کیف پول دلاری حسابت را شارژ می‌کنی؛ هزینهٔ هر سفارش پذیرفته‌شده از آن کسر می‌شود و نتیجه یا با خواندن وضعیت سفارش برمی‌گردد یا — اگر آدرس بازگشت بدهی — با یک وب‌هوک امضاشده.

✓

کاتالوگ

بازی‌ها، محصولات، پکیج‌ها و قیمت فروش لحظه‌ای دلاری.

✓

اعتبارسنجی بازیکن

بررسی حساب بازی پیش از دریافت وجه از مشتری.

✓

سفارش و کیف پول

ثبت سفارش، خواندن وضعیت آن و دیدن موجودی و تراکنش‌ها.

✓

وب‌هوک امضاشده

هر رویداد سفارش به آدرس خودت فرستاده می‌شود و با امضای HMAC قابل بررسی است.

02

احراز هویت

هر درخواست کلیدت را در هدر X-API-Key می‌فرستد. کلید یک رمز است: آن را فقط در هدر بفرست، هرگز در آدرس، در query string یا در لاگ — کلیدی که در آدرس باشد به تاریخ مرورگر، لاگ پروکسی و اسکرین‌شات راه پیدا می‌کند. این API به هیچ هدر forward شده اعتماد نمی‌کند، پس فهرست IP اختیاری هر کلید قابل جعل نیست.

هدر

درخواست بدون کلید، با کلید ناشناخته یا کلید غیرفعال/باطل پاسخ 401 می‌گیرد و هیچ چیز دیگری دربارهٔ حساب فاش نمی‌شود.

curl "https://api.waryashop.org/api/v1/games" \
  -H "X-API-Key: YOUR_API_KEY"

1 کلید برای هر حساب

پس از ورود، آن را از صفحهٔ کلیدهای API بساز. هر کلید اسکوپ دارد و می‌تواند آدرس‌هایی را که از آن‌ها پاسخ می‌دهد محدود کند (تا 32 قانون). هر زمان می‌توانی آن را بازتولید، غیرفعال یا باطل کنی؛ هر پاسخ X-Request-Id را هم دارد.

03

اندپوینت‌ها

هر مسیر نسبت به Base URL بالا است. هر عملیات به اسکوپ نوشته‌شده در کنارش نیاز دارد.

کاتالوگ

GET https://api.waryashop.org/api/v1/games catalog:read

لیست بازی‌ها و محصولات

کد محصول، نام انگلیسی، نام فارسی اختیاری و آدرس تصویر میزبانی‌شده روی واریا. صفحه‌بندی‌شده؛ صفحهٔ پیش‌فرض کل لیست است.

GET https://api.waryashop.org/api/v1/games/{code}/catalogue catalog:read

پکیج‌ها و قیمت فروش

هنگام ثبت سفارش دقیقاً همان catalogue_name این پاسخ را ارسال کن. این‌ها قیمت فروش واریا به دلار و به‌صورت رشتهٔ اعشاری است. فقط پکیج‌هایی فهرست می‌شوند که همین حالا قیمت‌شان قابل تأیید است؛ محصولی که دیگر قابل فروش نیست یا مبلغش تأیید نمی‌شود اینجا غایب است — نه اینکه با ۰٫۰۰۰۰۰۰ منتشر شود — و نام‌بردن آن در سفارش پاسخ ۴۲۲ می‌گیرد.

GET https://api.waryashop.org/api/v1/games/{code}/fields catalog:read

فیلدهای لازم بازیکن

شناسه‌هایی که فرم سفارش این بازی باید بگیرد، همراه با meta.source و meta.freshness که می‌گوید پاسخ از کجا آمده است. ووچرها لیست خالی برمی‌گردانند.

GET https://api.waryashop.org/api/v1/games/{code}/servers catalog:read

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

لیست خالی یک پاسخ تأییدشده است: این بازی انتخاب سرور نمی‌خواهد. بازی‌ای که لیستش تأیید نشود پاسخ 503 می‌گیرد، نه لیست خالی.

خرید

POST https://api.waryashop.org/api/v1/player/validate players:validate

اعتبارسنجی بازیکن

قبل از دریافت وجه از مشتری، اکانت او را بررسی کن. خطای موقت پاسخ 503 با Retry-After است، نه «اکانت نامعتبر».

POST https://api.waryashop.org/api/v1/orders orders:write

ثبت سفارش

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

GET https://api.waryashop.org/api/v1/orders/{orderId} orders:read

دریافت وضعیت سفارش

برای ووچر تکمیل‌شده، فیلد delivery کد تحویل را دارد.

GET https://api.waryashop.org/api/v1/orders orders:read

لیست سفارش‌ها

تاریخچه صفحه‌بندی‌شده؛ جدیدترین سفارش اول است.

حساب

GET https://api.waryashop.org/api/v1/balance balance:read

موجودی کیف پول

موجودی آزاد و قفل‌شده USD به‌صورت رشتهٔ اعشاری برمی‌گردد.

GET https://api.waryashop.org/api/v1/transactions transactions:read

تراکنش‌های کیف پول

گردش حساب صفحه‌بندی‌شده برای تطبیق مالی.

04

اسکوپ‌ها

هر کلید فقط به اندپوینت‌هایی می‌رسد که اسکوپ‌هایش پوشش می‌دهند. درخواستی که کلیدش اسکوپ لازم را ندارد پاسخ 403 می‌گیرد و اسکوپ ناموجود را نام می‌برد. مجموعهٔ فقط-خواندنی به‌طور پیش‌فرض داده می‌شود؛ ساخت سفارش اسکوپی است که باید درخواست کنی.

اسکوپ چه چیزی را باز می‌کند
catalog:read Read games, packages, order fields and servers
players:validate Validate a player account before placing an order
balance:read Read the wallet balance
transactions:read Read this account's own transactions
orders:read Read this account's own orders
orders:write Create orders (an Idempotency-Key header is required)
05

محدودیت نرخ

این‌ها محدودیت‌هایی است که API واقعاً اعمال می‌کند، بر حسب درخواست در دقیقه.

کجا هر فراخوان کل سرویس
هر درخواست /api/v1، پیش از بررسی کلید 600/min 6,000/min
کلید تو (هر کلید، قابل تنظیم) 60/min (پیش‌فرض، تا 6,000) —
POST https://api.waryashop.org/api/v1/player/validate 60/min 600/min

هر پاسخ دو هدر X-RateLimit-Limit و X-RateLimit-Remaining را دارد. پاسخ ردشده 429 است و هدرهای Retry-After و X-RateLimit-Reset را هم دارد — پیش از تلاش دوباره آن‌ها را بخوان؛ همان مقدار در بدنه به‌صورت meta.retry_after تکرار می‌شود.

06

صفحه‌بندی

اندپوینت‌های فهرستی با page و per_page (نام دیگر: limit) صفحه‌بندی می‌شوند. مقدار per_page در فهرست سفارش و تراکنش بین ۱ تا 100 محدود می‌شود؛ فهرست‌های کاتالوگ به‌طور پیش‌فرض و حداکثر 500 خانواده در هر صفحه‌اند و meta.has_more می‌گوید صفحهٔ بعدی هست یا نه.

هر پاسخ فهرستی در meta مقادیر current_page، last_page، per_page، total، count و request_id را دارد، پس کلاینت می‌تواند صفحه‌ها را بپیماید و همچنان یک شناسهٔ همبستگی نقل کند.

curl "https://api.waryashop.org/api/v1/orders?page=2&per_page=50" \
  -H "X-API-Key: YOUR_API_KEY"
07

خطاها

هر پاسخ — موفق یا ناموفق — یک پوشش JSON با success، error_code، message و meta.request_id است. پاسخ‌های خطا کد و پیام را زیر error هم تکرار می‌کنند. در هر درخواست پشتیبانی meta.request_id را ذکر کن.

401 کلیدی فرستاده نشده
{
    "success": false,
    "error": {
        "code": "MISSING_API_KEY",
        "message": "X-API-Key header is required."
    },
    "error_code": "MISSING_API_KEY",
    "message": "X-API-Key header is required.",
    "meta": {
        "request_id": "01J8ZQ4M6W9K2N7P3R5T8V0XYZ"
    }
}
403 کلید اسکوپ لازم را ندارد
{
    "success": false,
    "error": {
        "code": "SCOPE_FORBIDDEN",
        "message": "This API key does not grant the \"catalog:read\" scope."
    },
    "error_code": "SCOPE_FORBIDDEN",
    "message": "This API key does not grant the \"catalog:read\" scope.",
    "meta": {
        "request_id": "01J8ZQ4M6W9K2N7P3R5T8V0XYZ"
    }
}

همهٔ وضعیت‌ها

وضعیت کدها معنا
200 / 201 — موفق. success: true، کلیدهای خود اندپوینت، همان کلیدها زیر data و meta.request_id.
400 BAD_REQUEST / IDEMPOTENCY_KEY_REQUIRED درخواست قابل فهم نبود، یا کلیدی که Idempotency-Key لازم دارد آن را نفرستاده است.
401 MISSING_API_KEY / INVALID_API_KEY / UNAUTHENTICATED کلید نبوده، ناشناخته است، یا غیرفعال/باطل شده است. هیچ چیز دیگری دربارهٔ حساب فاش نمی‌شود.
402 INSUFFICIENT_BALANCE موجودی کیف پول برای این سفارش کافی نیست. هیچ مبلغی کسر و هیچ سفارشی ثبت نشد.
403 SCOPE_FORBIDDEN / ACCOUNT_BLOCKED / IP_NOT_ALLOWED کلید این اندپوینت را پوشش نمی‌دهد، حساب مسدود است، یا درخواست از بیرون فهرست IP مجاز کلید آمده است.
404 NOT_FOUND / GAME_NOT_FOUND / ORDER_NOT_FOUND چیزی در آن آدرس سرویس نمی‌شود، آن محصول قابل فروش نیست، یا آن سفارش مال شما نیست (شناسهٔ حساب دیگر 404 است، نه 403).
405 METHOD_NOT_ALLOWED متد HTTP همانی نیست که این اندپوینت می‌پذیرد.
409 IDEMPOTENCY_CONFLICT / CONFLICT کلید Idempotency-Key پیش‌تر توسط همین حساب برای سفارش متفاوتی استفاده شده است. آن را فقط با بدنهٔ یکسان تکرار کن؛ کلیدی که حساب دیگری به‌کار می‌برد مال همان حساب است و هرگز با کلید تو تعارض ندارد.
422 VALIDATION_FAILED / INVALID_REQUEST یک فیلد ناقص، بدشکل یا غیرقابل فروش است. errors هر فیلد را نام می‌برد.
429 Retry-After: 60s RATE_LIMITED تعداد درخواست‌ها زیاد است. پیش از تلاش دوباره، مقدار هدر Retry-After (ثانیه) را صبر کن.
500 INTERNAL_ERROR / SERVICE_TEMPORARILY_UNAVAILABLE خطای پیش‌بینی‌نشده در سمت ما. meta.request_id آن را در لاگ‌های ما مشخص می‌کند؛ با فاصلهٔ تصاعدی دوباره تلاش کن.
503 Retry-After: 60s CATALOG_TEMPORARILY_UNAVAILABLE / SERVICE_TEMPORARILY_UNAVAILABLE کاتالوگ یا قیمت تأیید نشد، یا سرویس موقتاً در دسترس نیست. هیچ مبلغی کسر نشده است؛ RETRY_AFTER ثانیه برای درخواست دوباره کافی است.

خطاهای 401، 402، 403 و 422 را بدون اصلاح درخواست تکرار نکن. برای 429 و خطاهای موقت 5xx فاصلهٔ تلاش‌ها را تصاعدی افزایش بده.

08

تکرار ایمنِ ساخت سفارش

ساخت سفارش هزینه دارد، پس POST /orders از طریق هدر Idempotency-Key تکرارایمن است — تنها مکانیزم منتشرشده. همان کلید را با همان بدنه بفرست تا با اطمینان دوباره تلاش کنی: تکرار، همان سفارش نخست را با idempotent_replay برابر true برمی‌گرداند و دوباره چیزی کسر نمی‌شود. همان کلید با بدنهٔ متفاوت برای حساب تو 409 است؛ کلیدی که حساب دیگری به‌کار می‌برد مال همان حساب است و هرگز با کلید تو تعارض ندارد.

curl -X POST "https://api.waryashop.org/api/v1/orders" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Idempotency-Key: 8f3kd-order-1042" \
  -H "Content-Type: application/json" \
  -d '{"game":"pubgm","catalogue_name":"60 UC","player_id":"12345678"}'
09

وب‌هوک مشتری

هنگام ساخت سفارش یک callback_url بفرست و واریا هر رویداد سفارش را به آن می‌فرستد. هر ارسال امضا می‌شود، پس می‌توانی مطمئن باشی از طرف ما آمده و در مسیر تغییر نکرده است. تلاش‌های دوباره طبق زمان‌بندی زیر است؛ کلید امضای چرخیده در یک بازهٔ مهلت در کنار جانشینش امضا می‌کند تا بتوانی بررسی را بدون از دست دادن رویدادها جابه‌جا کنی.

رویدادها

  • order.created
  • order.processing
  • order.completed
  • order.failed
  • order.refunded

بدنه نام رویداد را دارد و api_version برابر 2026-10-28 است.

تلاش‌های دوباره

تا 5 تلاش، با فاصله‌های 1, 5, 15, 60 دقیقه بین آن‌ها (فاصلهٔ آخر تکرار می‌شود). ارسالی که پشت سر هم شکست بخورد برای بررسی ثبت می‌شود.

بازهٔ مهلت پس از چرخش کلید: 60 دقیقه.

آدرس بازگشت باید HTTPS باشد؛ آدرس http:// رد می‌شود و ریدایرکت‌ها دنبال نمی‌شوند.

امضا

X-Warya-Signature: t=<unix>,v1=<hex>

v1 همان HMAC-SHA256 روی رشتهٔ "{t}.{event_id}.{raw_body}" با کلید وب‌هوک تو است؛ همان t در X-Warya-Timestamp و شناسهٔ رویداد در X-Warya-Event-Id تکرار می‌شود. بررسی با بازمحاسبه روی همان بایت‌هایی است که دریافت کرده‌ای. برای پذیرش 2xx پاسخ بده و تکرار همان X-Warya-Event-Id را پردازش‌شده بدان.

:raw_body = the exact bytes you received
t, v1 = the two values in X-Warya-Signature
expected = hmac_sha256(key = WEBHOOK_SECRET, message = t + "." + event_id + "." + raw_body)
ok = hash_equals(expected, v1)  # compare in constant time
10

شروع کنید

  1. 1. حساب بساز

    در واریا ثبت‌نام و وارد شو. هر حساب همکاری شامل کلید API، محدودیت IP و وب‌هوک امضاشده است.

    ساخت حساب →
  2. 2. درخواست دسترسی همکاری (API)

    فرم خودکارِ درخواست دسترسی همکاری هنوز راه‌اندازی نشده است. تا آن زمان، دسترسی API را از مسیر پشتیبانی تلگرام درخواست کن تا برای حسابت فعال شود.

    ارتباط با پشتیبانی در تلگرام →
  3. 3. کلید بساز

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

  4. 4. فراخوانی /api/v1/games

    کاتالوگ را با کلیدت بخوان. درخواست بدون کلید پاسخ 401 پایین را می‌گیرد — همان پاسخ واقعی گرفته‌شده از API زنده:

    curl "https://api.waryashop.org/api/v1/games" \
      -H "X-API-Key: YOUR_API_KEY"

    بدون کلید، API زنده این را برمی‌گرداند:

    {
        "success": false,
        "error": {
            "code": "MISSING_API_KEY",
            "message": "X-API-Key header is required."
        },
        "error_code": "MISSING_API_KEY",
        "message": "X-API-Key header is required.",
        "meta": {
            "request_id": "01J8ZQ4M6W9K2N7P3R5T8V0XYZ"
        }
    }
  5. 5. سفارش ثبت کن

    ابتدا بازیکن را بررسی کن، سپس سفارش را همراه با Idempotency-Key بفرست (همان درخواستی که در بخش ۰۸ آمد). این هم پاسخ 201 آن:

    {
        "success": true,
        "order_id": "WR-20261010-8F3KD",
        "status": "processing",
        "charged": "0.950000",
        "currency": "USD",
        "idempotent_replay": false,
        "data": {
            "order_id": "WR-20261010-8F3KD",
            "status": "processing",
            "charged": "0.950000",
            "currency": "USD",
            "idempotent_replay": false
        },
        "meta": {
            "request_id": "01J8ZQ4M6W9K2N7P3R5T8V0XYZ"
        }
    }
  6. 6. وب‌هوک را دریافت کن

    هنگام ساخت سفارش یک callback_url بفرست؛ ما هر رویداد سفارش را امضاشده به آن می‌فرستیم. اگر ترجیح می‌دهی خودت بپرسی، GET /orders/{orderId} را بخوان و وقتی وضعیت completed، failed یا refunded شد بس کن.

قرارداد ماشین‌خوان

همین قرارداد به‌صورت سند OpenAPI 3.1 منتشر می‌شود و بدون کلید در دسترس است. از آن کلاینت بساز یا در Postman یا Insomnia وارد کن.

https://api.waryashop.org/openapi.json

سؤالی داری؟ مسیر پشتیبانی رسمی تلگرام است — @warya_game.