منع تكرار الطلبات (Idempotency)
قد ينقطع الاتصال بعد أن تحفظ كسور طلبك وقبل أن يصلك الرد. في هذه الحالة يجب ألا تؤدي إعادة المحاولة إلى إنشاء العميل أو الفاتورة مرة ثانية. لهذا يجب أن يحمل كل طلب POST وPATCH الـ Header Idempotency-Key، وعند إعادة المحاولة ترسل المفتاح نفسه.
curl https://api.kosoor.com.sa/v1/customers \
-H "Authorization: Bearer ksr_live_..." \
-H "Idempotency-Key: 9b2c4c0e-6a51-4c0b-8a43-3c2f2f1a7d10" \
-H "Content-Type: application/json" \
-d '{"type":"person","firstName":"Sara","phone":"+966501234567"}'
شروط المفتاح
- من 1 إلى 255 حرفاً من حروف ASCII القابلة للطباعة، مع التمييز بين الحروف الكبيرة والصغيرة. أسهل خيار هو UUID جديد لكل عملية.
- المفاتيح مرتبطة بمفتاح الـ API الذي أرسلها، فلا مشكلة إذا استخدم مفتاح API آخر القيمة نفسها.
- تحتفظ كسور بالمفتاح لمدة 30 يوماً.
ماذا يحدث عند إعادة المحاولة
| ما ترسله | ما ترجعه كسور |
|---|---|
| المفتاح نفسه مع نفس الـ Method والمسار والـ Body، بعد طلب ناجح | الرد المحفوظ نفسه مع Idempotent-Replayed: true، دون تنفيذ أي شيء من جديد |
| المفتاح نفسه مع طلب مختلف | 422 idempotency_key_reused |
| المفتاح نفسه والطلب الأول لم ينتهِ بعد | 409 idempotency_in_progress مع Retry-After: 1 |
| المفتاح نفسه بعد طلب فاشل | يُنفَّذ الطلب من جديد، لأن الردود الناجحة فقط هي التي تُحفظ |
| بدون مفتاح | 400 missing_idempotency_key |
إذا توقف طلب في منتصف التنفيذ، يبقى مفتاحه محجوزاً لمدة 5 دقائق، وبعدها تنفّذه إعادة المحاولة بالمفتاح نفسه.
متى تعيد المحاولة
أعد المحاولة بالمفتاح نفسه عند انتهاء مهلة الطلب (Timeout)، أو انقطاع الاتصال، أو وصول 409 idempotency_in_progress، أو أي خطأ 5xx. أما أخطاء 4xx فلا تعِد الطلب كما هو، لأنه سيرجع بالخطأ نفسه: صحّح الطلب ثم أرسله بمفتاح جديد. ويُستثنى من ذلك ثلاثة أخطاء تعتمد على الوقت، فأعد المحاولة فيها لاحقاً بالمفتاح نفسه، لأن ردود 4xx لا تُحفظ: 409 invoice_not_cleared بعد أن تعتمد الهيئة الفاتورة، و 409 invoice_busy بعد ثوانٍ، و 422 loyalty_refund_blocked مرة واحدة بعد دقائق، فإن رجع بالخطأ نفسه يصدر التاجر الإشعار من لوحة التحكم حيث يستطيع المشرف تجاوز الرفض.