# Convert API

> حوّل بين العملات الرقمية مباشرة من رصيد متجرك — احصل على سعر مباشر ونفّذ بسعر السوق.

تتيح لك Convert API التحويل بين العملات الموجودة في رصيد متجرك بسعر السوق الحالي — نفس المحرك الذي يشغّل تبويب **Swap** في لوحة تحكم المتجر، وأصبح الآن متاحًا من خلال الخادم الخلفي الخاص بك.

> **WARNING:** تُوقَّع نقاط نهاية Convert باستخدام **مفتاح API العادي** الخاص بك — نفس المفتاح المستخدم في طلبات [Payment API](/docs/payments)، **وليس** مفتاح Payout API. تنفيذ عملية تحويل يخصم ويضيف إلى رصيد متجرك فورًا، لذا تعامل مع هذا المفتاح بنفس الحذر الذي تتعامل به مع أي بيانات اعتماد تحرّك الأموال.

## الحصول على سعر التحويل

يعيد سعرًا إرشاديًا لعملية تحويل بسعر السوق الحالي — السعر الفعلي والمبالغ الناتجة. لا يتم خصم أو حجز أي شيء؛ استدعِه بقدر ما تحتاج قبل التنفيذ.

`POST /v1/convert/price`

### معاملات الطلب

| الحقل | النوع | مطلوب | الوصف | القيمة |
|-------|------|-------|-------|--------|
| `from_currency` | string | نعم | العملة المصدر | `BTC`, `ETH`, `USDT`, `USDC`, `TRX`, `BNB`, `GRAM`, `SOL`, `POL`, `LTC`, `DASH`, `DOGE`, `ZEC`, `XRP`, `XMR` |
| `to_currency` | string | نعم | العملة الهدف. يجب أن تختلف عن `from_currency` | `USDT`, `USDC`, `BTC`, `ETH`, `TRX`, `BNB`, `GRAM`, `SOL`, `POL`, `LTC`, `DASH`, `DOGE`, `ZEC`, `XRP`, `XMR` |
| `amount` | decimal | نعم | المبلغ المراد تحويله، أكبر من `0` |  |
| `amount_type` | string | نعم | إلى أي جانب يشير `amount` | `from`, `to` |

> **INFO:** تعني `amount_type=from` إنفاق `amount` بالضبط من `from_currency`. وتعني `amount_type=to` استلام `amount` بالضبط من `to_currency`.

**🟢 200 OK** · `application/json`

```json
{
  "state": 0,
  "result": {
    "success": true,
    "from_currency": "BTC",
    "to_currency": "USDT",
    "amount_type": "from",
    "from_amount": "0.01000000",
    "to_amount": "947.86690000",
    "effective_rate": "94786.69000000",
    "from_amount_usd": "947.87",
    "to_amount_usd": "947.87"
  }
}
```

#### حقول الاستجابة

| الحقل | النوع | الوصف |
|-------|------|-------|
| `success` | boolean | ما إذا كان حساب السعر قد نجح |
| `from_currency` | string | العملة المصدر |
| `to_currency` | string | العملة الهدف |
| `amount_type` | string | يعكس `amount_type` من الطلب |
| `from_amount` | string | المبلغ الذي سيُخصم بعملة `from_currency` |
| `to_amount` | string | المبلغ الذي سيُضاف بعملة `to_currency` |
| `effective_rate` | string | السعر المطبَّق على هذا العرض — وحدة واحدة من `from_currency` بعملة `to_currency` (يشمل بالفعل تسعير المنصة) |
| `from_amount_usd` | string \| null | ما يعادل `from_amount` بالدولار الأمريكي |
| `to_amount_usd` | string \| null | ما يعادل `to_amount` بالدولار الأمريكي |

- هذا السعر **إرشادي فقط** — قد يتغيّر سعر السوق بين طلب السعر واستدعاء التنفيذ.
- لا يخصم أو يحجز هذا الاستدعاء أي رصيد.

> Use your project UUID and the endpoint-appropriate API key from the merchant dashboard.

#### Interactive request: `POST /v1/convert/price`
  - `from_currency` (enum, required): BTC,ETH,USDT,USDC,TRX,BNB,GRAM,SOL,POL,LTC,DASH,DOGE,ZEC,XRP,XMR
  - `to_currency` (enum, required): USDT,USDC,BTC,ETH,TRX,BNB,GRAM,SOL,POL,LTC,DASH,DOGE,ZEC,XRP,XMR
  - `amount` (decimal, required)
  - `amount_type` (enum, required): from,to

## تنفيذ التحويل

ينفّذ عملية تحويل بسعر السوق الحالي ويحدّث رصيد متجرك. لا توجد خطوة منفصلة "لتأكيد السعر" — استدعِ هذه النقطة مباشرة بالمبلغ الذي تريد تحويله.

`POST /v1/convert`

> **INFO:** **التكرار الآمن (Idempotency).** تكرار نفس الطلب تمامًا (نفس `from_currency` و`to_currency` و`amount` و`amount_type`) خلال دقيقة تقريبًا من الاستدعاء الأول يعيد عملية التحويل الموجودة بدلاً من إنشاء عملية ثانية. بعد انتهاء هذه المدة، يُعامَل الطلب المطابق كعملية تحويل جديدة — لا تُعِد المحاولة عشوائيًا عند انتهاء المهلة دون التحقق أولًا من نتيجة الاستدعاء السابق.

> **WARNING:** تقتصر هذه النقطة على **10 طلبات في الدقيقة** لكل جهة استدعاء — وهو حدّ أكثر صرامة من حدّ الطلبات العام في الـ API — لأن كل استدعاء يحرّك رصيدًا حقيقيًا.

### معاملات الطلب

| الحقل | النوع | مطلوب | الوصف | القيمة |
|-------|------|-------|-------|--------|
| `from_currency` | string | نعم | العملة المصدر | `BTC`, `ETH`, `USDT`, `USDC`, `TRX`, `BNB`, `GRAM`, `SOL`, `POL`, `LTC`, `DASH`, `DOGE`, `ZEC`, `XRP`, `XMR` |
| `to_currency` | string | نعم | العملة الهدف. يجب أن تختلف عن `from_currency` | `USDT`, `USDC`, `BTC`, `ETH`, `TRX`, `BNB`, `GRAM`, `SOL`, `POL`, `LTC`, `DASH`, `DOGE`, `ZEC`, `XRP`, `XMR` |
| `amount` | decimal | نعم | المبلغ المراد تحويله، أكبر من `0` |  |
| `amount_type` | string | نعم | إلى أي جانب يشير `amount` | `from`, `to` |

**🟢 200 OK** · `application/json`

```json
{
  "state": 0,
  "result": {
    "id": 12345,
    "type": "manual",
    "status": "completed",
    "from_currency": "BTC",
    "to_currency": "USDT",
    "from_amount": "0.01000000",
    "requested_from_amount": "0.01000000",
    "refund_amount": null,
    "to_amount": "947.86690000",
    "exchange_rate": "94786.69000000",
    "fee_amount": "0.00000000",
    "from_amount_usd": "947.87",
    "to_amount_usd": "947.87",
    "processed_at": "2026-01-20T15:30:24Z",
    "created_at": "2026-01-20T15:30:22Z"
  }
}
```

#### حقول الاستجابة

| الحقل | النوع | الوصف |
|-------|------|-------|
| `id` | int | معرّف طلب التحويل المخصَّص من النظام |
| `type` | string | دائمًا `manual` في هذه الـ API |
| `status` | string | الحالة الحالية (انظر «حالات التحويل» أدناه) |
| `from_currency` | string | العملة المصدر |
| `to_currency` | string | العملة الهدف |
| `from_amount` | string | المبلغ المخصوم بعملة `from_currency` |
| `requested_from_amount` | string \| null | مبلغ المصدر الذي طلبته أصلًا عندما تكون `amount_type = from`. تكون `null` عندما تكون `amount_type = to` |
| `refund_amount` | string \| null | الجزء من المبلغ المخصوم مسبقًا الذي أُعيد إليك بعد تنفيذ جزئي. تكون `null` إذا اكتمل الطلب بالكامل |
| `to_amount` | string | المبلغ المضاف بعملة `to_currency` |
| `exchange_rate` | string | السعر المطبَّق فعليًا على هذا التحويل — وحدة واحدة من `from_currency` بعملة `to_currency` (يشمل بالفعل تسعير المنصة) |
| `fee_amount` | string | رسوم المنصة المفروضة على هذا التحويل، بعملة `from_currency` أو `to_currency` حسب اتجاه العملية. مُدرَجة بالفعل ضمن `exchange_rate` — تُعرض هنا لأغراض الشفافية |
| `from_amount_usd` | string \| null | ما يعادل `from_amount` بالدولار الأمريكي |
| `to_amount_usd` | string \| null | ما يعادل `to_amount` بالدولار الأمريكي |
| `processed_at` | string (ISO 8601) \| null | وقت انتهاء تنفيذ التحويل. تكون `null` أثناء المعالجة |
| `created_at` | string (ISO 8601) | وقت إنشاء طلب التحويل |

#### حالات التحويل

| الحالة | الوصف |
|--------|-------|
| `pending` | تم الإنشاء، لم يُرسَل بعد إلى السوق |
| `processing` | الرصيد مُقفَل والطلب موضوع في السوق |
| `completed` | تم التنفيذ بالكامل — أُضيف `to_amount` إلى رصيدك |
| `failed` | تعذّر التنفيذ — أُعيد أي مبلغ مخصوم مسبقًا تلقائيًا |
| `partially_completed` | لأزواج العملات التي لا يوجد لها سوق مباشر فقط (يتم توجيهها عبر عملة وسيطة): اكتملت المرحلة الأولى لكن فشلت الثانية. تُضاف إليك العملة الوسيطة بدلاً من `to_currency` — أعِد التحويل منها للوصول إلى هدفك الأصلي |

#### Interactive request: `POST /v1/convert`
  - `from_currency` (enum, required): BTC,ETH,USDT,USDC,TRX,BNB,GRAM,SOL,POL,LTC,DASH,DOGE,ZEC,XRP,XMR
  - `to_currency` (enum, required): USDT,USDC,BTC,ETH,TRX,BNB,GRAM,SOL,POL,LTC,DASH,DOGE,ZEC,XRP,XMR
  - `amount` (decimal, required)
  - `amount_type` (enum, required): from,to

## الأخطاء

عند الفشل، تحتوي الاستجابة على `state: 1` وقيمة `error_code` — مشتركة بين `/v1/convert/price` و`/v1/convert`:

**🔴 422 / 400** · `application/json`

```json
{
  "state": 1,
  "error_code": "amount_too_small",
  "errors": {
    "amount": "Amount is too small for this conversion. Please increase the amount and try again."
  }
}
```

| `error_code` | حالة HTTP | الوصف |
|--------------|-----------|-------|
| `validation_failed` | 422 | معاملات غير صالحة أو مفقودة، أو رفض بسبب قاعدة عمل (مثل عدم كفاية الرصيد) — راجع الحقل `errors` للتفاصيل |
| `amount_too_small` | 422 | `amount` أقل من الحد الأدنى القابل للتداول لهذا الزوج من العملات |
| `convert_unavailable` | 400 | تعذّر تنفيذ التحويل في الوقت الحالي (بيانات السوق غير متاحة أو لا يوجد مسار بين العملتين) — أعِد المحاولة بعد قليل |
| `internal_error` | 400 | خطأ داخلي غير متوقّع في الخادم أثناء معالجة الطلب |

## التحويل التلقائي للدفعات الواردة

التحويل التلقائي هو إعداد مشروع للفواتير الواردة والاعتمادات الثابتة في المحفظة. يتم تكوينه في لوحة تحكم التاجر، وليس عن طريق إضافة حقول إلى `/v1/payment`. كل قاعدة تختار عملة أو أكثر كمصدر وعملة مستهدفة.

عند اكتمال التحويل، يمكن أن تتضمن معلومات الدفع وويب هوكات التاجر:

```json
{
  "payment_amount": "0.14800000",
  "merchant_amount": "0.146520000000000000",
  "payer_currency": "XMR",
  "convert": {
    "to_currency": "USDT",
    "commission": "0.09000000",
    "rate": "323.21000000",
    "amount": "47.262015740000000000"
  }
}
```

مجالات المبالغ منفصلة عن قصد:

- `payment_amount` — ما تم اكتشافه على السلسلة في عملة الدفع المصدر؛
- `merchant_amount` — صافي المبلغ المصدر المنسوب للتاجر قبل التحويل؛
- `convert.amount` — المبلغ المعتمد في `convert.to_currency`;
- `convert.rate` و `convert.commission` — نتيجة التحويل المنفذة، وليست سعرًا يجب عليك إعادة حسابه محليًا.

> **WARNING:** غياب `convert` ذو معنى: قد لا يكون التحويل قد اكتمل، أو قد لا يكون مهيأً لهذا المصدر، أو قد يكون قد عاد إلى رصيد العملة المصدر. لا تبتكر أبدًا مبلغًا مستهدفًا من `/exchange-rates` أو من سعر السوق العام.

### فشل التحويل التلقائي والعودة إلى

التحويل يحدث بعد استلام الدفع عبر البلوكشين. توافر السوق، الحد الأدنى لأحجام الطلبات، حدود الدقة، انتهاء مهلة التبادل، ونقص السيولة القابلة للتنفيذ يمكن أن تؤخر أو تمنع التحويل.

- الإيداعات التي تقل عن الحد الأدنى العالمي/المشروع تتجاوز خط تحويل العملات وتُعَّد إلى رصيد العملة المصدر.
- يمكن إعادة محاولة الإخفاقات المؤقتة بشكل غير متزامن.
- يمكن أن تعود الودائع الكبيرة أو غير القابلة للتداول إلى رصيد عملة المصدر بعد نفاد سياسة إعادة المحاولة.
- لذلك يمكن أن تكون عملية الدفع صالحة حتى إذا لم يحدث تحويل العملة المستهدفة المطلوب.

يجب على تكاملك الاحتفاظ بالدفع الذي تم التحقق منه أولاً، ثم التسوية مع العملة الفعلية المضافة إلى الحساب من معلومات الدفع، وكتلة `convert` الاختيارية، وأرصدة التاجر. لا تمنع تأكيد webhook الخاص بالدفع أثناء الانتظار على تحليلاتك أو أنظمة الإشعارات الخاصة بك.

### اختبارات قبول التحويل التلقائي

اختبر على الأقل: التحويل المباشر الناجح، التحويل عبر جسر/متعدد القفزات، الغبار أدنى الحد الأدنى، إعادة المحاولة العابرة، العودة إلى العملة المصدر، الدفع الناقص، الدفع الزائد، الويب هوك المكرر، فقدان `convert`، والمصالحة بعد مهلة غامضة.

## حالات الحافة للتحويل اليدوي

- `/v1/convert/price` هو معاينة إرشادية؛ قد يغير تحرك السوق نتيجة التنفيذ.
- `amount_type: from` يصلح طلب الجانب المصدر، بينما يطلب `amount_type: to` مبلغ الجانب الهدف. لا تقم بعكس المعنى عند عرض واجهة تأكيد.
- يمكن توجيه زوج بدون سوق مباشر من خلال عملة وسيطة. إذا تم إكمال ساق واحدة فقط، يقوم `partially_completed` بالإبلاغ عن الائتمان الوسيط.
- إذا انتهت مهلة استدعاء التنفيذ، قم بالمصالحة قبل إعادة المحاولة. يمكن لأمر السوق أن ينفذ حتى عندما يتم فقدان استجابة HTTP الخاصة به.
- عامل `failed` كحالة للمصالحة، وليس كإذن لتطبيق إدخال رصيد تعويضي محلي؛ المنصة هي المالكة لمحاسبة الخصم/الإرجاع.