الانتقال إلى المحتوى الرئيسي
كل المقالات
تقني3 دقائق قراءة

لا تحصّلوا مرتين أبدًا — شرح Idempotency

تنقطع الشبكة في اللحظة الخطأ، فتعيدون المحاولة، فيُخصم من الزبون مرتين. كيف تحسم ترويسة HTTP واحدة الأمر.

يرسل خادمكم طلب دفع. تنقطع الشبكة قبل وصول الاستجابة. لا تعرفون هل تمّت العملية أم لا. فماذا تفعلون؟

إن أعدتم المحاولة خاطرتم بالخصم مرتين. وإن لم تعيدوها خاطرتم بخسارة بيعة. لهذه المعضلة حلّ اسمه Idempotency — أي عدم التكرار — ويسع ترويسة HTTP واحدة.

المشكلة ليست نادرة

يسهل تصوّر أن هذه الحالة نظرية. وهي ليست كذلك. مهلة منتهية، أو إعادة تشغيل حاوية في اللحظة الخطأ، أو عميل جوّال ينتقل من الواي‑فاي إلى الجيل الرابع، أو طابور مهامّ يعيد رسالة: كل واحد من هذه الحوادث ينتج الوضع نفسه بالضبط.

عند بضع مئات من المدفوعات يوميًا، يقع الأمر. وعند بضعة آلاف، يقع كل يوم.

مفتاح Idempotency

كل عملية إنشاء تقبل ترويسة Idempotency-Key. والقاعدة بسيطة: استدعاءان بالمفتاح نفسه ينتجان موردًا واحدًا.

bash
curl -X POST 'https://api-psp.charipay.ma/v1/payment-links' \
  -H 'X-CHARI-PAY-API-KEY: chari_sk_live_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: order-2026-1042' \
  -d '{ "amount": 249.00, "description": "Order #1042" }'

أعيدوا هذا الاستدعاء كما شئتم: ستحصلون دائمًا على رابط الدفع نفسه. لا على ثانٍ.

يجب أن يكون المفتاح حتميًا وخاصًا بالعملية. مرجع طلبكم مرشّح ممتاز: تعرفونه، ولا يتغيّر، وهو فريد لديكم. أما معرّف عشوائي يُولَّد في كل محاولة فلا يفيد شيئًا — وهو بالضبط ما يُفترض بالمفتاح أن يمنعه.

روابط الدفع تذهب أبعد

في روابط الدفع، يحمل حقل externalId الضمانة نفسها بشكل دائم: فهو فريد لكل حساب ولكل بيئة.

أنشئوا رابطًا مرتين بالمعرّف نفسه، فتعيد الواجهة الرابط القائم برمز 200 بدل 201. اختلاف الرمز يقول لكم بالضبط ما جرى، دون أن تحفظوا أي حالة وسيطة.

وهذا مفيد بوجه خاص حين تقود معالجتكم طابور رسائل: قد تُسلَّم الرسالة مرتين، وقد يستدعي كودكم مرتين، وتبقى النتيجة صحيحة.

في الاستردادات

يؤدي مرجع الاسترداد الدور نفسه. إعادة استرداد بالمرجع نفسه لا تسترد مرتين — وهو ما يجنّبكم، في استرداد جزئي، صنفًا كاملًا من الحوادث المرهقة في فكّها.

ما لا يفعله Idempotency

لا يغني عن التحقق من حالاتكم أنتم. فإن كان نظامكم قادرًا على إنشاء طلبين لسلة واحدة، فلن تصلح ذلك أي ترويسة HTTP.

ولا يجعل الويب هوكس عندكم غير قابلة للتكرار. تلك مهمة منفصلة بالروح نفسها: كل تسليم يحمل معرّف حدث، فاحفظوه وتجاهلوا ما عالجتموه سابقًا. قد يصل الإشعار نفسه مرتين — بالتصميم، كي لا يضيع أيّ منها.

توليد مفتاح جيد

مفتاح Idempotency ليس رقمًا عشوائيًا يُسحب لحظة النداء — فذلك تفويت للفكرة كلها. المفتاح الجيد حتمي: العملية التجارية نفسها تنتج دائمًا المفتاح نفسه.

النمط الأسلم: اشتقوا المفتاح من معرّف الكائن التجاري الذي يطلق الأداء. order-8842-payment لتحصيل الطلبية 8842؛ وsubscription-512-instalment-2026-09 لقسط اشتراك؛ وrefund-tx-77a1 لاسترجاع. إذا مرّ كودكم من هناك ثانية — إعادة تلقائية، طابور رسائل سلَّم مرتين، مستخدم مستعجل — كان المفتاح متطابقًا، والعملية واحدة.

وبالمقابل، عمليتان متمايزتان فعلًا يجب أن تنتجا مفتاحين متمايزين: لا تستعملوا معرّف الزبون وحده أبدًا، وإلا تشاركت كل طلبياته مفتاحًا واحدًا.

حدّ يجب معرفته: يحمي المفتاح النداء، لا منطقكم. إذا أنشأ كودكم طلبيتين مختلفتين لنفس الشراء، حملت كل واحدة مفتاحها وحُصِّلت كل واحدة. Idempotency يبدأ في نموذج بياناتكم.

Idempotency في جهة الويب هوكس

المبدأ نفسه يسري في الاتجاه الآخر. قد يصلكم إشعار أداء مرتين — وهذه ضمانة موثوقية، لا عيب. فيجب أن يكون معالج الويب هوك عندكم غير قابل للتكرار هو الآخر: معرّف الحدث يلعب دور المفتاح، وجدول بقيد فرادة يلعب دور الحارس.

الآليتان تتجاوبان: مفتاح Idempotency يمنع إعادتكم من إنشاء أداءين؛ وإزالة تكرار الأحداث تمنع إعادتنا من جعلكم تشحنون طلبيتين. الإدماج المتين يحمل الاثنين، وحادث الشبكة نفسه — المذنب الحقيقي الوحيد في هذه القصة — لم يعد يكلف أحدًا شيئًا.

القاعدة في جملة

كل عملية إنشاء تلتزم بمال تحمل مفتاح Idempotency مشتقًّا من مرجعكم أنتم، وكل معالج ويب هوك يزيل التكرار بمعرّف الحدث. عادتان، وعشرة أسطر من الشيفرة، ويختفي صنف كامل من الأخطاء.

بقلم فريق ChariPay.

اقرؤوا بعده

تقني3 دقائق قراءة

إنجاح دمج الويب هوك

خمسة أخطاء تتكرّر في كل عملية دمج تقريبًا، والمعالج في خمسة عشر سطرًا الذي يتفاداها جميعًا.

سؤال حول عملية الدمج لديكم؟

يجيب فريقنا التجّار والمطوّرين على حد سواء، من أول اختبار حتى الإطلاق.