الانتقال إلى المحتوى الرئيسي

الأمان

1. احمِ مفاتيح API الخاصة بك

لا تكشف أبداً عن مفاتيح API في كود frontend أو المستودعات العامة!
# .env file (add to .gitignore)
ONECLICK_API_KEY=your_key_here
const apiKey = process.env.ONECLICK_API_KEY;

2. Backend فقط

استدعِ دائماً API Navio من backend، ولا تفعل ذلك أبداً من frontend:
// ❌ WRONG - Frontend
fetch("https://api.oneclickdz.com/v3/ocpay/createLink", {
  headers: { "X-Access-Token": "YOUR_KEY" }, // Exposed to users!
});

// ✅ CORRECT - Backend
// Frontend calls YOUR API, your backend calls OneClick
fetch("/api/create-payment", { method: "POST" });

3. تحقق من المدخلات

function validateOrderData(data) {
  if (!Number.isInteger(data.amount)) {
    throw new Error("Amount must be integer");
  }

  if (data.amount < 500 || data.amount > 500000) {
    throw new Error("Amount must be between 500 and 500,000 DZD");
  }

  if (!data.title || data.title.trim().length === 0) {
    throw new Error("Title is required");
  }

  return data;
}

4. تحقق قبل التنفيذ

تحقق دائماً من حالة الدفع في backend قبل تنفيذ الطلبات!
async function fulfillOrder(orderId) {
  const order = await db.orders.findOne({ id: orderId });

  // CRITICAL: Verify payment status
  const response = await fetch(
    `https://api.oneclickdz.com/v3/ocpay/checkPayment/${order.paymentRef}`,
    {
      headers: { "X-Access-Token": process.env.ONECLICK_API_KEY },
    }
  );

  const data = await response.json();

  if (data.data.status !== "CONFIRMED") {
    throw new Error("Payment not confirmed");
  }

  // Safe to fulfill
  await processOrder(order);
}

معالجة الأخطاء

معالجة أخطاء API

async function createPaymentSafe(orderId, amount, title) {
  try {
    const response = await fetch(
      "https://api.oneclickdz.com/v3/ocpay/createLink",
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-Access-Token": process.env.ONECLICK_API_KEY,
        },
        body: JSON.stringify({
          productInfo: { title, amount },
        }),
      }
    );

    if (!response.ok) {
      if (response.status === 403) {
        throw new Error("Merchant not validated");
      }
      throw new Error("API request failed");
    }

    const data = await response.json();

    if (!data.success) {
      throw new Error(data.error?.message || "Unknown error");
    }

    return data.data;
  } catch (error) {
    console.error("Payment creation failed:", error);
    throw error;
  }
}

الاختبار

استخدم Sandbox

اختبر بمفاتيح sandbox قبل الإنتاج:
# Development
ONECLICK_API_KEY=sk_sandbox_abc123...

# Production
ONECLICK_API_KEY=sk_live_xyz789...

سيناريوهات الاختبار

اختبر هذه الحالات:
  • ✅ دفع ناجح
  • ✅ دفع فاشل
  • ✅ انتهاء صلاحية رابط الدفع (20 دقيقة)
  • ✅ العميل يعود دون دفع
  • ✅ أخطاء API

قائمة تحقق الإنتاج

قبل الإطلاق:

الأمان

  • مفاتيح API في متغيرات البيئة
  • لا استدعاءات API من frontend
  • التحقق من المدخلات منفَّذ
  • HTTPS مُفعَّل

الوظائف

  • إنشاء الطلب يعمل
  • روابط الدفع تُولَّد بشكل صحيح
  • التحقق من الحالة يعمل
  • تنفيذ الطلبات فقط عند CONFIRMED
  • مهمة cron تعمل

الاختبار

  • اختبار sandbox مكتمل
  • جميع الحالات الحدية مختبرة
  • معالجة الأخطاء مُتحقَّق منها

المراقبة

  • تسجيل الأخطاء مُفعَّل
  • إمكانية عرض الطلبات المعلقة
  • إمكانية التحقق اليدوي من الحالة

الأخطاء الشائعة

تجنّب هذه الأخطاء:
  • ❌ ترميز مفاتيح API مباشرةً في الكود
  • ❌ استدعاء API من frontend
  • ❌ عدم حفظ paymentRef
  • ❌ التنفيذ دون التحقق
  • ❌ غياب معالجة الأخطاء
  • ❌ التحقق بتكرار مفرط (احترم حدود معدل الطلبات)
  • ❌ عدم الاختبار في sandbox أولاً

أفضل ممارسات قاعدة البيانات

أضف فهارس لتحسين الأداء:
-- Speed up pending order queries
CREATE INDEX idx_orders_pending
ON orders(status, payment_ref)
WHERE status = 'PENDING';

-- Speed up paymentRef lookups
CREATE INDEX idx_payment_ref ON orders(payment_ref);

التسجيل

سجّل الأحداث المهمة:
// Log payment creation
console.log("[Payment] Created", {
  orderId,
  paymentRef,
  amount,
  timestamp: new Date(),
});

// Log status changes
console.log("[Payment] Status changed", {
  orderId,
  oldStatus: "PENDING",
  newStatus: "PAID",
  timestamp: new Date(),
});

الخطوات التالية

مرجع API

توثيق API الكامل

التواصل مع الدعم

احصل على مساعدة فريقنا

لوحة التحكم

راقب مدفوعاتك

دليل الأمان

ممارسات أمان متقدمة

أنت جاهز! 🎉

أصبح لديك الآن كل ما تحتاجه لقبول المدفوعات عبر Navio. ابدأ بالـ sandbox، اختبر بدقة، ثم انشر في الإنتاج!