Sign in
مقدمة/المصادقة

المصادقة وتوقيع الطلبات

قم بتوقيع طلبات API باستخدام HMAC-SHA256 مع project UUID وAPI key الخاص بك.

يجب أن يحمل كل طلب API (باستثناء webhooks الواردة) project UUID الخاص بك وتوقيع الطلب. يثبت التوقيع أن الطلب صادر منك وأن لا أحد قام بتعديله أثناء النقل.

مفاتيح API

يستخدم 2328.io مفتاحين يشتركان في خوارزمية التوقيع نفسها لكنهما يغطيان نقاط نهاية مختلفة:

المفتاحيُستخدم لـ
API keyالمدفوعات، المحافظ الثابتة، الرصيد، أسعار الصرف، والتحقق من webhooks المدفوعات/المحافظ الثابتة
Payout API keyجميع نقاط النهاية /v1/payout/* والتحقق من webhooks السحب

كلا المفتاحين موجودان في إعدادات مشروعك على 2328.io. الأمثلة أدناه تذكر "API key" بشكل عام — استبدله بالمفتاح المناسب لنقطة النهاية التي تستدعيها.

لا تخلط أبدًا بين المفتاحين: توقيع طلب سحب باستخدام API key العادي (أو طلب دفع باستخدام Payout key) يُرجع خطأ توقيع.

الرؤوس المطلوبة

الرأسالنوعمطلوبالوصف
Content-Typestringنعمدائمًا application/json
projectstringنعمproject UUID الخاص بك
signstringنعمتوقيع HMAC-SHA256 للطلب، محسوب باستخدام API key الخاص بك
User-Agentstringنعميحدد تطبيقك (مثل MyShop/1.4 (+https://myshop.example)). قد يتم حظر الطلبات بدون User-Agent.

كيف يعمل التوقيع

اعتبر التوقيع بمثابة بصمة لمحتوى الطلب. يتم بناؤه عن طريق:

  1. تسلسل المحتوى إلى JSON (مضغوط — بدون مسافات إضافية).
  2. ترميز Base64 لذلك JSON. هذه الخطوة تطبّع المدخلات عبر اللغات — بمجرد أن تصبح ASCII خالصة، تنتج كل اللغات نفس البايتات لـ HMAC.
  3. حساب HMAC-SHA256 لسلسلة Base64 باستخدام API key الخاص بك، ثم تحويل النتيجة إلى hex بأحرف صغيرة.

بالنسبة لطلبات GET وغيرها من الطلبات بدون محتوى، قم بتوقيع سلسلة فارغة بدلًا من JSON.

توقيع السلسلة الفارغة ثابت لمفتاح API معين. يمكنك تخزينه مؤقتًا إذا قمت بإجراء العديد من استدعاءات GET.

التطبيقات

PHP
<?php
function apiSign(array $data, string $apiKey): string {
    $json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    $base64 = base64_encode($json);
    return hash_hmac('sha256', $base64, $apiKey);
}

الطلبات بدون محتوى (GET)

بالنسبة للطلبات بدون محتوى (مثل GET /v1/payout/status/{uuid})، قم بتوقيع سلسلة فارغة:

Shell
SIGN=$(printf '' | openssl dgst -sha256 -hmac "$API_KEY" -hex | awk '{print $NF}')

مثال كامل لطلب

Shell
curl -X POST https://api.2328.io/api/v1/payment \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyShop/1.0 (+https://myshop.example)" \
  -H "project: YOUR_PROJECT_UUID" \
  -H "sign: YOUR_HMAC_SIGNATURE" \
  -d '{"amount":"100.00","currency":"USD","order_id":"ORDER-123"}'

لا تكشف أبدًا عن API key الخاص بك في كود من جانب العميل. قم بتوقيع الطلبات على الواجهة الخلفية لديك. تسرّب API key يمنح أي شخص وصولًا كاملًا إلى حساب التاجر.

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

عندما يرسل لك 2328.io webhook، تعمل نفس الخوارزمية بشكل عكسي:

  1. استخرج حقل sign من المحتوى.
  2. قم بترميز الحقول المتبقية كـ JSON (مضغوط، بدون مسافات).
  3. قم بترميز Base64 لتلك السلسلة.
  4. احسب HMAC-SHA256 بالمفتاح المناسب.
  5. قارنه بـ sign المستلم باستخدام مقارنة بزمن ثابت (hash_equals، crypto.timingSafeEqual، hmac.compare_digest، subtle.ConstantTimeCompare، OpenSSL.fixed_length_secure_compare).

يعتمد مفتاح التوقيع على مصدر webhook:

Webhookالمفتاح المستخدم للتحقق
webhooks المدفوعات / المحافظ الثابتة (/v1/payment، /v1/static-wallet)API key
webhooks السحب (/v1/payout)Payout API key

أخطاء شائعة في التحقق. يجب أن ينتج مُرمِّز JSON لديك نفس البايتات تمامًا التي أنتجها المُرسِل — وإلا فسيختلف Base64 ولن يتطابق التوقيع.

  • Go: استخدم json.NewEncoder مع SetEscapeHTML(false). الـ json.Marshal الافتراضي يهرب < و> و& إلى < ويُفسد التوقيع.
  • Python: مرِّر ensure_ascii=False إلى json.dumps. بدونها، تُهرَّب الأحرف غير ASCII (السيريلية، الصينية، …) إلى \uXXXX.
  • JSON مضغوط: بدون مسافات بيضاء بين الحقول (separators=(",", ":") في Python).
  • ترتيب الحقول (Go): إن map[string]any العادي يُرتِّب المفاتيح عشوائيًا عند إعادة الترميز. استخدم json.RawMessage أو struct مُرتَّبة، أو احذف sign من البايتات الأصلية.

إذا استمر فشل التحقق، فشغِّل apiSign على الحمولة بنفسك — يجب أن ينتج نفس السلسلة السداسية عشرية مثل sign المستلم.

التوقيع الصحيح لا يمنع إعادة الإرسال. هو فقط يُثبت أن الـ webhook جاء من 2328.io — ولا يمنع المهاجم من إعادة إرسال webhook تم اعتراضه لاحقًا. تحقق دائمًا من عدم التكرار باستخدام uuid (أو txid للمحافظ الثابتة) قبل قيد الأموال. ارفض الطلب بـ HTTP 401 إذا كان التوقيع مفقودًا أو خاطئًا.

أمثلة الكود الكاملة موجودة في Webhook Notifications. ومعالجة إعادة المحاولة وقواعد عدم التكرار في أفضل الممارسات.