# مستندات API ترونادو

راهنمای کامل اتصال کسب‌وکار شما به درگاه ترونادو

- Base URL: `https://bot.tronado.cloud`
- نسخه‌ی پیشنهادی: `v5`
- پشتیبانی: @TronadoSupp — https://t.me/TronadoSupp

> این فایل به‌صورت خودکار از documentation.content.ts ساخته می‌شود. دستی ویرایش نکنید.

## معرفی

این مستندات تمام endpoint های مورد نیاز برای اتصال اپلیکیشن یا وب‌سایت شما به API ترونادو را پوشش می‌دهد. برای هر endpoint، پارامترهای ورودی، ساختار پاسخ و نمونه‌ی کد آورده شده است.

> **استفاده در ابزارهای هوش مصنوعی:** اگر می‌خواهید این مستندات را به ChatGPT، Claude یا هر ابزار هوش مصنوعی دیگری بدهید تا کد اتصال را برایتان بنویسد، به‌جای آدرس همین صفحه، آدرس زیر را بدهید. این نسخه‌ی متنی (Markdown) دقیقاً همین محتواست و بدون اجرای جاوااسکریپت خوانده می‌شود — آدرس همین صفحه برای این ابزارها خالی دیده می‌شود.

**نسخه‌ی متنی برای هوش مصنوعی**

```text
https://miniapp.tronado.cloud/assets/api-docs.md
```

> **نکته مهم:** در بخش «ایجاد سفارش» نحوه‌ی ساخت تراکنش و استفاده از صفحه‌ی پرداخت ترونادو توضیح داده شده است. در این روش، مشتری روی دکمه‌ی ربات کسب‌وکار شما کلیک می‌کند و صفحه‌ی پرداخت ترونادو باز می‌شود؛ بدون اینکه لازم باشد وارد ربات ترونادو شود.

> **مهم‌ترین بخش:** قرارداد callback یا همان IPN، مهم‌ترین بخش این مستندات است — تطبیق پرداخت و شارژ کاربر شما بر پایه‌ی همان انجام می‌شود. حتماً بخش «IPN Callback» را کامل بخوانید.

## شروع سریع

برای دریافت API Key با پشتیبانی ترونادو ارتباط بگیرید و کسب‌وکار خود را احراز کنید. سپس در هر درخواست، این هدرها را ارسال کنید:

**Headers**

```http
x-api-key: <YOUR_API_KEY>
Content-Type: application/json
```

**آدرس پایه (Base URL)**

| Field | Type | Description |
| --- | --- | --- |
| `https://bot.tronado.cloud` | base url | تمام مسیرهای این مستندات نسبت به این آدرس هستند. |

## دامنه‌ی Callback

> **ثبت دامنه الزامی است:** دامنه‌ی CallbackUrl شما باید از پیش در فهرست دامنه‌های مجاز کسب‌وکارتان ثبت شده باشد. اگر دامنه ثبت نشده باشد، callback ارسال نمی‌شود و سفارش بدون هیچ اطلاع‌رسانی در سیستم شما باقی می‌ماند.

پیش از تغییر دامنه یا افزودن دامنه‌ی جدید، حتماً آن را از طریق پشتیبانی ثبت کنید. این محدودیت برای جلوگیری از هدایت callback به دامنه‌ی مهاجم در صورت لو رفتن API Key اعمال شده است.

همچنین CallbackUrl باید حتماً https باشد.

## نسخه‌بندی

نسخه در مسیر URL و بعد از آدرس پایه قرار می‌گیرد: /api/v{version}/… — نسخه‌ی پیشنهادی فعلی v5 است. تنها اندپوینت GetOrderToken نسخه‌بندی می‌شود.

- در callback دو فیلد UserPaidTomanAmount و TomanAmountWithoutWage ارسال می‌شود.
- هر callback با امضای HMAC-SHA512 در هدر X-Tronado-Sig امضا می‌شود.
- برای هر تغییر وضعیت سفارش یک callback جداگانه ارسال می‌شود، نه فقط هنگام پرداخت موفق.

**نمونه**

```http
POST https://bot.tronado.cloud/api/v5/GetOrderToken
```

## محدودیت‌ها

محدودیت‌های ایجاد تراکنش برای هر کاربر:

| محدودیت | مقدار | قابل تغییر؟ |
| --- | --- | --- |
| تعداد تراکنش در روز | ۱ | با هماهنگی پشتیبانی |
| سقف مبلغ روزانه | ۵۰۰ هزار تومان | بله |
| سقف مبلغ ماهانه | ۱ میلیون تومان | با هماهنگی پشتیبانی |
| تراکنش کنسل‌شده در روز | ۲ | خیر |
| تراکنش کنسل‌شده در ماه | ۴ | خیر |

## قیمت‌گذاری و کارمزد

کارمزد پیش‌فرض ۲۰٪ است اما برای هر کسب‌وکار قابل تنظیم است. حداقل کارمزد، بیشترِ دو مقدار «۹٬۰۰۰ تومان» یا «معادل ۰٫۱ دلار» است؛ یعنی اگر ۲۰٪ کارمزد شما کمتر از این مقدار شود، همین حداقل اعمال می‌شود.

تعیین پرداخت‌کننده‌ی کارمزد با پارامتر wageFromBusinessPercentage در GetOrderToken انجام می‌شود. این پارامتر مشخص می‌کند چه درصدی از کارمزد را کسب‌وکار جذب کند:

| مقدار | رفتار |
| --- | --- |
| ۰ (پیش‌فرض) | کل کارمزد روی مبلغ پرداختی کاربر اضافه می‌شود؛ شما ترون کامل فاکتور را دریافت می‌کنید. |
| ۱۰۰ | کل کارمزد از سهم شما کم می‌شود؛ کاربر تقریباً معادل ارزش پایه‌ی فاکتور را می‌پردازد. |
| بین ۰ تا ۱۰۰ | کارمزد به‌نسبت بین کاربر و کسب‌وکار تقسیم می‌شود. |

> **کدام فیلد را برای شارژ کاربر استفاده کنم؟:** دو فیلد تومانی callback نسخه‌ی v5 معنای یکسانی ندارند. TomanAmountWithoutWage یعنی ارزش تومانی ترونی که واقعاً به شما تحویل داده شد، و UserPaidTomanAmount یعنی مبلغی که کاربر پرداخت کرد (شامل کارمزد).

- با wageFromBusinessPercentage = 0 (پیش‌فرض؛ کارمزد را کاربر می‌دهد): از TomanAmountWithoutWage استفاده کنید. اگر در این حالت UserPaidTomanAmount را شارژ کنید، کارمزد ترونادو را از جیب خودتان به کاربر هدیه داده‌اید.
- با wageFromBusinessPercentage = 100 (کارمزد را شما جذب می‌کنید): از UserPaidTomanAmount استفاده کنید؛ این مبلغ تقریباً برابر ارزش پایه‌ی فاکتور شماست.
- با مقادیر بین ۰ و ۱۰۰: ارزش فاکتور خودتان را شارژ کنید — یعنی همان TronAmount ی که در GetOrderToken فرستادید ضربدر قیمت ترون.

مثال عددی: فرض کنید فاکتور شما ۱۰ ترون است، کارمزد کسب‌وکار شما ۲۰٪ و قیمت ترون ۷۰٬۰۰۰ تومان (کارمزد شبکه را برای سادگی صفر گرفته‌ایم). ابتدا کارمزد به ترون حساب می‌شود: ۱۰ − (۱۰ ÷ ۱٫۲) = ۱٫۶۶۷ ترون. سپس سهمی که شما جذب می‌کنید از ترون تحویلی کم می‌شود و کارمزد روی همان مقدار کم‌شده اعمال می‌گردد:

**مقایسه‌ی سه حالت**

| wageFromBusinessPercentage | ترون تحویلی به شما | TomanAmountWithoutWage | UserPaidTomanAmount | کارمزد کاربر | کارمزد شما |
| --- | --- | --- | --- | --- | --- |
| ۰ | ۱۰٫۰۰۰ | ۷۰۰٬۰۰۰ | ۸۴۰٬۰۰۰ | ۱۴۰٬۰۰۰ | ۰ |
| ۵۰ | ۹٫۱۶۷ | ۶۴۱٬۷۰۰ | ۷۷۰٬۰۰۰ | ۷۰٬۰۰۰ | ۵۸٬۳۰۰ |
| ۱۰۰ | ۸٫۳۳۳ | ۵۸۳٬۳۰۰ | ۷۰۰٬۰۰۰ | ۰ | ۱۱۶٬۷۰۰ |

> **خواندن سطر ۵۰:** کاربر ۷۷۰٬۰۰۰ تومان پرداخت کرد (به‌جای ۸۴۰٬۰۰۰ در حالت ۰) و شما به‌جای ۱۰ ترون، ۹٫۱۶۷ ترون گرفتید. اگر می‌خواهید کاربر ارزش کامل فاکتور را بگیرد، ۷۰۰٬۰۰۰ تومان یعنی ارزش فاکتور خودتان را شارژ کنید؛ اختلاف ۷۰۰٬۰۰۰ با ۶۴۱٬۷۰۰ همان نیمی از کارمزد است که پذیرفته‌اید بپردازید.

توجه: wageFromBusinessPercentage تعیین می‌کند چقدر ترون بگیرید، نه اینکه کدام فیلد را شارژ کنید. TomanAmountWithoutWage در همه‌ی حالت‌ها یعنی «ارزش آنچه دریافت کردم». اعداد نهایی به‌دلیل رند شدن و افزودن مقدار جزئی برای یکتا کردن مبلغ واریزی، تا چند هزار تومان با محاسبه‌ی بالا تفاوت دارند.

> **کارمزد شبکه‌ی ترون:** برای ولت‌های NowPayments یا ولت‌های غیرفعال، حدود ۱٫۲ ترون بابت هزینه‌ی فعال‌سازی ولت در شبکه‌ی ترون به مبلغ نهایی اضافه می‌شود. هزینه‌ی انتقال (تا حدود ۰٫۸ ترون) نیز برای ولت‌های فعال به مبلغ نهایی اضافه می‌شود. اگر مبلغی بیش از این اضافه شد با پشتیبانی تماس بگیرید.

## سفارش

### GetOrderToken

`POST /api/v5/GetOrderToken`

ایجاد تراکنش جدید و دریافت توکن پرداخت

> **WARN:** قبل از این درخواست حتماً قیمت ترون را از بخش «قیمت‌ها» بگیرید تا مقدار ترون درخواستی را درست محاسبه کنید.

**بدنه‌ی درخواست**

| Field | Type | Description |
| --- | --- | --- |
| `PaymentID` | string | شناسه‌ی پرداخت در سیستم شما (یکتا) |
| `WalletAddress` | string | آدرس کیف پول مقصد |
| `TronAmount` | decimal | مقدار ترون فاکتور |
| `CallbackUrl` | string | آدرسی که نتیجه‌ی پرداخت به آن POST می‌شود (باید https و ثبت‌شده باشد) |

**پارامترهای مسیر و کوئری**

| Field | Type | Description |
| --- | --- | --- |
| `apiVersion` | path | نسخه‌ی API در مسیر URL — پیشنهادی v5 (پیش‌فرض ۱) |
| `wageFromBusinessPercentage` | query | درصد کارمزدی که کسب‌وکار جذب می‌کند (۰ تا ۱۰۰). توضیح کامل در بخش قیمت‌گذاری. (پیش‌فرض ۰) |

**نمونه‌ی درخواست**

```json
{
  "PaymentID": "INV-10231",
  "WalletAddress": "TExampleWa11etAddressForDocsOnly00",
  "TronAmount": 10.0,
  "CallbackUrl": "https://your-site.com/tronado/callback"
}
```

**پاسخ (۲۰۰)**

| Field | Type | Description |
| --- | --- | --- |
| `Token` | string | توکن تراکنش |
| `FullPaymentUrl` | string | لینک کامل پرداخت |
| `ErrorMessage` | string | پیام خطا (در صورت وجود) |
| `EstimatedTomanAmount` | string | مبلغ تخمینی به تومان (از v3 به بعد) |
| `EstimatedTomanAmountExpireDateUtc` | string | تاریخ انقضای مبلغ تخمینی به وقت UTC |

> **صفحه‌ی پرداخت ترونادو:** توکن را به انتهای این لینک اضافه کنید و روی دکمه‌ی ربات خود قرار دهید. مشتری با کلیک، وارد صفحه‌ی پرداخت می‌شود.

```http
https://t.me/tronado_robot/customerpayment?startapp={YOUR_TOKEN}
```

### GetStatus

`POST /Order/GetStatus`

رصد وضعیت سفارش با شناسه‌ی ترونادو یا TXID

**بدنه‌ی درخواست**

| Field | Type | Description |
| --- | --- | --- |
| `Id` | string | شناسه‌ی تراکنش — OrderId ترونادو یا TrndOrderID_{orderId} یا TXID |

**پاسخ (۲۰۰)**

| Field | Type | Description |
| --- | --- | --- |
| `UniqueCode` | string | کد یکتا |
| `PaymentID` | string | شناسه‌ی پرداخت شما |
| `UserTelegramId` | long | شناسه‌ی کاربر تلگرام |
| `Wallet` | string | کیف پول مقصد |
| `Hash` | string | هش تراکنش (TXID) |
| `TronAmount` | decimal | مقدار ترون تحویلی |
| `ActualTronAmount` | decimal? | مقدار ترون اولیه پیش از تعدیل |
| `OrderStatusID` | int? | شناسه‌ی عددی وضعیت سفارش |
| `OrderStatusTitle` | string | عنوان فارسی وضعیت |
| `IsPaid` | bool | پرداخت موفق؟ |
| `PaymentDate` | string | تاریخ پرداخت |

**خطا — سفارش یافت نشد**

```json
{ "Error": "No order found with this txid" }
```

### GetStatusByPaymentID

`POST /Order/GetStatusByPaymentID`

همان GetStatus، اما با شناسه‌ی پرداخت خودتان

**بدنه‌ی درخواست**

| Field | Type | Description |
| --- | --- | --- |
| `Id` | string | شناسه‌ی پرداخت در اپلیکیشن شما — همان PaymentID که در GetOrderToken فرستادید |

ساختار پاسخ دقیقاً مانند GetStatus است.

## IPN Callback

> **INFO:** این درخواست را شما ارسال نمی‌کنید — این همان چیزی است که ترونادو به CallbackUrl شما POST می‌کند.

- برای هر تغییر وضعیت سفارش یک callback جداگانه به CallbackUrl شما ارسال می‌شود.
- برای تشخیص پرداخت موفق: IsPaid == true یا OrderStatusID == 30 را بررسی کنید.
- درخواست‌های تکراری را با کلید (PaymentId, OrderStatusID) حذف تکرار کنید.
- برای تأیید دریافت، کد 2xx برگردانید. در غیر این صورت ترونادو دوباره تلاش می‌کند.

> **تأیید امضا الزامی است:** هر callback یک هدر X-Tronado-Sig دارد. کلید اختصاصی کسب‌وکار شما (IpnSigningKey) را از پشتیبانی دریافت می‌کنید. امضا را روی بدنه‌ی خام و پیش از هرگونه parse محاسبه کنید و با مقایسه‌ی ثابت‌زمان تطبیق دهید؛ اگر برابر نبود درخواست را رد کنید.

**فرمول امضا**

```text
X-Tronado-Sig = HMAC_SHA512(rawJsonBody, YOUR_IPN_SIGNING_KEY)  // hex
```

**Node.js**

```javascript
const crypto = require('crypto');
const sig = crypto.createHmac('sha512', YOUR_IPN_SIGNING_KEY)
                  .update(rawBody)            // بدنه‌ی خام، نه JSON.stringify
                  .digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(req.header('X-Tronado-Sig')))) {
  return res.status(401).end();
}
```

**C#**

```csharp
using var h = new HMACSHA512(Encoding.UTF8.GetBytes(YOUR_IPN_SIGNING_KEY));
var hex = Convert.ToHexString(h.ComputeHash(rawBodyBytes)).ToLowerInvariant();
var ok = CryptographicOperations.FixedTimeEquals(
            Encoding.UTF8.GetBytes(hex),
            Encoding.UTF8.GetBytes(sigHeader.ToLowerInvariant()));
```

**فیلدهای payload**

| Field | Type | Description |
| --- | --- | --- |
| `UniqueCode` | string | کد یکتای تراکنش (در v5 همان توکن GUID) |
| `PaymentId` | string | شناسه‌ی پرداخت شما |
| `UserTelegramId` | long | شناسه‌ی کاربر تلگرام |
| `Wallet` | string | کیف پول مقصد |
| `Hash` | string | هش تراکنش (TXID) یا TrndOrderID_{orderId} |
| `TronAmount` | decimal | مقدار ترون تحویل‌شده به شما. با wageFromBusinessPercentage=0 برابر کل فاکتور است؛ با ۱۰۰ پس از کسر کارمزد. |
| `ActualTronAmount` | decimal | مقدار ترون اولیه پیش از تعدیل احتمالی |
| `UserPaidTomanAmount` | int | مبلغی که کاربر واقعاً پرداخت کرد (با کارمزد). برای انتخاب فیلد درست جهت شارژ، بخش قیمت‌گذاری را ببینید. (v5) |
| `TomanAmountWithoutWage` | int | ارزش تومانی ترونی که به شما تحویل داده شد (بدون کارمزد). در حالت پیش‌فرض همین مبلغ را برای کاربر شارژ کنید. (v5) |
| `OrderStatusID` | int | شناسه‌ی عددی وضعیت سفارش |
| `OrderStatusTitle` | string | عنوان فارسی وضعیت. صرفاً جهت نمایش است؛ منطق سمت خود را روی OrderStatusID پیاده کنید نه روی این متن. |
| `IsPaid` | bool | پرداخت موفق؟ |
| `PaymentDate` | string | تاریخ و زمان وضعیت |

> **TIP:** قیمت هر ترون به تومان در این سفارش = TomanAmountWithoutWage ÷ TronAmount

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

| Code | Name | عنوان |
| --- | --- | --- |
| ۲۰ | `WaitingForPayment` | در انتظار عکس |
| ۲۵ | `PhotoSentToAdmin` | عکس ارسال شده به ادمین |
| ۲۷ | `ReadyToTransfer` | آماده برای انتقال ترون |
| ۳۰ | `PaymentAccepted` | تایید شده — پرداخت قطعی |
| ۴۰ | `PaymentRejected` | رد شده |
| ۲۰۰ | `Cancelled` | لغو شده |

**نمونه‌ی payload**

```json
{
  "UniqueCode": "00000000000000000000000000000000",
  "PaymentId": "INV-10231",
  "UserTelegramId": 123456789,
  "Wallet": "TExampleWa11etAddressForDocsOnly00",
  "Hash": "TrndOrderID_1000001",
  "TronAmount": 7.703448,
  "ActualTronAmount": 7.703448,
  "UserPaidTomanAmount": 596270,
  "TomanAmountWithoutWage": 513720,
  "OrderStatusID": 30,
  "OrderStatusTitle": "تایید شده",
  "IsPaid": true,
  "PaymentDate": "2026-08-01T13:34:40.453"
}
```

## قیمت‌ها

دریافت قیمت‌ها و محاسبه‌ی مقدار ترون درخواستی. همه‌ی این اندپوینت‌ها POST هستند و برخلاف بقیه‌ی مسیرها به هدر x-api-key نیاز ندارند؛ تنها GetPriceWithWageToToman با فیلد RequestCode در بدنه‌ی درخواست احراز می‌شود.

> **بدنه‌ی خالی نفرستید:** حتی وقتی اندپوینتی پارامتر ورودی ندارد، حداقل {} را به‌عنوان بدنه بفرستید. درخواست POST بدون Content-Length را IIS با خطای 411 Length Required رد می‌کند و این خطا به‌سادگی با ۴۰۴ اشتباه گرفته می‌شود.

### قیمت ترون به تومان

`POST /Tron/GetPriceToToman`

اولین اندپوینت پیش از ایجاد تراکنش

> **INFO:** قیمت ترون در ترونادو با صرافی‌های دیگر متفاوت است؛ برای محاسبه‌ی درست مقدار ترون درخواستی، ابتدا قیمت را از اینجا بگیرید. این درخواست بدنه ندارد.

**پاسخ (۲۰۰)**

| Field | Type | Description |
| --- | --- | --- |
| `TronPriceToman` | int | قیمت ترون به تومان (نه ریال) |
| `TronPriceDollar` | decimal | قیمت ترون به دلار |

### قیمت ترون با کارمزد

`POST /Tron/GetPriceWithWageToToman`

مقدار ترون دلخواه را به تومان (همراه کارمزد) برمی‌گرداند

**بدنه‌ی درخواست**

| Field | Type | Description |
| --- | --- | --- |
| `RequestCode` | string | از طریق پشتیبانی تهیه می‌شود |
| `WalletAddress` | string | آدرس کیف پول مقصد |
| `TronAmount` | decimal | مقدار ترون |

**پاسخ (۲۰۰)**

| Field | Type | Description |
| --- | --- | --- |
| `ActualAmountToman` | int | مقدار تومانی معادل ترون درخواستی (بدون کارمزد) |
| `AmountWithWageToman` | int | مقدار تومانی همراه با کارمزد |

### تبدیل تومان به ترون

`POST /Toman/ConvertToTronWageSubtracted`

مقدار تومانی را گرفته و معادل ترون (بدون احتساب کارمزد) را برمی‌گرداند

**بدنه‌ی درخواست**

| Field | Type | Description |
| --- | --- | --- |
| `Toman` | int | مقدار تومانی درخواستی |
| `Wallet` | string | آدرس کیف پول مقصد |

**پاسخ (۲۰۰)**

| Field | Type | Description |
| --- | --- | --- |
| `TronAmount` | decimal | مقدار ترون |
| `TronSunAmount` | decimal | مقدار ترون به Sun |

### تبدیل دلار به ترون

`POST /Dollar/ConvertToTronWageSubtracted`

مقدار دلاری را گرفته و معادل ترون (بدون احتساب کارمزد) را برمی‌گرداند

**بدنه‌ی درخواست**

| Field | Type | Description |
| --- | --- | --- |
| `Dollar` | decimal | مقدار دلار |
| `Wallet` | string | آدرس کیف پول مقصد |

**پاسخ (۲۰۰)**

| Field | Type | Description |
| --- | --- | --- |
| `TronAmount` | decimal | مقدار ترون |
| `TronSunAmount` | decimal | مقدار ترون به Sun |

### قیمت دلار به تومان

`POST /Dollar/GetPriceToToman`

قیمت دلار به تومان را برمی‌گرداند. بدون بدنه.

**پاسخ (۲۰۰)**

| Field | Type | Description |
| --- | --- | --- |
| `DollarPrice` | int | قیمت دلار به تومان |

## تست در محیط توسعه

با اکانتی که کسب‌وکار برایتان ثبت شده، این دستورها را به ربات ترونادو بفرستید. برای تست روی localhost یک آدرس عمومی (external url) بسازید و در CallbackUrl قرار دهید.

**ارسال یک IPN تستی ثابت**

```text
/dummyrequest <your_callback_url>
```

**ارسال یک IPN تستی با داده‌ی دلخواه**

```text
/dummysuccessfulrequest {
  "PaymentID": "12345",
  "UserTelegramId": 123456,
  "Wallet": "Wallet",
  "TronAmount": 12.123456,
  "ActualTronAmount": 12.123456,
  "CallbackUrl": "https://your-tunnel.example.com/Test/Test"
}
```

## پشتیبانی

برای دریافت API Key، ثبت دامنه‌ی callback، تنظیم درصد کارمزد یا هر سوال دیگری با پشتیبانی ترونادو در ارتباط باشید.
