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

Documentation Index

Fetch the complete documentation index at: https://docs.oneclickdz.com/llms.txt

Use this file to discover all available pages before exploring further.

نظرة عامة

بعد تنفيذ طلبات شحن الإنترنت، احصل على رموز البطاقات وأرقام المعاملات من API وسلّمها للعملاء بأمان. رموز البطاقات ذات قيمة ويجب التعامل معها بعناية.
أمر بالغ الأهمية: رموز البطاقات بيانات حساسة. شفّرها دائماً عند التخزين والإرسال.

بنية بيانات البطاقة

الطلبات المنفَّذة تحتوي على ثلاثة حقول رئيسية:
{
  "status": "FULFILLED",
  "card_code": "123456789012",
  "num_trans": "AT-2025-12345",
  "date_traitement": "2025-11-01T12:00:45.000Z"
}
  • card_code : رمز الشحن القابل للإدخال (المعرّف الرئيسي)
  • num_trans : رقم معاملة اتصالات الجزائر (دليل الشراء)
  • date_traitement : طابع التوقيت للمعالجة
يجب تسليم الحقول الثلاثة للعميل.

مرجع API

GET /v3/internet/check-id/{id}

استرجاع تفاصيل البطاقة المنفَّذة

التخزين الآمن

شفّر رموز البطاقات دائماً قبل تخزينها:
const crypto = require('crypto');

const ENCRYPTION_KEY = process.env.ENCRYPTION_KEY; // Must be 32 bytes
const ALGORITHM = 'aes-256-gcm';

function encryptCardCode(code) {
  const iv = crypto.randomBytes(16);
  const cipher = crypto.createCipheriv(
    ALGORITHM,
    Buffer.from(ENCRYPTION_KEY, 'hex'),
    iv
  );

  let encrypted = cipher.update(code, 'utf8', 'hex');
  encrypted += cipher.final('hex');

  const authTag = cipher.getAuthTag();

  return {
    iv: iv.toString('hex'),
    encryptedData: encrypted,
    authTag: authTag.toString('hex')
  };
}

function decryptCardCode(iv, encryptedData, authTag) {
  const decipher = crypto.createDecipheriv(
    ALGORITHM,
    Buffer.from(ENCRYPTION_KEY, 'hex'),
    Buffer.from(iv, 'hex')
  );

  decipher.setAuthTag(Buffer.from(authTag, 'hex'));

  let decrypted = decipher.update(encryptedData, 'hex', 'utf8');
  decrypted += decipher.final('utf8');

  return decrypted;
}

// Store encrypted card
async function storeCardSecurely(topupId, cardData) {
  const encrypted = encryptCardCode(cardData.card_code);

  await db.internetOrders.updateOne(
    { topupId },
    {
      $set: {
        status: 'FULFILLED',
        encryptedCard: encrypted,
        numTrans: cardData.num_trans,
        dateTraitement: cardData.date_traitement,
        fulfilledAt: new Date()
      }
    }
  );
}

طرق التسليم

1. التسليم عبر البريد الإلكتروني

async function deliverCardViaEmail(userId, topupId, cardData) {
  const user = await db.users.findOne({ _id: userId });

  await sendEmail({
    to: user.email,
    subject: 'Your Internet Card is Ready',
    html: `
      <h2>Your internet recharge card</h2>
      <p>Service: ${cardData.type}</p>
      <p>Number: ${cardData.number}</p>
      <p>Value: ${cardData.topup_amount} DA</p>
      
      <h3>Card Details:</h3>
      <p><strong>Card Code:</strong> ${cardData.card_code}</p>
      <p><strong>Transaction Number:</strong> ${cardData.num_trans}</p>
      <p><strong>Date:</strong> ${new Date(cardData.date_traitement).toLocaleString()}</p>
      
      <h3>How to Use:</h3>
      <p>1. Dial *600# from your ${cardData.type} line</p>
      <p>2. Select "Recharge"</p>
      <p>3. Enter the card code: ${cardData.card_code}</p>
    `
  });
}

2. العرض داخل التطبيق

app.get('/api/internet-orders/:topupId/card', authenticateUser, async (req, res) => {
  const { topupId } = req.params;
  const userId = req.user.id;

  // Verify ownership
  const order = await db.internetOrders.findOne({ topupId, userId });

  if (!order) return res.status(404).json({ error: 'Order not found' });
  if (order.status !== 'FULFILLED') {
    return res.status(400).json({ error: 'Order not fulfilled yet' });
  }

  const cardCode = decryptCardCode(
    order.encryptedCard.iv,
    order.encryptedCard.encryptedData,
    order.encryptedCard.authTag
  );

  res.json({
    topupId: order.topupId,
    type: order.type,
    cardCode,
    transactionNumber: order.numTrans,
    processedDate: order.dateTraitement,
    instructions: getCardUsageInstructions(order.type)
  });
});

function getCardUsageInstructions(type) {
  if (type === 'ADSL') {
    return [
      'Dial *600# from your ADSL line',
      'Select "Recharge"',
      'Enter the card code',
      'Confirm to add credit to your account'
    ];
  } else { // 4G
    return [
      'Dial *600# from your 4G device',
      'Select "Recharge"',
      'Enter the card code',
      'Your data will be activated immediately'
    ];
  }
}

3. التسليم عبر SMS

async function deliverCardViaSMS(phoneNumber, cardData) {
  const message = `Your ${cardData.type} card: ${cardData.card_code}\nTrans: ${cardData.num_trans}\nTo use: Dial *600#`;

  await sendSMS({ to: phoneNumber, message });
}

سير التسليم الكامل

async function completeOrderDelivery(topupId, userId) {
  // 1. Get order details
  const order = await checkTopupStatus(topupId);

  if (order.status !== 'FULFILLED') {
    throw new Error('Order not ready for delivery');
  }

  // 2. Store encrypted card
  await storeCardSecurely(topupId, order);

  // 3. Deliver to customer
  await deliverCardViaEmail(userId, topupId, order);

  // 4. Log delivery (without sensitive data)
  await logCardDelivery(topupId, userId, 'email');

  console.log(`✅ Order ${topupId} delivery complete`);
}

تسجيل التدقيق

سجّل أحداث التسليم دون كشف بيانات البطاقة:
async function logCardDelivery(topupId, userId, method) {
  await db.auditLogs.insertOne({
    event: 'CARD_DELIVERED',
    topupId,
    userId,
    method, // 'email', 'sms', 'in-app'
    timestamp: new Date(),
    ipAddress: req.ip,
    userAgent: req.headers['user-agent']
  });
  
  // ❌ NEVER log actual card codes
  // console.log('Card code:', card.card_code); // DON'T DO THIS
}

تعليمات الاستخدام حسب النوع

قدّم تعليمات واضحة لكل نوع خدمة:
function getCardUsageInstructions(type) {
  const instructions = {
    ADSL: {
      title: 'How to use your ADSL card',
      steps: [
        'Pick up your landline phone',
        'Dial *600#',
        'Select "Recharge" or "Flexy"',
        'Enter your card code: ${cardCode}',
        'Press # to confirm',
        'Your credit will be added immediately'
      ],
      support: 'For help, call 3003 from your ADSL line'
    },
    '4G': {
      title: 'How to use your 4G card',
      steps: [
        'Ensure your 4G SIM is active',
        'Dial *600# from your device',
        'Select "Recharge Internet"',
        'Enter your card code: ${cardCode}',
        'Press # to confirm',
        'Your data will be activated within minutes'
      ],
      support: 'For help, call 3003 from your mobile'
    }
  };
  
  return instructions[type];
}

قائمة التحقق الأمنية

1

توليد مفتاح تشفير

أنشئ مفتاح تشفير آمن بطول 32 بايت وخزّنه في متغيرات البيئة
2

التشفير قبل التخزين

شفّر دائماً card_code قبل الإدراج في قاعدة البيانات
3

التحقق من الملكية

تأكد أن معرّف المستخدم يتطابق مع الطلب قبل عرض البطاقة
4

استخدام HTTPS

تأكد من أن جميع طرق التسليم تستخدم نقلاً مشفراً
5

تسجيل التدقيق

سجّل أحداث التسليم دون تضمين الرموز الفعلية
6

تعليمات واضحة

قدّم تعليمات استخدام خطوة بخطوة لكل نوع خدمة

أفضل الممارسات

التشفير في حالة السكون

شفّر دائماً رموز البطاقة قبل تخزينها في قاعدة البيانات

HTTPS فقط

لا ترسل بطاقات عبر اتصالات غير مشفرة

التحقق من الملكية

تحقق أن المستخدم يملك الطلب قبل عرض البطاقة

لا سجلات نصية

لا تسجّل رموز البطاقة كنص عادي في أي مكان

تضمين التعليمات

قدّم دائماً تعليمات استخدام واضحة

سجل التدقيق

سجّل أحداث التسليم دون بيانات حساسة

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

async function deliverCardSafely(topupId, userId) {
  try {
    await completeOrderDelivery(topupId, userId);
    return { success: true };
  } catch (error) {
    console.error('Delivery failed:', error);
    
    if (error.message.includes('not ready')) {
      return {
        success: false,
        error: 'ORDER_NOT_READY',
        message: 'Order is still processing. Please wait.'
      };
    }
    
    if (error.message.includes('not found')) {
      return {
        success: false,
        error: 'ORDER_NOT_FOUND',
        message: 'Order not found or you do not have access to it.'
      };
    }
    
    return {
      success: false,
      error: 'DELIVERY_FAILED',
      message: 'Failed to deliver card. Please contact support.'
    };
  }
}

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

نظرة عامة

العودة إلى نظرة عامة على التكامل

تتبع الحالة

استعلام تنفيذ الطلبات

أفضل ممارسات الأمان

إرشادات الأمان العامة

إرسال الشحنات

تقديم طلبات الشحن

تحميل المنتجات

جلب البطاقات المتاحة

مرجع API

التوثيق الكامل للـ endpoint