لا تحصّلوا مرتين أبدًا — شرح Idempotency
شرح Idempotency في المدفوعات: كيف تمنع ترويسة Idempotency-Key وحقل externalId خصم المبلغ من الزبون مرتين حين تنقطع الشبكة في منتصف النداء.
يرسل خادمكم طلب دفع. تنقطع الشبكة قبل وصول الاستجابة. لا تعرفون هل تمّت العملية أم لا. فماذا تفعلون؟
إن أعدتم المحاولة خاطرتم بالخصم مرتين. وإن لم تعيدوها خاطرتم بخسارة بيعة. لهذه المعضلة حلّ اسمه Idempotency — أي عدم التكرار — ويسع ترويسة HTTP واحدة.
المشكلة ليست نادرة
يسهل تصوّر أن هذه الحالة نظرية. وهي ليست كذلك. مهلة منتهية، أو إعادة تشغيل حاوية في اللحظة الخطأ، أو عميل جوّال ينتقل من الواي‑فاي إلى الجيل الرابع، أو طابور مهامّ يعيد رسالة: كل واحد من هذه الحوادث ينتج الوضع نفسه بالضبط.
عند بضع مئات من المدفوعات يوميًا، يقع الأمر. وعند بضعة آلاف، يقع كل يوم.
مفتاح Idempotency
كل عملية إنشاء تقبل ترويسة Idempotency-Key — ويضبط دليل Idempotency في توثيق الواجهة البرمجية قواعدها. والقاعدة بسيطة: استدعاءان بالمفتاح نفسه ينتجان موردًا واحدًا.
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" }'أعيدوا هذا الاستدعاء كما شئتم: ستحصلون دائمًا على رابط الدفع نفسه. لا على ثانٍ. ولتتحققوا من ذلك بأنفسكم، ضعوا مكانه مفتاح اختبار (chari_sk_test_…): يفتح لكم ابدؤوا في وضع الاختبار السندبوكس فور التسجيل، دون انتظار أي موافقة.
يجب أن يكون المفتاح حتميًا وخاصًا بالعملية. مرجع طلبكم مرشّح ممتاز: تعرفونه، ولا يتغيّر، وهو فريد لديكم. أما معرّف عشوائي يُولَّد في كل محاولة فلا يفيد شيئًا — وهو بالضبط ما يُفترض بالمفتاح أن يمنعه.
روابط الدفع تذهب أبعد
في روابط الدفع، يحمل حقل externalId الضمانة نفسها بشكل دائم: فهو فريد لكل حساب ولكل بيئة.
أنشئوا رابطًا مرتين بالمعرّف نفسه، فتعيد الواجهة الرابط القائم برمز 200 بدل 201. اختلاف الرمز يقول لكم بالضبط ما جرى، دون أن تحفظوا أي حالة وسيطة.
وهذا مفيد بوجه خاص حين تقود معالجتكم طابور رسائل: قد تُسلَّم الرسالة مرتين، وقد يستدعي كودكم مرتين، وتبقى النتيجة صحيحة. ولإيجاد الطلبية التي وراء كل أداء بعد ذلك، راجعوا ربط الأداء بالطلبية.
في الاستردادات
يؤدي مرجع الاسترداد — حقل refundReference في مرجع واجهة الاستردادات — الدور نفسه. إعادة استرداد بالمرجع نفسه لا تسترد مرتين — وهو ما يجنّبكم، في استرداد جزئي، صنفًا كاملًا من الحوادث المرهقة في فكّها.
ما لا يفعله Idempotency
لا يغني عن التحقق من حالاتكم أنتم. فإن كان نظامكم قادرًا على إنشاء طلبين لسلة واحدة، فلن تصلح ذلك أي ترويسة HTTP.
ولا يجعل الويب هوكس عندكم غير قابلة للتكرار. تلك مهمة منفصلة بالروح نفسها، يشرحها دليل إنجاح دمج الويب هوك: كل تسليم يحمل معرّف حدث، فاحفظوه وتجاهلوا ما عالجتموه سابقًا. قد يصل الإشعار نفسه مرتين — بالتصميم، كي لا يضيع أيّ منها. وأخيرًا، لا يقول لكم ما تفعلونه بخطأ: فإعادة النداء أو التصحيح يتوقفان على الرمز المُعاد، المشروح في رموز أخطاء API الدفع.
توليد مفتاح جيد
مفتاح Idempotency ليس رقمًا عشوائيًا يُسحب لحظة النداء — فذلك تفويت للفكرة كلها. المفتاح الجيد حتمي: العملية التجارية نفسها تنتج دائمًا المفتاح نفسه.
النمط الأسلم: اشتقوا المفتاح من معرّف الكائن التجاري الذي يطلق الأداء. order-8842-payment لتحصيل الطلبية 8842؛ وclient-512-subscription لإنشاء اشتراك الزبون 512؛ وrefund-tx-77a1 لاسترجاع. إذا مرّ كودكم من هناك ثانية — إعادة تلقائية، طابور رسائل سلَّم مرتين، مستخدم مستعجل — كان المفتاح متطابقًا، والعملية واحدة.
وبالمقابل، عمليتان متمايزتان فعلًا يجب أن تنتجا مفتاحين متمايزين: لا تستعملوا معرّف الزبون وحده أبدًا، وإلا تشاركت كل طلبياته مفتاحًا واحدًا.
حدّ يجب معرفته: يحمي المفتاح النداء، لا منطقكم. إذا أنشأ كودكم طلبيتين مختلفتين لنفس الشراء، حملت كل واحدة مفتاحها وحُصِّلت كل واحدة. Idempotency يبدأ في نموذج بياناتكم.
Idempotency في جهة الويب هوكس
المبدأ نفسه يسري في الاتجاه الآخر. قد يصلكم إشعار أداء مرتين — وهذه ضمانة موثوقية، لا عيب. فيجب أن يكون معالج الويب هوك عندكم غير قابل للتكرار هو الآخر: معرّف الحدث يلعب دور المفتاح، وجدول بقيد فرادة يلعب دور الحارس.
الآليتان تتجاوبان: مفتاح Idempotency يمنع إعادتكم من إنشاء أداءين؛ وإزالة تكرار الأحداث تمنع إعادتنا من جعلكم تشحنون طلبيتين. الإدماج المتين يحمل الاثنين، وحادث الشبكة نفسه — المذنب الحقيقي الوحيد في هذه القصة — لم يعد يكلف أحدًا شيئًا.
القاعدة في جملة
كل عملية إنشاء تلتزم بمال تحمل مفتاح Idempotency مشتقًّا من مرجعكم أنتم، وكل معالج ويب هوك يزيل التكرار بمعرّف الحدث. عادتان، وعشرة أسطر من الشيفرة، ويختفي صنف كامل من الأخطاء.
الخطوة التالية
أوضح اختبار أن تعيدوا بأنفسكم نداءً بالمفتاح نفسه وتقارنوا الاستجابات. يطلب ابدؤوا في وضع الاختبار اسمًا وبريدًا إلكترونيًا مهنيًا واسم الشركة؛ وبعد رابط التفعيل الذي يصلكم بالبريد واختيار كلمة المرور، تنشئون مفتاح اختبار من البوابة — مجانًا وبلا حدّ زمني. وللإدماج كاملًا — المفاتيح، والروابط، والجلسات، والويب هوك الموقَّع — اتبعوا دليل واجهة الدفع البرمجية في المغرب.
بقلم فريق ChariPay.