واجهة بطاقات الهدايا — جلب الكود والتسليم الآلي
تختلف بطاقة الهدية عن أي منتج رقمي آخر في أمر واحد: الكود لا رجعة فيه. فما إن يصل ذلك النص إلى المشتري حتى تفقد أي وسيلة لمعرفة ما إذا استُهلك، ويصبح كل نزاع محسوماً بسجلّك لا بالمنطق. فيما يلي المسار الكامل للكود من الطلب إلى التسليم، مع التركيز على المواضع التي تُفقد فيها الأموال فعلاً.
خمس مراحل يجب الفصل بينها
معظم أعطال إصدار الأكواد تحدث لأن المطوّر يعامل هذا كله كعملية واحدة. إنها خمس عمليات بخمسة أنماط فشل مختلفة:
| المرحلة | ما يحدث | من يملك الحالة |
|---|---|---|
| 1. الطلب | ترسل طلب شراء | قاعدتك + المورّد |
| 2. الإصدار | المورّد يحجز الكود ويصدره | المورّد |
| 3. الجلب | تستخرج الكود من الاستجابة | قاعدتك |
| 4. التخزين | الكود مشفّر لديك | قاعدتك |
| 5. التسليم | المشتري يرى الكود | واجهتك أو البريد |
كل انتقال يجب أن يكون صفاً مستقلاً موسوماً بالوقت في قاعدة بياناتك. فإذا كان لديك عمود status واحد يغطي الرحلة كلها، فسيتركك أول عطل عاجزاً عن الإجابة على السؤال الوحيد المهم: هل صدر كود أصلاً؟
المرحلة 1. إنشاء الطلب
يُنشأ الطلب بمعرّف المنتج والكمية:
curl -X POST "https://public-api.foxreload.com/api/orders" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"itemId": "product_01krgfgww8eth9xvvysd6y7r4j",
"quantity": 1
}
],
"isMock": false
}'
الاستجابة كائن طلب بحالة active، مع id وprice وcreatedAt وpaymentExpiresAt ومصفوفة items[].
ثلاث قواعد في هذه المرحلة:
- سجّل النية في قاعدة بياناتك قبل استدعاء المورّد لا بعده. فالصف الذي يقول «نحن على وشك طلب هذا للعميل س» يجب أن يوجد قبل مغادرة طلب HTTP، وإلا فإن انهيار العملية بين الإرسال والاستجابة لا يترك أثراً.
- احفظ
order_idالخاص بالمورّد لحظة وصوله. هو المفتاح الوحيد الذي ستجد به ذلك الطلب لاحقاً. - لا تخلط الطلبات التجريبية بالحقيقية في جدول واحد دون علامة صريحة. كائن الطلب لدى FoxReload يحمل
isMock— انسخه إلى مخططك.
المرحلة 2. الإصدار لدى المورّد
بعد الإنشاء ينتقل الطلب active ← paid (خصم من الرصيد) ← processing (المورّد يصدر) ← completed.
مرحلة processing تخص نظام طرف آخر وقد تستغرق من ثوانٍ إلى وقت أطول بوضوح حسب نوع البطاقة. ومهمتك الوحيدة هنا هي ألّا تفعل شيئاً هدّاماً ما دامت الحالة مجهولة. لا مجال لـ«الأرجح أنه فشل، لنطلب واحداً آخر».
المرحلة 3. جلب الكود
يُجلب الكود باستطلاع الطلب:
curl "https://public-api.foxreload.com/api/orders/{order_id}" \
-H "X-API-Key: YOUR_API_KEY"
عندما تصير status == "completed" يحمل كل عنصر في items[]:
product— كائن المنتج بحقولهidوnameوuserGuideوattributesexternalData[]— مصفوفة الأكواد أو أرقام PIN الصادرةerror— خطأ خاص بهذا البند إن وُجد
الحقل userGuide ليس زخرفياً. إنه تعليمات التفعيل من المورّد ويجب أن تصل المشتري مع الكود — فنصف تذاكر «الكود لا يعمل» تعني في الحقيقة أن المشتري يستهلكه في المنطقة الخطأ أو في القسم الخطأ من حسابه.
بشأن الويب هوك — تحقق من مورّدك أنت
بعض المورّدين يستطيعون إشعارك عند اكتمال الطلب، غالباً بتوقيع HMAC على الاستدعاء الراجع. تحقق مما إذا كان مورّدك تحديداً يطبّق ذلك. أما FoxReload فلا يدعم الويب هوك — وتُجلب النتائج بالاستطلاع فقط.
وحتى حيث توجد الويب هوك، أبقِ الاستطلاع شبكة أمان: فالتسليم غير مضمون أبداً وقد يكون معالجك معطّلاً في اللحظة الخاطئة تماماً. الويب هوك مسرِّع، والاستطلاع مصدر الحقيقة.
التنفيذ الجزئي
في الطلب متعدد البنود تكتمل البنود باستقلال. فقد يعيد بند كوداً بينما يفشل آخر مع امتلاء items[].error.
الاستجابة الصحيحة:
- كل ما صدر فعلاً يُحفظ ويُسلَّم. فذلك المال أُنفق والكود موجود.
- للجزء الناقص، إما إعادة الطلب كعملية منفصلة أو استرداد قيمته للعميل.
- لا تعتبر الطلب كله فاشلاً بعدما خرجت بعض الأكواد. هذا المسار ينتهي باسترداد قيمة بضاعة استلمها العميل فعلاً.
المرحلة 4. الحماية من الإصدار المزدوج
هذا أغلى خطأ في هذه الفئة، وينشأ في موضعين مختلفين.
التكرار على مستوى الطلب
ترسل طلب إنشاء، تنتهي المهلة، تعيد الإرسال — فتنشئ طلبين. اشتريت الآن كودين وسلّمت واحداً، والثاني إما جامد في دفاترك أو، وهو الأسوأ، يخرج للمشتري التالي بالخطأ.
بعض الواجهات تقبل ترويسة Idempotency-Key تحل هذا عند المورّد. تحقق مما إذا كان مورّدك يطبّقها فعلاً — كثيرون لا يفعلون. ولا يدعم FoxReload ترويسة Idempotency-Key.
فالحماية إذاً عندك:
- احفظ مفتاح عملية فريداً في قاعدة بياناتك قبل الاستدعاء.
- عند انتهاء المهلة، اطلب قائمة طلبات المورّد أولاً، مرشّحة بالحالات، وتحقق من وجود الطلب.
- ولا تعِد المحاولة إلا بعد التأكد من عدم وجوده.
curl "https://public-api.foxreload.com/api/orders/?statuses=active,processing&limit=20" \
-H "X-API-Key: YOUR_API_KEY"
التكرار على مستوى التسليم
المصدر الثاني تسابق داخل نظامك أنت. ينقر العميل «أظهر الكود» مرتين، فتقرأ عمليتان متوازيتان صف الطلب على أنه «الكود جاهز وغير مسلَّم»، وتمضي كلتاهما إلى التسليم.
العلاج معاملة مع قفل صف: التسليم يعلّم الطلب مسلَّماً ويُثبّت المعاملة قبل أن يغادر الكود نظامك. وإن كان الكود يخرج بالبريد فإن الإرسال يُدرج في طابور داخل المعاملة نفسها لا يُنفّذ تزامنياً في منتصفها.
إعادة المحاولة
القاعدة العامة: لا تعِد إلا ما يأمن تكراره.
429و5xx— إعادة محاولة بتراجع أسّي وتشويش عشوائي.- بقية
4xxعدا429— لا إعادة محاولة أبداً، فالجواب لن يتغير. - انتهاء المهلة عند الإنشاء — ليس إعادة محاولة بل فحص حالة أولاً.
التفاصيل في مقال أنماط إعادة المحاولة والتراجع.
المرحلة 5. التخزين — التشفير والصلاحيات
كود بطاقة الهدية أداة لحاملها. من قرأه أمكنه إنفاقه.
- شفّر قيمة الكود على مستوى التطبيق بمفتاح من مدير الأسرار. تشفير القرص لا يكفي: فتفريغ قاعدة البيانات أو نسخة احتياطية مسروقة أو حقن SQL كلها تقرأ القرص وقد فُكّ تشفيره.
- اقصر فك التشفير على خدمة واحدة. فنسخة التحليلات ولوحة الدعم وسكربتات التنقيح لا ينبغي أن تملك هذا الحق.
- لا تكتب الأكواد في السجلات أبداً. لا في السجلات العادية ولا في مخرجات التنقيح ولا في تتبعات APM ولا في متن تذكرة دعم. أخفِ القيمة عند خروجها من طبقة الوصول للبيانات، لا في كل موضع طباعة على حدة.
- احفظ بصمة تجزئة بجانب الكود. تتيح لك إثبات «هذا هو الكود الذي أصدرناه» دون كشف القيمة مرة أخرى.
- حدّد مدة الاحتفاظ. بعد التسليم وانقضاء نافذة النزاع يمكن حذف القيمة المشفّرة مع إبقاء البصمة والبيانات الوصفية.
المرحلة 6. التسليم وسجل التدقيق
التسليم نفسه عملية قابلة للفشل. البريد يرتد، والتبويب يُغلق، والمشتري يكتب عنواناً خاطئاً.
النمط العملي:
- يُعرض الكود مرة واحدة على صفحة طلب محمية متاحة للمشتري الموثّق وحده.
- إعادة الوصول تتم من منطقة الحساب، مع تسجيل كل مشاهدة.
- أي رابط عرض لمرة واحدة يكون قصير العمر وأحادي الاستخدام.
- يُسجَّل أول عرض بطابع زمني — وهذه هي الواقعة التي ستستشهد بها في النزاع.
سجل التدقيق
الحد الأدنى من الأحداث التي تُسجَّل لكل كود:
| الحدث | ما تلتقطه |
|---|---|
| إنشاء الطلب | المعرّف الداخلي، المنتج، المشتري، الوقت |
| استلام معرّف المورّد | حقل order_id لدى المورّد |
| جلب الكود | بصمة الكود، البند، الوقت |
| عرض الكود للمشتري | الوقت، عنوان IP، معرّف الجلسة |
| فتح نزاع | رابط الطلب والتذكرة |
| حسم النزاع | استرداد أو رفض أو استبدال |
هذا السجل — لا محادثة الدعم — هو ما يجيب عن سؤال «هل سُلّم الكود ومتى». وكيف يعمل هذا الدليل عملياً موضّح في تفادي عمليات ردّ المدفوعات في السلع الرقمية.
وتذكّر المخاطر التي لا تصلحها أي شيفرة: إلغاء الكود من جهة المُصدِر، وقيود الاستهلاك الإقليمية، وإبطال البطاقة عند اشتباه المُصدِر بالاحتيال. تحليل هذه السيناريوهات في التعامل مع إلغاء الأكواد والقيود الإقليمية.
من أين تجلب بطاقات الهدايا بالجملة
يستحق بناء المسار أعلاه مرة واحدة، وأمام كتالوج واسع بما يكفي لتغطية تشكيلتك كلها. FoxReload مورّد جملة للسلع الرقمية بأكثر من 900 صنف — بطاقات هدايا، مفاتيح ألعاب، عمليات شحن، شرائح eSIM، ورخص برمجيات — كلها خلف واجهة REST واحدة مع تسليم آلي وأصناف متعددة المناطق. نموذج طلب واحد وبنية استجابة واحدة عبر الفئات كلها، بدل تكامل منفصل مع كل جهة مُصدِرة.
