# المحافظ الثابتة

> عناوين إيداع دائمة مرتبطة بطلب أو مستخدم معيّن، مثالية للمدفوعات المتكررة وطويلة الأمد.

المحافظ الثابتة هي عناوين دائمة لاستلام مدفوعات العملات المشفرة. ترتبط بـ `order_id` معيّن وتكون فريدة بمجموع `project_id + order_id + currency + network`.

استخدم المحافظ الثابتة من أجل:

- الإيداعات المتكررة من نفس المستخدم
- عناوين دفع طويلة الأمد تُعرض على الملف الشخصي للمستخدم
- تدفقات إيداع كبيرة الحجم حيث تريد عنوانًا ثابتًا لكل مستخدم

## إنشاء محفظة ثابتة

`POST /v1/static-wallet`

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

| الحقل | النوع | مطلوب | الوصف |
|-------|------|----------|-------------|
| `currency` | string | نعم | العملة المشفرة (USDT، BTC، ETH، إلخ.) |
| `network` | string | نعم | رمز الشبكة |
| `order_id` | string | نعم | معرّف الطلب/المستخدم الخاص بك (حتى 255 حرفًا) |
| `label` | string | لا | تسمية المحفظة (حتى 255 حرفًا) |
| `url_callback` | string | نعم | عنوان URL لإشعارات webhook |
| `invite_code` | string | لا | رمز المُحيل |

### مثال على الطلب

```json
{
  "currency": "USDT",
  "network": "TRX-TRC20",
  "order_id": "USER-123",
  "label": "User deposit #123",
  "url_callback": "https://your-site.com/webhook/static"
}
```

### مثال على الاستجابة

```json
{
  "state": 0,
  "result": {
    "uuid": "019b2265-34d8-7001-a230-8f97de90d481",
    "address": "TXYZabc123...",
    "currency": "USDT",
    "network": "TRX-TRC20",
    "label": "User deposit #123",
    "order_id": "USER-123",
    "status": "active",
    "url": "https://go.2328.io/static/019b2265-34d8-7001-a230-8f97de90d481",
    "created_at": "2026-01-20T12:00:00Z",
    "qr": "data:image/png;base64,iVBORw0..."
  }
}
```

## معلومات المحفظة

احصل على معلومات المحفظة الثابتة بواسطة `uuid` أو `address`.

`POST /v1/static-wallet/info`

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

| الحقل | النوع | مطلوب | الوصف |
|-------|------|----------|-------------|
| `uuid` | string | نعم* | معرّف المحفظة الثابتة UUID |
| `address` | string | نعم* | عنوان البلوكتشين للمحفظة |

> **INFO:** يجب توفير واحد على الأقل من `uuid` أو `address`.

### مثال على الاستجابة

```json
{
  "state": 0,
  "result": {
    "uuid": "019b2265-34d8-7001-a230-8f97de90d481",
    "address": "TXYZabc123...",
    "currency": "USDT",
    "network": "TRX-TRC20",
    "status": "active",
    "total_received": "1250.50",
    "transactions_count": 3,
    "created_at": "2026-01-20T12:00:00Z",
    "qr": "data:image/png;base64,iVBORw0..."
  }
}
```

- `total_received` — مجموع جميع الإيداعات المستلمة بهذه المحفظة، بـ `currency`.
- `transactions_count` — عدد الإيداعات المستلمة حتى الآن.
- `qr` — رمز QR مُرمَّز بـ Base64 (data URI) لعنوان الإيداع (موجود دائمًا للمحافظ الثابتة، حيث يتم تعيين العنوان عند الإنشاء).

## قائمة المحافظ

`POST /v1/static-wallet/list`

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

| الحقل | النوع | مطلوب | الوصف |
|-------|------|----------|-------------|
| `status` | string | لا | تصفية حسب الحالة (`active`، `inactive`) |
| `currency` | string | لا | تصفية حسب العملة |
| `network` | string | لا | تصفية حسب الشبكة |
| `order_id` | string | لا | تصفية حسب order_id |
| `page` | int | لا | رقم الصفحة (الافتراضي: 1) |
| `per_page` | int | لا | عدد العناصر لكل صفحة (الافتراضي: 20، الحد الأقصى: 100) |

### مثال على الاستجابة

```json
{
  "state": 0,
  "result": {
    "items": [
      {
        "uuid": "019b2265-...",
        "address": "TXYZabc123...",
        "currency": "USDT",
        "network": "TRX-TRC20",
        "status": "active",
        "total_received": "1250.50",
        "transactions_count": 3
      }
    ],
    "paginate": {
      "count": 1,
      "current_page": 1,
      "per_page": 20,
      "total": 1,
      "total_pages": 1,
      "has_more": false
    }
  }
}
```

## تفعيل / تعطيل المحفظة

تبديل ما إذا كانت المحفظة الثابتة تقبل مدفوعات جديدة.

`POST /v1/static-wallet/disable`

`POST /v1/static-wallet/enable`

### الطلب

تأخذ كلتا نقطتي النهاية معاملًا واحدًا:

```json
{
  "uuid": "019b2265-34d8-7001-a230-8f97de90d481"
}
```

### مثال على الاستجابة

```json
{
  "state": 0,
  "result": {
    "uuid": "019b2265-34d8-7001-a230-8f97de90d481",
    "status": "inactive",
    "message": "Static wallet disabled successfully"
  }
}
```

بالنسبة لـ `enable`، تكون `status` هي `"active"` وتكون `message` هي `"Static wallet enabled successfully"`.

## معاملات المحفظة

احصل على قائمة بجميع الإيداعات المستلمة بمحفظة ثابتة.

`POST /v1/static-wallet/transactions`

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

| الحقل | النوع | مطلوب | الوصف |
|-------|------|----------|-------------|
| `uuid` | string | نعم | معرّف المحفظة الثابتة UUID |
| `date_from` | date | لا | تاريخ البداية (YYYY-MM-DD) |
| `date_to` | date | لا | تاريخ النهاية (YYYY-MM-DD) |
| `page` | int | لا | رقم الصفحة (الافتراضي: 1) |
| `per_page` | int | لا | عدد العناصر لكل صفحة (الافتراضي: 15، الحد الأقصى: 5000) |

### مثال على الاستجابة

```json
{
  "state": 0,
  "result": {
    "items": [
      {
        "uuid": "abc123-def456-...",
        "order_id": "USER-123",
        "amount": "100.00",
        "currency": "USDT",
        "payment_status": "paid",
        "txid": "0xabc123def456...",
        "fee_amount": "3.00",
        "net_amount": "97.00",
        "created_at": "2026-01-20T15:30:00Z"
      }
    ],
    "paginate": {
      "count": 1,
      "hasPages": true,
      "perPage": 15,
      "page": 1
    }
  }
}
```

- `fee_amount` — رسوم المنصة المخصومة من هذا الإيداع، بـ `currency`.
- `net_amount` — المبلغ المُضاف إلى رصيد التاجر بعد الرسوم.

## webhooks المحافظ الثابتة

عند استلام دفعة على محفظة ثابتة، يرسل النظام webhook إلى `url_callback`.

> **WARNING:** يختلف تنسيق webhook للمحافظ الثابتة عن webhooks المدفوعات العادية. الجدير بالذكر أن webhooks المحافظ الثابتة تتضمن حقل `merchant_amount` الذي يجب استخدامه للإيداع.

### محتوى webhook

```json
{
  "uuid": "a28b293f-5c76-4053-8062-ae9ca4ab784b",
  "order_id": "USER-7666308594",
  "amount": "10.00000000",
  "currency": "USDT",
  "amount_usd": "10.00000000",
  "exchange_rate": "1.00000000",
  "payer_currency": "USDT",
  "payer_amount": "10.00000000",
  "network": "TRX-TRC20",
  "address": "TMU9Tgpchvgbywkbj5SdC8KJS73t5m3M7G",
  "payment_status": "paid",
  "txid": "8369ede26a0da05b1bae154b4bb4072eb2453db30ba86b21831902670929454f",
  "tx_explorer_url": "https://tronscan.org/#/transaction/8369ede26a0da05b1bae154b4bb4072eb2453db30ba86b21831902670929454f",
  "payment_amount": "10.00000000",
  "merchant_amount": "9.920000000000000000",
  "created_at": "2026-05-09T16:13:04+03:00",
  "sign": "dd958d1405febce670a9a196e9141784b9f2a5f39cd6d1832d6f3f68d0de1e10"
}
```

> **INFO:** webhooks المحافظ الثابتة **لا تتضمن** `url` أو `expires_at` (لأن العنوان دائم، وليس جلسة). لكنها **تتضمن** `exchange_rate` و`created_at`.

### مرجع الحقول

| الحقل | النوع | الوصف |
|-------|------|-------------|
| `uuid` | string | معرّف المعاملة (الفاتورة) UUID لهذا الإيداع |
| `order_id` | string | `order_id` الخاص بمحفظتك الثابتة |
| `amount` | decimal (8 dp) | مبلغ العملة المشفرة المستلم |
| `currency` | string | العملة المشفرة المستلمة (تطابق `currency` للمحفظة) |
| `amount_usd` | decimal (8 dp) | القيمة بالدولار الأمريكي وقت الاستلام |
| `exchange_rate` | decimal | سعر صرف العملة المشفرة / الدولار المستخدم |
| `payer_currency` | string | نفس `currency` للمحافظ الثابتة |
| `payer_amount` | decimal (8 dp) | نفس `amount` للمحافظ الثابتة |
| `network` | string | شبكة البلوكتشين |
| `address` | string | عنوان المحفظة الثابتة |
| `payment_status` | string | ???? ??????? ???????? ???? ????? `paid`? ??? ???? ??? AML ???? `aml_lock` ???? ?? ???? ????? ???????? |
| `txid` | string | هاش معاملة البلوكتشين |
| `tx_explorer_url` | string \| null | رابط المعاملة في مستكشف البلوكشين. تكون القيمة `null` عند عدم وجود `txid` أو عندما يكون التحويل داخليًا بنظام P2P. |
| `payment_amount` | decimal (8 dp) | نفس `amount` |
| `merchant_amount` | decimal (18 dp) | **المبلغ بعد خصم الرسوم** — استخدمه للإيداع |
| `created_at` | string (ISO 8601) | متى تم استلام الإيداع |
| `sign` | string (hex) | توقيع HMAC-SHA256 للمحتوى |

## أفضل الممارسات

- **`order_id` فريد** — استخدم `order_id` فريدًا لكل مستخدم أو طلب
- **Idempotency** — تحقق من `txid` قبل المعالجة لتجنب الإيداعات المكررة
- **التحقق من التوقيعات** — تحقق دائمًا من توقيع `sign` قبل إيداع الأموال
- **استخدم `merchant_amount`** — أضف للمستخدمين على أساس `merchant_amount`، وليس `payment_amount`

## دورة الحياة وعدم التغيير عند التكرار

المحفظة الثابتة هي هوية إيداع قابلة لإعادة الاستخدام، وليست فاتورة. ليس لديها مبلغ متوقع ولا تاريخ انتهاء. يمكن أن تنتج عنوان واحد أي عدد من المعاملات الإيداعية خلال فترة حياته.

الإنشاء لا يتغير عند التكرار لنفس مشروع التاجر، `order_id`، `currency`، و`network`: يتم إرجاع المحفظة الموجودة. احرص على ثبات هذا الزوج واستمر في المحفظة المعادة `uuid`؛ لا تستخدم `order_id` جديدًا في كل مرة يفتح فيها نفس العميل شاشة الإيداع.

عدم التغيير عند التكرار للإيداع يختلف عن عدم التغيير عند التكرار للمحفظة:

- `order_id` يحدد التوافق بين المحفظة القابلة لإعادة الاستخدام والعميل؛
- `uuid` للمحفظة يحدد سجل المحفظة الدائم؛
- الويب هوك `uuid` يحدد عملية إيداع مكتشفة واحدة;
- `txid` يحدد التحويل على السلسلة ويعتبر مفتاح التكرار الأساسي لمنح الرصيد.

استخدم قيد فريد في قاعدة البيانات لهوية السلسلة/الشبكة/معرف المعاملة المعالجة وادعِ ذلك في نفس المعاملة التي تخص رصيد العميل الداخلي.

## تمكين وتعطيل الدلالات

إيقاف المحفظة يمنع التطبيق من معالجتها كهدف إيداع نشط؛ لا يمحو العنوان أو تاريخه ولا يمكنه إيقاف تحويل على البلوكشين تم إرساله بالفعل من قبل المستخدم.

> **DANGER:** لا تخبر المستخدمين أبدًا أن الأموال المرسلة إلى عنوان غير نشط يتم إرجاعها تلقائيًا. التحويلات عبر البلوكشين لا يمكن عكسها. قم بالتعطيل فقط بعد إزالة العنوان من واجهة المستخدم الخاصة بك، واحتفظ بإجراء استعادة عملي للإيداعات المتأخرة.

إعادة التمكين تحافظ على نفس هوية المحفظة والعنوان. لا تنشئ بديلاً لمجرد تغيير التسمية؛ التسمية ليست معرفًا للتسوية.

## حالات حافة المحفظة الثابتة

| الوضع | المعاملة الصحيحة |
|-----------|------------------|
| طلب إنشاء مكرر | اقبل المحفظة الموجودة المُعادة وتحقق من الثنائي المخزن لها بدلاً من توقع عنوان جديد. |
| إيداعات متعددة إلى عنوان واحد | قم بإنشاء صف إيداع محلي منفصل لكل معاملة `uuid`/`txid`؛ لا تقم أبدًا بوضع علامة على المحفظة نفسها بأنها "مدفوعة". |
| نسخة ويب هوك مكررة | إرجاع HTTP 200 بعد العثور على txid الذي تم تأكيده بالفعل؛ لا تقم بإضافة رصيد مرة أخرى. |
| تأخير التأكيد أو إعادة ملاحظة السلسلة | حافظ على معالجة غير متغيرة وقم بالتسوية من `/v1/static-wallet/transactions`. |
| إيداع أقل من الحد الأدنى للتحويل التلقائي | توقع رصيد العملة المصدر بدون إكمال بلوك `convert`. |
| نجاح التحويل التلقائي | تخزين قيم الدفع المصدرية ونتيجة `convert` الهدف بشكل منفصل. |
| رمز خاطئ أو شبكة خاطئة | لا تُزيّف أي رصيد. سجّل الأدلة وارتقِ بالأمر إلى الدعم/الاسترداد لأن القدرة على الاسترداد تعتمد على السلسلة. |
| سلسلة قائمة على المذكرة/الوسم | اعرض وتحقق من كل حقل وجهة يتم إرجاعه من المنصة؛ قد لا يكون العنوان وحده كافيًا عند الحاجة إلى مذكرة. |
| قفل مكافحة غسيل الأموال | لا تمنح الرصيد للمستخدم النهائي حتى يتم إصدار الحالة الرسمية من خلال عملية الامتثال. |
| تم تعطيل المحفظة بعد عرض العنوان | أزلها من واجهة المستخدم فورًا، ولكن واصل مراقبة تنبيهات العمليات للتحويلات المتأخرة. |

## نموذج المطابقة

قم بتشغيل وظيفة دورية تتصفح `/v1/static-wallet/transactions`، وتقوم بإجراء تحديث أو إدراج للودائع حسب txid، وتقارن بين `merchant_amount`، والحالة، ونتيجة التحويل الاختيارية مع دفتر الحسابات الداخلي الخاص بك. يجب أن تجعل تسليم الويب هوك عملية المطابقة سريعة، ولكن يجب أن تجعل عملية المطابقة مكتملة.