رفتن به محتوای اصلی

مرجع API

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

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

احراز هویت

روی هر فراخوانی کلیدت را در هدر X-API-Key بفرست. هرگز در آدرس یا query string. کلید نبوده/ناشناخته/غیرفعال/باطل پاسخ 401 می‌گیرد و هیچ چیز دیگری دربارهٔ حساب نام نمی‌برد. هر حساب 1 کلید دارد؛ اسکوپ می‌گیرد و می‌تواند آدرس‌هایی را که از آن‌ها پاسخ می‌دهد محدود کند (تا 32 قانون).

curl "https://api.waryashop.org/api/v1/balance" \
  -H "X-API-Key: YOUR_API_KEY"
محدودیت‌ها

محدودیت نرخ و صفحه‌بندی

کجا هر فراخوان کل سرویس
هر درخواست /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 را دارد؛ پاسخ ۴۲۹ هم Retry-After و X-RateLimit-Reset را دارد و مدت انتظار را به‌صورت meta.retry_after تکرار می‌کند. اندپوینت‌های فهرستی با page و per_page (نام دیگر limit) صفحه‌بندی می‌شوند: مقدار per_page در فهرست سفارش و تراکنش بین ۱ تا 100 محدود می‌شود و فهرست‌های کاتالوگ به‌طور پیش‌فرض و حداکثر 500 خانواده در هر صفحه‌اند، با meta.has_more وقتی صفحهٔ بعدی هست.

کاتالوگ

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

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

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

موفق:
200
اسکوپ:
catalog:read
کوئری:
search, category, page, per_page, sort
GET https://api.waryashop.org/api/v1/games/{code}/catalogue catalog:read

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

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

موفق:
200
اسکوپ:
catalog:read
مسیر:
code
کوئری:
search, in_stock, page, per_page, sort
GET https://api.waryashop.org/api/v1/games/{code}/fields catalog:read

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

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

موفق:
200
اسکوپ:
catalog:read
مسیر:
code
GET https://api.waryashop.org/api/v1/games/{code}/servers catalog:read

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

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

موفق:
200
اسکوپ:
catalog:read
مسیر:
code

خرید

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

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

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

موفق:
200
اسکوپ:
players:validate
بدنه:
game, player_id, server_id?, charname?
POST https://api.waryashop.org/api/v1/orders orders:write

ثبت سفارش

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

موفق:
201
اسکوپ:
orders:write
هدر:
Idempotency-Key
بدنه:
game, catalogue_name, player_id, server_id?, charname?, customer_reference?, callback_url?

هدر 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"
    }
}
GET https://api.waryashop.org/api/v1/orders/{orderId} orders:read

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

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

موفق:
200
اسکوپ:
orders:read
مسیر:
orderId
GET https://api.waryashop.org/api/v1/orders orders:read

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

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

موفق:
200
اسکوپ:
orders:read
کوئری:
status, type, game, customer_reference, from, to, page, per_page, sort

حساب

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

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

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

موفق:
200
اسکوپ:
balance:read
GET https://api.waryashop.org/api/v1/transactions transactions:read

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

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

موفق:
200
اسکوپ:
transactions:read
کوئری:
type, status, from, to, page, per_page, sort
پاسخ‌ها

قرارداد وضعیت و خطا

پاسخ موفق success: true دارد، کلیدهای اندپوینت را در سطح بالا، همان کلیدها را زیر data و meta.request_id را (هم در هدر X-Request-Id) برمی‌گرداند. پاسخ ناموفق success: false با error_code و message دارد که آن‌ها را زیر error هم تکرار می‌کند.

وضعیت کدها معنا
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 · بدون کلید

{
    "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"
    }
}

422 · اعتبارسنجی ناموفق

{
    "success": false,
    "error": {
        "code": "VALIDATION_FAILED",
        "message": "The request could not be validated."
    },
    "error_code": "VALIDATION_FAILED",
    "message": "The request could not be validated.",
    "errors": {
        "game": [
            "The game field is required."
        ]
    },
    "meta": {
        "request_id": "01J8ZQ4M6W9K2N7P3R5T8V0XYZ"
    }
}
سفارش

وضعیت‌های سفارش

GET /orders/{orderId} یکی از چهار وضعیت را منتشر می‌کند. فیلد delivery فقط برای سفارش ووچرِ تکمیل‌شده کد تحویل را دارد و در هر وضعیت دیگر null است. این بدنه‌ها توسط همان سریالایزری ساخته شده‌اند که خود اندپوینت با آن پاسخ می‌دهد.

created
{
    "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"
    }
}
processing
{
    "order_id": "WR-20261028-8F3KD",
    "status": "processing",
    "type": "game_topup",
    "game": "pubgm",
    "catalogue_name": "60 UC",
    "player_id": "12345678",
    "server_id": null,
    "total_amount": "0.950000",
    "currency": "USD",
    "customer_reference": "MY-ORDER-123",
    "delivery": null,
    "created_at": "2026-10-10T09:00:00+00:00",
    "updated_at": "2026-10-10T09:00:00+00:00"
}
completed
{
    "order_id": "WR-20261028-8F3KD",
    "status": "completed",
    "type": "game_topup",
    "game": "pubgm",
    "catalogue_name": "60 UC",
    "player_id": "12345678",
    "server_id": null,
    "total_amount": "0.950000",
    "currency": "USD",
    "customer_reference": "MY-ORDER-123",
    "delivery": {
        "code": "WARYA-60UC-4KQ7T2M9"
    },
    "created_at": "2026-10-10T09:00:00+00:00",
    "updated_at": "2026-10-10T09:00:00+00:00"
}
failed
{
    "order_id": "WR-20261028-8F3KD",
    "status": "failed",
    "type": "game_topup",
    "game": "pubgm",
    "catalogue_name": "60 UC",
    "player_id": "12345678",
    "server_id": null,
    "total_amount": "0.950000",
    "currency": "USD",
    "customer_reference": "MY-ORDER-123",
    "delivery": null,
    "created_at": "2026-10-10T09:00:00+00:00",
    "updated_at": "2026-10-10T09:00:00+00:00"
}
refunded
{
    "order_id": "WR-20261028-8F3KD",
    "status": "refunded",
    "type": "game_topup",
    "game": "pubgm",
    "catalogue_name": "60 UC",
    "player_id": "12345678",
    "server_id": null,
    "total_amount": "0.950000",
    "currency": "USD",
    "customer_reference": "MY-ORDER-123",
    "delivery": null,
    "created_at": "2026-10-10T09:00:00+00:00",
    "updated_at": "2026-10-10T09:00:00+00:00"
}
Webhooks

وب‌هوک مشتری

سفارش را با callback_url بساز و واریا هر رویداد سفارش را به آن می‌فرستد. هر ارسال امضا می‌شود. آدرس باید HTTPS باشد؛ ریدایرکت‌ها دنبال نمی‌شوند و میزبان در هر تلاش دوباره resolve و بررسی می‌شود.

رویدادها

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

تحویل

  • Signature: X-Warya-Signature
  • Timestamp: X-Warya-Timestamp
  • Event id: X-Warya-Event-Id
  • api_version: 2026-10-28
  • Retries: 5 attempts, waits 1, 5, 15, 60 min
  • Grace after rotation: 60 min

بررسی امضا

v1 همان HMAC-SHA256 روی "{t}.{event_id}.{raw_body}" با کلید وب‌هوک تو است. روی همان بایت‌هایی که دریافت کرده‌ای بازمحاسبه کن و در زمان ثابت مقایسه کن.

: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
API CONTRACT

مشخصات فنی OpenAPI 3.1

قرارداد ماشین‌خوان که بدون کلید در دسترس است. آن را در Postman، Insomnia یا Swagger وارد کن، schema‌ها را ببین یا یک SDK تایپ‌شده بساز. همان سندی که این مرجع از آن رندر می‌شود در آدرس زیر در دسترس است.

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

پاسخ ماشین، پاسخ انسان. قرارداد خوانده‌شده از API در حال اجرا.