وصل

وثائق المطورين

اربط أنظمتك بوصل عبر REST API وWebhooks. أنشئ مفتاحاً من الإعدادات ← التكاملات وابدأ خلال دقائق.

1. نظرة عامة

وصل يوفّر واجهة REST تحت https://api.wasl.nami-lab.com/api/v1 لسحب العملاء والتحويلات والفواتير، بالإضافة إلى Webhooks تدفع الأحداث إلى خادمك عند التحقق من تحويل أو دفع فاتورة أو رفع تنبيه.

  • اسحب البيانات عبر مفتاح API (server-to-server).
  • ادفع صور التحويلات عبر رابط رفع موقّع + تسجيل لبدء تشغيل OCR تلقائياً.
  • استقبل الأحداث عبر Webhook موقّع على عنوانك.
  • المبالغ تُرسل كـ amountMinor (أصغر وحدة عملة، نصّية لتجنّب Overflow).

2. المصادقة

من لوحة التحكم: الإعدادات ← التكاملات ← أنشئ مفتاحاً. المفتاح الكامل يظهر مرة واحدة فقط ويبدأ بـ wsl_.

أرسله في كل طلب:

http
Authorization: Bearer wsl_…

المفتاح يعمل بصلاحيات المالك على مستوى المؤسسة. لا تضعه في تطبيقات الموبايل أو الواجهة الأمامية — خزّنه في الخادم فقط. يمكنك إلغاؤه فوراً من نفس الصفحة.

الصلاحيات (Scopes)

كل مفتاح API يحمل مجموعة صلاحيات فرعية. اختر أقل صلاحية تكفي للتكامل:

  • read — كل مسارات GET فقط. آمن للتكاملات القرائية (لوحات، ملخصات).
  • notifications:write — رفع صور التحويلات، مراجعتها، وتأكيدها.
  • invoices:write — إنشاء وتعديل الفواتير والعملاء والاستردادات.

المفاتيح القديمة (قبل يوم Sprint 35) تعامَل كأنها تحمل كل الصلاحيات. الرد على طلب بصلاحية ناقصة: 403 API key missing required scope.

3. الاصطلاحات

الترقيم (Pagination)

كل مسارات القوائم تدعم page (يبدأ من 1) وpageSize (افتراضي 20، أقصى 100). الرد بالشكل التالي:

json
{
  "data": [ /* … page of rows … */ ],
  "page": 1,
  "pageSize": 20,
  "total": 143,
  "totalPages": 8,
  "hasNext": true,
  "hasPrev": false
}

المبالغ والعملات

كل الحقول النقدية بصيغة amountMinor نصّية بأصغر وحدة (قروش). أرسل currency بالكود ISO-4217 — المدعوم حالياً: SDG وUSD.

التواريخ والوقت

كل التواريخ ISO-8601 بتوقيت UTC. اعرضها بتوقيت Africa/Khartoum لمستخدميك.

معرّفات الموارد

المعرّفات كلها بصيغة cuid نصّية. لا تخزّنها كأرقام.

Idempotency-Key

في الاتصالات الضعيفة، الطلب قد يوصل مرتين. مرّر رأس Idempotency-Key على كل طلب POST إنشاء — وصل يحفظ الرد لأول محاولة ناجحة (لمدة 24 ساعة) ويعيده كما هو لأي محاولة تحمل نفس المفتاح ونفس الحمولة:

bash
curl -s -X POST "https://api.wasl.nami-lab.com/api/v1/invoices" \
  -H "Authorization: Bearer wsl_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-4711" \
  -d '{ "customerId": "clx…", "items": [ … ] }'

المسارات المدعومة حالياً: POST /invoices، POST /invoices/:id/refunds، POST /customers، POST /uploads/register، POST /public-receipts/notifications/:id. المفتاح نفسه مع حمولة مختلفة يرجع 409 Idempotency-Key reused with a different request payload.

4. أهم المسارات

كل المسارات تحت /api/v1. أمثلة شائعة:

التحويلات (الإشعارات)

GET /notifications — قائمة التحويلات مع تصفية حسب الحالة، الفرع، العميل، والتاريخ.

bash
curl -s "https://api.wasl.nami-lab.com/api/v1/notifications?status=VERIFIED&pageSize=20" \
  -H "Authorization: Bearer wsl_YOUR_API_KEY" \
  -H "Accept: application/json"

العملاء

GET /customers · POST /customers · GET /customers/:id · حسابات بنك العميل عبر /customers/:id/bank-accounts

bash
curl -s -X POST "https://api.wasl.nami-lab.com/api/v1/customers" \
  -H "Authorization: Bearer wsl_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "محل النور",
    "phone": "+249900000000"
  }'

الفواتير

GET /invoices · POST /invoices · GET /invoices/:id · ربط التحويلات عبر POST /invoices/:id/link · فكّ الربط عبر DELETE /invoices/:id/link/:transferId · استرداد جزئي عبر POST /invoices/:id/refunds

bash
curl -s "https://api.wasl.nami-lab.com/api/v1/invoices/{invoiceId}" \
  -H "Authorization: Bearer wsl_YOUR_API_KEY" \
  -H "Accept: application/json"

موارد أخرى

  • GET /branches — الفروع
  • GET /branch-groups · POST /branch-groups — مجموعات الفروع حسب النشاط (باقة المؤسسات، ميزة chain.rollup)
  • GET /branch-groups/:id/overview · /leaderboard · /timeseries — لوحة مبيعات المجموعة
  • GET /banks · GET /banks/tree — سجل البنوك السودانية
  • GET /recurring-invoices — قوالب الفواتير الدورية
  • GET /analytics/summary · تقارير/analytics/*
  • POST /reports/preview · POST /reports/export
  • GET /reconciliation/unlinked-transfers · /reconciliation/suggestions

5. رفع صور التحويلات

لدفع صور من نظامك (POS، واتساب بوت، …) استخدم عملية من خطوتين: اطلب رابط رفع موقّع، ارفع الصورة، ثم سجّلها لتشغيل OCR.

1) اطلب رابط الرفع

bash
curl -s -X POST "https://api.wasl.nami-lab.com/api/v1/uploads/sign" \
  -H "Authorization: Bearer wsl_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "receipt.jpg",
    "mimeType": "image/jpeg",
    "size": 812345
  }'

الرد يحتوي على uploadUrl (رابط PUT مباشر) وobjectKey.

2) ارفع الصورة مباشرة

bash
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: image/jpeg" \
  --data-binary "@receipt.jpg"

3) سجّل الرفع

bash
curl -s -X POST "https://api.wasl.nami-lab.com/api/v1/uploads/register" \
  -H "Authorization: Bearer wsl_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "objectKey": "org_abc/receipts/2026-08-16/receipt.jpg",
    "bankId": null,
    "branchId": null
  }'

الرد يُرجع notificationId. تتبّع الحالة عبر GET /notifications/:id أو بانتظار حدث transfer.verified عبر webhook.

6. حسابات الاستقبال

لبناء صفحة “حوّل لنا” في تطبيقك، اسحب حسابات مؤسستك عبر:

bash
curl -s "https://api.wasl.nami-lab.com/api/v1/org-bank-accounts" \
  -H "Authorization: Bearer wsl_YOUR_API_KEY" \
  -H "Accept: application/json"

كل حساب يحمل اسم البنك، رقم/مالك الحساب، وisActive. اعرض المفعّلة فقط لعملائك.

وصل يمنحك روابط عامة تحمل توقيعك وتُشاركها مع عميلك عبر واتساب أو SMS. لا تحتاج إلى جلسة أو مفتاح لفتحها.

رابط إيصال لتحويل مؤكد

bash
curl -s -X POST "https://api.wasl.nami-lab.com/api/v1/public-receipts/notifications/{notificationId}" \
  -H "Authorization: Bearer wsl_YOUR_API_KEY"

الرد يُرجع token. الرابط العام: https://api.wasl.nami-lab.com/r/{token}. لإلغاء كل الروابط دفعة واحدة، استعمل DELETE /public-receipts/notifications/:id.

رابط صفحة دفع فاتورة

bash
curl -s -X POST "https://api.wasl.nami-lab.com/api/v1/public-invoices/invoices/{invoiceId}" \
  -H "Authorization: Bearer wsl_YOUR_API_KEY"

الرابط العام: https://api.wasl.nami-lab.com/i/{token} — يعرض بنود الفاتورة وحسابات الاستقبال وQR للدفع.

8. Webhooks

من تبويب Webhooks في التكاملات، أضف عنوان HTTPS واختر الأحداث. وصل يرسل POST بـ JSON خلال حوالي 10 ثوانٍ، ويعيد المحاولة عند الفشل المؤقت.

الأحداث

  • transfer.verified — تحويل مؤكد
  • invoice.paid — فاتورة مدفوعة (كلياً أو جزئياً)
  • alert.raised — تنبيه (تكرار، احتيال، …)

رؤوس الطلب

  • X-Wasl-Event — اسم الحدث
  • X-Wasl-Delivery — معرّف التسليم
  • X-Wasl-Signature — التوقيع t=<unix>,v1=<hmac>
  • User-Agent: Wasl-Webhooks/1.0

شكل الحمولة

json
{
  "id": "evt_01HXYZ…",
  "type": "transfer.verified",
  "createdAt": "2026-08-16T12:00:00.000Z",
  "data": {
    "transferId": "clx…",
    "amountMinor": "1500000",
    "currency": "SDG",
    "referenceNumber": "123456789",
    "bankId": "clx…",
    "customerId": "clx…",
    "branchId": "clx…",
    "status": "VERIFIED",
    "fraudSignals": []
  }
}

المصفوفة fraudSignals تحمل عناصر مثل CROSS_ORG_SENDER أو UNKNOWN_SENDER_ACCOUNT — استعملها لتنبيه فريقك قبل تسليم البضاعة.

التحقق من التوقيع

احسب HMAC-SHA256 للسلسلة {t}.{rawBody} باستخدام سر الـ webhook، وقارنها بـ v1 بمقارنة آمنة زمنياً. ارفض الطلبات الأقدم من 5 دقائق.

javascript
import { createHmac, timingSafeEqual } from 'node:crypto'

export function verifyWaslSignature (secret, rawBody, header, toleranceSec = 300) {
  const parts = Object.fromEntries(
    header.split(',').map((part) => {
      const [k, ...rest] = part.trim().split('=')
      return [k, rest.join('=')]
    }),
  )
  if (!parts.t || !parts.v1) return false
  const t = Number(parts.t)
  if (!Number.isFinite(t)) return false
  if (Math.abs(Math.floor(Date.now() / 1000) - t) > toleranceSec) return false

  const expected = createHmac('sha256', secret)
    .update(`${t}.${rawBody}`)
    .digest('hex')
  const a = Buffer.from(expected, 'utf8')
  const b = Buffer.from(parts.v1, 'utf8')
  return a.length === b.length && timingSafeEqual(a, b)
}

أرجع حالة 2xx بسرعة. الحالات 4xx (عدا 408/429) تُعتبر نهائية ولن تُعاد.

9. الأخطاء والحدود

  • 401 — مفتاح أو جلسة غير صالحة
  • 403 — لا صلاحية لهذا المسار
  • 404 — المورد غير موجود في مؤسستك
  • 422 — تحقق من الحقول (رسالة مفصّلة في الجسم)
  • 429 — تجاوز حد الطلبات؛ أعد المحاولة لاحقاً

الحد الافتراضي: 60 طلب/دقيقة لكل مفتاح API. عند الحاجة إلى معدّل أعلى، تواصل معنا. الاستجابات JSON، والحقول النقدية تُرجع كنص لتجنّب مشاكل الأرقام الكبيرة.

10. مرجع تفاعلي

جرّب كل المسارات مباشرة من Swagger UI. المرجع يعرض فقط ما يستطيع مفتاح API استدعاءه — إدارة الفريق، الإعدادات، وأدوات الفريق الداخلية للوحة التحكم غير معروضة لأنها ليست جزءاً من التكامل. للمساعدة: تواصل معنا.