منصة B2B للسلع الرقمية

أنماط استطلاع نتائج الطلبات والتعافي 2026

أنماط مجرّبة لاسترجاع نتائج الطلبات بموثوقية — استطلاع بتراجع، كشف التعثّر، تعافٍ بأسلوب DLQ، وبناء طبقة دفع خاصة فوق استطلاع FoxReload.

أنماط استطلاع نتائج الطلبات والتعافي 2026 — واجهات السلع الرقمية B2B

تسلّم FoxReload نتائج الطلبات عبر الاستطلاع لا خطافات الويب. لا توجد ترويسة X-FoxReload-Signature، ولا نقطة نهاية استدعاء HMAC، ولا تدفّق أحداث order.*. عندما تصبح status الطلب completed، تظهر الأكواد المُسلّمة في items[].externalData. تغطي هذه المقالة الأنماط الإنتاجية للاستطلاع الموثوق، والتعافي من الطلبات المتعثّرة، وبناء طبقة إشعارات شبيهة بخطافات الويب في خلفيتك الخاصة.

1. الاستطلاع بالتراجع الأُسّي — الرياضيات

الفاصل الثابت الساذج بمقدار 5 ثوانٍ ينشئ حملًا غير ضروري على الواجهة. الصيغة الصحيحة تتراجع مع مرور الوقت —

function nextPollDelay(attempt: number): number {
  const base = 5_000; // 5s
  const cap = 30_000; // 30s
  const exp = Math.min(base * Math.pow(1.5, attempt), cap);
  const jitter = Math.random() * exp * 0.3; // ±30%
  return exp + jitter;
}
// attempt 0: 5–6.5s
// attempt 3: ~17–22s
// attempt 6+: 27–39s (capped at 30s base + jitter)

2. تنفيذ الاستطلاع مع كشف التعثّر

// Express + BullMQ pattern
async function pollOrder(orderId: string, apiKey: string): Promise<Order> {
  const maxAttempts = 40; // ~15 minutes total
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    const res = await fetch(
      `https://public-api.foxreload.com/api/orders/${orderId}`,
      { headers: { 'X-API-Key': apiKey } },
    );
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const order = await res.json();

    if (order.status === 'completed') {
      // Extract and deliver codes
      const codes = order.items.flatMap((i: any) => i.externalData ?? []);
      await db.insert('delivery_log', { orderId, codes, deliveredAt: new Date() });
      await deliverToCustomer(orderId, codes);
      return order;
    }
    if (['cancelled', 'failed'].includes(order.status)) {
      await handleTerminalFailure(order);
      return order;
    }
    await sleep(nextPollDelay(attempt));
  }
  // Stalled — alert ops
  await alertOps(`Order ${orderId} stalled after ${maxAttempts} poll attempts`);
  throw new Error(`Order ${orderId} did not complete in time`);
}

3. طابور التعافي من الطلبات المتعثّرة

بعد أن يستنفد استطلاعك الأولي، لا تتجاهل الطلبات المتعثّرة. انقلها إلى طابور تعافٍ لإعادة فحص دورية —

// Scheduled job — runs every 5 minutes
async function recoverStalledOrders(apiKey: string) {
  const stalled = await db.orders.findAll({
    status: ['active', 'paid', 'processing'],
    createdAt: { lt: new Date(Date.now() - 10 * 60_000) },
    inRecovery: false,
  });

  for (const order of stalled) {
    await db.orders.update(order.id, { inRecovery: true });
    await queue.add('recover-order', { orderId: order.foxreloadId, apiKey }, {
      attempts: 8,
      backoff: { type: 'exponential', delay: 30_000 },
      removeOnFail: false, // keep in DLQ for manual inspection
    });
  }
}

يراجع فريق المناوبة مدخلات DLQ — إما إعادة وضعها في الطابور بعد حلّ المشكلة، أو إغلاقها يدويًا إذا تأكد إلغاء الطلب.

4. إزالة التكرار — منع التسليم المزدوج

قد يعمل عامل الاستطلاع لديك بالتوازي أو تُعاد محاولته. احمِ نفسك من تسليم الأكواد نفسها مرتين باستخدام قيد UNIQUE في قاعدة البيانات —

async function deliverOnce(orderId: string, codes: any[]): Promise<boolean> {
  try {
    await db.query(
      'INSERT INTO delivery_log (order_id, codes, delivered_at) VALUES ($1, $2, NOW())',
      [orderId, JSON.stringify(codes)],
    );
    await sendCodesToCustomer(orderId, codes); // email, bot message, etc.
    return true;
  } catch (err: any) {
    if (err.code === '23505') return false; // already delivered (unique violation)
    throw err;
  }
}
التخزين زمن الاستجابة مدة البقاء التكلفة / مليون سجل
Postgres UNIQUE 5–8ms للأبد $0.10
Redis SETNX <2ms 24h $0.40
DynamoDB ConditionExpression 8–12ms 24h $1.25

بالنسبة لمعظم الشركاء، يكون Postgres UNIQUE الأمثل — رخيص ودائم ويوفّر سجل تدقيق كاملًا.

5. بناء طبقة إشعارات الدفع الخاصة بك

يجب ألا يستطلع مستهلكوك الأدنى (روبوت Telegram، مرسل البريد، طابور التنفيذ) FoxReload كلٌّ على حدة. شغّل عامل استطلاع واحدًا لكل طلب وانشر أحداث الاكتمال داخليًا —

POST /api/orders ──▶ Your backend creates order
                       │
                       ▼
            Polling worker (one process per order)
              polls GET /api/orders/{id} with backoff
                       │
                       ▼ (on completed)
            Internal queue (Redis Streams / SQS / BullMQ)
            publish { orderId, status, codes }
                       │
                 ┌─────┴─────────────┐
                 ▼                   ▼
          Telegram delivery      Email sender

6. التنبيه عند تدهور التسليم

المقياس الواجب مراقبته هو معدل اكتمال الطلبات المتدحرج خلال 10 دقائق. إذا انخفض دون 99%، فتلك حادثة. قاعدة Prometheus —

- alert: OrderDeliveryDegraded
  expr: |
    (sum(rate(orders_completed_total[10m]))
     / (sum(rate(orders_completed_total[10m])) + sum(rate(orders_stalled_total[10m])))
    ) < 0.99
  for: 2m
  labels: { severity: page }

يُوجَّه التنبيه إلى PagerDuty/Opsgenie. في 80% من الحالات يكون السبب الجذري تأخيرًا من جهة المورّد — ويحلّه طابور التعافي من الطلبات المتعثّرة تلقائيًا ضمن نافذة إعادة المحاولة.

CTA

توثيق واجهة طلبات FoxReload الكامل، ورموز الحالة، ومخطط externalData متاحة بعد التهيئة — اطلب وصول الواجهة.

الأسئلة الشائعة

هل ترسل FoxReload خطافات ويب عند اكتمال الطلب؟
لا. لا ترسل FoxReload خطافات ويب. لا توجد ترويسة X-FoxReload-Signature، ولا استدعاء HMAC، ولا تدفّق أحداث *.order. الطريقة الصحيحة للحصول على نتائج الطلب هي استطلاع GET /api/orders/{order_id} حتى تصبح الحالة 'completed' أو 'cancelled' أو 'failed'.
كيف أزيل تكرار نتائج الطلبات؟
تحقق من قاعدة بياناتك من معرّف الطلب قبل المعالجة. عندما يكتشف عامل الاستطلاع لديك أن status == 'completed'، أدرج صفًا في جدول delivery_log مع قيد UNIQUE على order_id. إذا فشل الإدراج، فالطلب قد عُولج سابقًا — تخطّاه.
كيف يجب أن تبدو حلقة الاستطلاع؟
ابدأ بفواصل 5 ثوانٍ خلال أول 60 ثانية، ثم تراجع إلى 15 أو 30 ثانية. اضبط حدًا أقصى للانتظار الإجمالي عند 10 إلى 15 دقيقة قبل تنبيه فريق التشغيل. تكتمل معظم طلبات FoxReload في أقل من 60 ثانية.
كيف أراقب الطلبات التي لا تكتمل أبدًا؟
شغّل مهمة مجدولة كل 5 دقائق تجد كل الطلبات ذات الحالة ضمن [active, paid, processing] وبتاريخ createdAt أقدم من 10 دقائق. نبّه فريق المناوبة لكل طلب متعثّر كي يتحرّوا الأمر.
احصل على وصول واجهة FoxReload

مقالات ذات صلة