مرجع 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 در حال اجرا.