مستندات API
خرید استارز و پریمیوم تلگرام از فرگمنت با یک درخواست HTTP. مبلغ از کیف پول شما کم میشود و تحویل خودکار انجام میشود.
شروع سریع
آدرس پایه (Base URL):
https://your-site.ir/api/v1
- در سایت وارد حساب خود شوید و از «حساب من ← API» (یا از پشتیبانی) یک کلید API بسازید. کلید فقط یکبار نمایش داده میشود.
- کیف پول خود را شارژ کنید؛ هر سفارش از موجودی کیف پول پرداخت میشود.
- اتصال را آزمایش کنید:
curl https://your-site.ir/api/v1/ping \
-H "Authorization: Bearer sk_live_YOUR_KEY"
همهی پاسخها JSON (UTF-8) هستند. مبلغها تومان و عدد صحیحاند، زمانها ISO 8601 (UTC).
احراز هویت
کلید را در هدر Authorization: Bearer sk_live_XXXX بفرستید. کلید را هرگز در آدرس (query string) نفرستید و در کد سمت مرورگر یا اپلیکیشن موبایل قرار ندهید؛ فقط از سرور خودتان صدا بزنید.
- کلید فقط بهصورت هش در سرور ذخیره میشود؛ گمشدنش قابل بازیابی نیست، کلید تازه بسازید و قدیمی را حذف کنید.
- میتوانید برای هر کلید «آیپیهای مجاز»، «سقف خرج روزانه» و «فقطخواندنی» تعیین کنید.
- ۳۰ تلاش با کلید اشتباه در ۱۰ دقیقه آیپی شما را موقتاً مسدود میکند.
محدودیت نرخ
بهطور پیشفرض ۶۰ درخواست در دقیقه برای هر کلید. وضعیت در هر پاسخ:
X-RateLimit-Limit: 60 X-RateLimit-Remaining: 57 X-RateLimit-Reset: 1767225600 # زمان یونیکس شروع پنجرهی بعد
بعد از گذشتن از سقف، پاسخ 429 با هدر Retry-After (ثانیه) برمیگردد. بررسی گیرنده (/recipients) سقف جداگانهی ۲۰ بار در دقیقه دارد.
خطاها
همهی خطاها این قالب را دارند و کد HTTP مناسب برمیگردد:
{ "error": { "code": "insufficient_funds", "message": "موجودی کیف پول کافی نیست.", "details": {} } }
| HTTP | code | معنا |
|---|---|---|
| 401 | missing_api_key / invalid_api_key | کلید ارسال نشده، نامعتبر، حذف یا غیرفعال است |
| 402 | insufficient_funds | موجودی کیف پول برای این سفارش کافی نیست (چیزی کم نمیشود) |
| 403 | ip_not_allowed / orders_not_allowed / account_blocked | آیپی مجاز نیست، کلید فقطخواندنی است یا حساب مسدود است |
| 404 | not_found / recipient_not_found | سفارش یا گیرنده پیدا نشد |
| 409 | idempotency_key_reused / not_cancellable | Idempotency-Key با درخواست دیگری استفاده شده؛ سفارش دیگر قابل لغو نیست |
| 415 | unsupported_media_type | Content-Type باید application/json باشد |
| 422 | validation_error | ورودی نامعتبر است؛ details.field فیلد مشکلدار را نشان میدهد |
| 429 | rate_limited / daily_limit_exceeded | محدودیت نرخ یا سقف خرج روزانهی کلید |
| 502 / 503 | delivery_failed / service_unavailable / api_disabled | سرویس موقتاً در دسترس نیست؛ بعداً دوباره تلاش کنید (پولی کم نشده) |
Idempotency (جلوگیری از ثبت دوباره)
اگر درخواست ثبت سفارش بهخاطر قطعی شبکه بیپاسخ ماند، چهکار کنیم که دوبار سفارش ثبت نشود؟ هنگام ثبت هر سفارش یک شناسهی یکتا در هدر Idempotency-Key بفرستید (حداکثر ۶۴ نویسه). تکرار همان درخواست با همان کلید، همان سفارش را با کد 200 و هدر Idempotent-Replay: true برمیگرداند و دوباره پولی کم نمیشود. اگر همان کلید را با دادهی دیگری بفرستید 409 میگیرید.
curl -X POST https://your-site.ir/api/v1/orders \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Idempotency-Key: order-2026-0001" \
-H "Content-Type: application/json" \
-d '{"type":"stars","recipient":"durov","quantity":100}'
چرخهی سفارش
وبهوک (webhook) ندارد؛ بعد از ثبت سفارش هر ۳ تا ۵ ثانیه GET /orders/{id} را صدا بزنید تا status به یک وضعیت نهایی برسد.
| status | معنا | نهایی؟ |
|---|---|---|
| queued | پرداخت شد و در صف خرید از فرگمنت است | خیر |
| review | مبلغ بالاتر از سقف ارسال خودکار است و منتظر تأیید دستی مدیر است (قابل لغو) | خیر |
| processing | خرید در حال انجام است (ممکن است خطای موقتی خورده و دوباره تلاش شود) | خیر |
| completed | تحویل شد؛ tx_hash تراکنش TON برگردانده میشود | بله |
| failed | تحویل ممکن نشد (مثلاً گیرنده پیدا نشد) و مبلغ خودکار به کیف پول برگشت؛ error علت را دارد | بله |
| cancelled | با درخواست شما لغو و مبلغ برگشت داده شد | بله |
| refunded | مبلغ توسط پشتیبانی بازگردانده شد | بله |
هیچوقت برای یک سفارش دوبار از فرگمنت خرید انجام نمیشود؛ حتی اگر تلاش دوباره لازم شود. اگر TON فرستاده شده باشد ولی تأیید نشانی نیامده باشد، سفارش در حالت processing میماند و بازگشت خودکار انجام نمیشود (ممکن است تحویل شده باشد)؛ با پشتیبانی تماس بگیرید.
مرجع endpointها
در حال بارگذاری…
نمونهی کد
# pip install requests
import requests, time, uuid
BASE = "https://your-site.ir/api/v1"
H = {"Authorization": "Bearer sk_live_YOUR_KEY"}
order = requests.post(f"{BASE}/orders", headers={**H, "Idempotency-Key": str(uuid.uuid4())},
json={"type": "stars", "recipient": "durov", "quantity": 100}, timeout=30).json()
oid = order["id"]
while True:
o = requests.get(f"{BASE}/orders/{oid}", headers=H, timeout=30).json()
if o["status"] in ("completed", "failed", "cancelled", "refunded"):
break
time.sleep(4)
print(o["status"], o.get("tx_hash"))
// Node.js 18+
const BASE = "https://your-site.ir/api/v1";
const H = { Authorization: "Bearer sk_live_YOUR_KEY", "Content-Type": "application/json" };
const res = await fetch(`${BASE}/orders`, {
method: "POST",
headers: { ...H, "Idempotency-Key": crypto.randomUUID() },
body: JSON.stringify({ type: "premium", recipient: "durov", months: 3 }),
});
let order = await res.json();
if (!res.ok) throw new Error(order.error.code + ": " + order.error.message);
while (!["completed", "failed", "cancelled", "refunded"].includes(order.status)) {
await new Promise((r) => setTimeout(r, 4000));
order = await (await fetch(`${BASE}/orders/${order.id}`, { headers: H })).json();
}
console.log(order.status, order.tx_hash);
<?php
$base = 'https://your-site.ir/api/v1';
$key = 'sk_live_YOUR_KEY';
function api(string $method, string $url, ?array $body = null, array $extra = []): array {
global $key;
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => $method, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => array_merge(["Authorization: Bearer $key", 'Content-Type: application/json'], $extra),
CURLOPT_POSTFIELDS => $body !== null ? json_encode($body) : null,
]);
$out = json_decode((string) curl_exec($ch), true);
return [curl_getinfo($ch, CURLINFO_RESPONSE_CODE), $out];
}
[$code, $order] = api('POST', "$base/orders", ['type' => 'stars', 'recipient' => 'durov', 'quantity' => 100],
['Idempotency-Key: ' . bin2hex(random_bytes(16))]);
if ($code >= 300 && $code !== 200) die($order['error']['code'] . ': ' . $order['error']['message']);
do {
sleep(4);
[, $o] = api('GET', "$base/orders/{$order['id']}");
} while (!in_array($o['status'], ['completed', 'failed', 'cancelled', 'refunded'], true));
echo $o['status'], ' ', $o['tx_hash'] ?? '', "\n";
# قیمت ۱۰۰۰ استارز curl "https://your-site.ir/api/v1/stars/price?quantity=1000" -H "Authorization: Bearer sk_live_YOUR_KEY" # بررسی گیرنده پیش از خرید curl "https://your-site.ir/api/v1/recipients/durov?type=stars&quantity=100" -H "Authorization: Bearer sk_live_YOUR_KEY" # سفارش پریمیوم ۶ ماهه curl -X POST "https://your-site.ir/api/v1/orders" \ -H "Authorization: Bearer sk_live_YOUR_KEY" -H "Content-Type: application/json" \ -H "Idempotency-Key: premium-0001" \ -d '{"type":"premium","recipient":"durov","months":6,"metadata":{"order_ref":"A-1001"}}' # وضعیت و لغو curl "https://your-site.ir/api/v1/orders/T-7KQ2M9XA" -H "Authorization: Bearer sk_live_YOUR_KEY" curl -X POST "https://your-site.ir/api/v1/orders/T-7KQ2M9XA/cancel" -H "Authorization: Bearer sk_live_YOUR_KEY"
سوالات رایج
خرید چطور از فرگمنت انجام میشود؟
سرور فروشگاه با ولت TON خودش (کلید ولت فقط روی سرویس امضای جدا میماند) وارد fragment.com میشود، گیرنده را جستوجو و قیمت را دریافت میکند، تراکنش را امضا و ارسال میکند و تأیید روی شبکه را بررسی میکند. هر سفارش حداکثر یک تراکنش دارد.
اگر تحویل ناموفق شد پولم چه میشود؟
اگر خرید قطعاً انجام نشده و هیچ TON ای فرستاده نشده باشد (مثلاً گیرنده پیدا نشد)، مبلغ خودکار به کیف پول برمیگردد و status=failed میشود. خطاهای موقت (قطعی شبکه، شلوغی فرگمنت) خودکار تلاش دوباره میشوند.
حداقل و حداکثر تعداد؟
استارز: از GET /prices بخوانید (stars.min و stars.max؛ معمولاً حداقل ۵۰). پریمیوم: ۳، ۶ یا ۱۲ ماه.
گیرنده چه یوزرنیمی میتواند باشد؟
یوزرنیم تلگرام کاربر (۵ تا ۳۲ نویسه، حروف انگلیسی، عدد و _) با یا بدون @. برای پریمیوم، حسابی که هماکنون پریمیوم دارد پذیرفته نمیشود (already_premium). پیش از خرید با GET /recipients/{username} میتوانید بررسی کنید.
تست ندارد؟
این API فقط روی سیستم واقعی کار میکند و محیط شبیهساز ندارد؛ برای آزمایش از کمترین مقدار (۵۰ استارز) استفاده کنید.
