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

استرجاع نتائج الطلبات من FoxReload عبر الاستطلاع

يُسلّم FoxReload نتائج الطلبات عبر الاستطلاع لا الـ webhooks. يغطّي هذا الدليل نمط الاستطلاع وكيفية بناء طبقة إشعارات شبيهة بالـ webhook في خادمك الخاص.

استرجاع نتائج الطلبات من FoxReload — الاستطلاع وبناء طبقة الإشعارات الخاصة بك

لا يرسل FoxReload أي webhooks. لا توجد ترويسة X-FoxReload-Signature، ولا نقطة نهاية لاستدعاء HMAC، ولا تدفّق أحداث order.*. للحصول على نتائج الطلبات — بما في ذلك الأكواد المُسلَّمة — تستطلع GET /api/orders/{order_id}. يشرح هذا الدليل نمط الاستطلاع بالتفصيل ويبيّن كيفية بناء طبقة إشعارات دفع شبيهة بالـ webhook في خادمك الخاص كي تتمكن الأنظمة المستهلِكة في الاتجاه السفلي (متجرك، وبوتك، وطابور التنفيذ لديك) من التفاعل مع اكتمال الطلب دون أن تستطلع هي بنفسها.

1. عقد الاستطلاع

عندما تكون status == "completed"، تكون كل items[].externalData مصفوفة من الأكواد المُسلَّمة أو بيانات التفعيل. وقد يحمل حقل items[].error نص خطأ خاصًا بكل عنصر.

الحالة المعنى إجراؤك
active في انتظار الدفع انتظر أو ادفع عبر /api/orders/{id}/pay
paid تم تأكيد الدفع انتظر
processing تنفيذ المورّد قيد التنفيذ واصل الاستطلاع
completed الأكواد في externalData اقرأ الأكواد وسلّمها
cancelled راجع cancelReason عالِج الأمر بسلاسة
failed فشل التنفيذ نبّه فريق العمليات

2. تنفيذ الاستطلاع

async function waitForCompletion(
  orderId: string,
  apiKey: string,
  maxWaitMs = 600_000,
): Promise<Order> {
  const start = Date.now();
  let delay = 5_000; // start at 5 s

  while (Date.now() - start < maxWaitMs) {
    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 (['completed', 'cancelled', 'failed'].includes(order.status)) {
      return order;
    }
    await sleep(delay);
    delay = Math.min(delay * 1.5, 30_000); // back off up to 30 s
  }
  throw new Error('Order did not complete within timeout');
}

جدول عملي — استطلِع كل 5 ثوانٍ خلال أول 60 ثانية، ثم كل 15–30 ثانية حتى 10 دقائق. إذا لم يصل الطلب بعد ذلك إلى حالة نهائية، فنبّه فريق العمليات لديك.

3. تجنّب الطلبات المكررة عند إعادة المحاولة

لا يمتلك FoxReload مفاتيح idempotency. إذا تلقّيت مهلة أو خطأ شبكة بعد استدعاء POST /api/orders، فلا تُنشئ طلبًا جديدًا على الفور. استدعِ أولًا GET /api/orders?limit=10 للتحقق مما إذا كان الطلب قد أُنشئ فعلًا. إن كان موجودًا فاستطلعه؛ وإن لم يكن، فمن الآمن إنشاء طلب جديد.

4. بناء طبقة الإشعارات غير المتزامنة الخاصة بك

ينبغي ألّا تستطلع مستهلِكاتك الداخلية (تسليم بوت Telegram، ومُرسِل البريد الإلكتروني، وطابور التنفيذ) FoxReload كلٌّ على حدة بشكل مستقل. بدلًا من ذلك، شغّل عامل استطلاع واحدًا لكل طلب ينشر النتائج إلى طابور رسائل أو يُصدِر أحداثًا تشترك فيها خدماتك الداخلية. هذا نمط نظيف وموثوق:

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

يمنحك هذا نموذج دفع شبيهًا بالـ webhook لأنظمتك الداخلية مع تنفيذ عقد استطلاع FoxReload بشكل صحيح.

5. حفظ الأكواد وتسليمها

عندما تكون الحالة completed، اقرأ items[].externalData وخزّن كل كود في قاعدة بياناتك مع معرّف الطلب والطابع الزمني ومرجع العميل قبل التسليم. لا تُسلّم الأكواد أبدًا دون حفظها أولًا — فالفشل في التسليم بعد الحفظ قابل للاسترداد؛ أما التسليم قبل الحفظ فليس كذلك.

for (const item of order.items) {
  for (const data of item.externalData ?? []) {
    await db.codes.insert({
      orderId: order.id,
      productId: item.product.id,
      code: data.code ?? JSON.stringify(data),
      deliveredAt: null,
    });
  }
}
await deliverCodesToCustomer(order.id);
await db.orders.update(order.id, { status: 'delivered', deliveredAt: new Date() });

6. التنبيه على الطلبات المتعطّلة

أضف مهمة مجدولة تتحقق من الطلبات العالقة في processing لأكثر من 10 دقائق وتنبّه فريق المناوبة لديك. يكشف هذا تأخّرات جانب المورّد قبل أن تتحول إلى مشكلات دعم عملاء.

// Run every 5 minutes
const stalled = await db.orders.findAll({
  status: ['paid', 'processing'],
  createdAt: { lt: new Date(Date.now() - 10 * 60_000) },
});
for (const order of stalled) {
  await alertOps(`Order ${order.id} has been processing for >10 min`);
}

يوفّر FoxReload نتيجة الطلب عبر الاستطلاع؛ وكل ما فوق ذلك — التسليم الفوري لعملائك، وحافلات الأحداث الداخلية، وتنبيهات التعطّل — هو بنيتك التحتية التي تتولى بناءها. النمط مباشر ومتين بمجرد إرسائه. اطلب الوصول للبدء.

احصل على وصول API الخاص بـ FoxReload

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