مرجع API
هر اندپوینتی که API همکاری واریا منتشر میکند، اسکوپی که هرکدام لازم دارد، پارامترهایی که میپذیرد و پوشش دقیقی که هر پاسخ دارد. بدون نیاز به حساب قابل خواندن.
https://api.waryashop.org/api/v1
احراز هویت
روی هر فراخوانی کلیدت را در هدر 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 وقتی صفحهٔ بعدی هست.
کاتالوگ
https://api.waryashop.org/api/v1/games
catalog:read
لیست بازیها و محصولات
کد محصول، نام انگلیسی، نام فارسی اختیاری و آدرس تصویر میزبانیشده روی واریا. صفحهبندیشده؛ صفحهٔ پیشفرض کل لیست است.
- موفق:
- 200
- اسکوپ:
catalog:read- کوئری:
- search, category, page, per_page, sort
https://api.waryashop.org/api/v1/games/{code}/catalogue
catalog:read
پکیجها و قیمت فروش
هنگام ثبت سفارش دقیقاً همان catalogue_name این پاسخ را ارسال کن. اینها قیمت فروش واریا به دلار و بهصورت رشتهٔ اعشاری است. فقط پکیجهایی فهرست میشوند که همین حالا قیمتشان قابل تأیید است؛ محصولی که دیگر قابل فروش نیست یا مبلغش تأیید نمیشود اینجا غایب است — نه اینکه با ۰٫۰۰۰۰۰۰ منتشر شود — و نامبردن آن در سفارش پاسخ ۴۲۲ میگیرد.
- موفق:
- 200
- اسکوپ:
catalog:read- مسیر:
- code
- کوئری:
- search, in_stock, page, per_page, sort
https://api.waryashop.org/api/v1/games/{code}/fields
catalog:read
فیلدهای لازم بازیکن
شناسههایی که فرم سفارش این بازی باید بگیرد، همراه با meta.source و meta.freshness که میگوید پاسخ از کجا آمده است. ووچرها لیست خالی برمیگردانند.
- موفق:
- 200
- اسکوپ:
catalog:read- مسیر:
- code
https://api.waryashop.org/api/v1/games/{code}/servers
catalog:read
سرورها و ریجنها
لیست خالی یک پاسخ تأییدشده است: این بازی انتخاب سرور نمیخواهد. بازیای که لیستش تأیید نشود پاسخ 503 میگیرد، نه لیست خالی.
- موفق:
- 200
- اسکوپ:
catalog:read- مسیر:
- code
خرید
https://api.waryashop.org/api/v1/player/validate
players:validate
اعتبارسنجی بازیکن
قبل از دریافت وجه از مشتری، اکانت او را بررسی کن. خطای موقت پاسخ 503 با Retry-After است، نه «اکانت نامعتبر».
- موفق:
- 200
- اسکوپ:
players:validate- بدنه:
- game, player_id, server_id?, charname?
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"
}
}https://api.waryashop.org/api/v1/orders/{orderId}
orders:read
دریافت وضعیت سفارش
برای ووچر تکمیلشده، فیلد delivery کد تحویل را دارد.
- موفق:
- 200
- اسکوپ:
orders:read- مسیر:
- orderId
https://api.waryashop.org/api/v1/orders
orders:read
لیست سفارشها
تاریخچه صفحهبندیشده؛ جدیدترین سفارش اول است.
- موفق:
- 200
- اسکوپ:
orders:read- کوئری:
- status, type, game, customer_reference, from, to, page, per_page, sort
حساب
https://api.waryashop.org/api/v1/balance
balance:read
موجودی کیف پول
موجودی آزاد و قفلشده USD بهصورت رشتهٔ اعشاری برمیگردد.
- موفق:
- 200
- اسکوپ:
balance:read
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"
}وبهوک مشتری
سفارش را با callback_url بساز و واریا هر رویداد سفارش را به آن میفرستد. هر ارسال امضا میشود. آدرس باید HTTPS باشد؛ ریدایرکتها دنبال نمیشوند و میزبان در هر تلاش دوباره resolve و بررسی میشود.
رویدادها
order.createdorder.processingorder.completedorder.failedorder.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مشخصات فنی OpenAPI 3.1
قرارداد ماشینخوان که بدون کلید در دسترس است. آن را در Postman، Insomnia یا Swagger وارد کن، schemaها را ببین یا یک SDK تایپشده بساز. همان سندی که این مرجع از آن رندر میشود در آدرس زیر در دسترس است.
https://api.waryashop.org/openapi.json
پاسخ ماشین، پاسخ انسان. قرارداد خواندهشده از API در حال اجرا.