Skip to main content

Overview

Send internet top-up orders after validating phone numbers and checking product availability. Orders are processed with the operator and typically complete within 3-45 seconds.
Always validate numbers first using /check-number to minimize failures and refunds.

API Reference

POST /v3/internet/send

Complete endpoint documentation

Basic Order Submission

async function sendInternetTopup(orderData) {
  const response = await fetch(
    "https://api.oneclickdz.com/v3/internet/send",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-Access-Token": process.env.API_KEY,
      },
      body: JSON.stringify({
        type: orderData.type,      // 'ADSL' or '4G'
        number: orderData.number,   // Phone number
        value: orderData.value,     // Card value
        ref: orderData.ref,         // Your unique reference
      }),
    }
  );

  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.error?.message || `HTTP ${response.status}`);
  }

  const result = await response.json();
  return result.data;
}

// Usage
const order = await sendInternetTopup({
  type: 'ADSL',
  number: '036362608',
  value: 1000,
  ref: `order-${Date.now()}`
});

console.log('Top-up sent:', order.topupId);

Success Response

{
  "success": true,
  "data": {
    "topupId": "6901616fe9e88196b4eb64b2",
    "topupRef": "order-123456"
  },
  "meta": {
    "timestamp": "2025-11-01T12:00:00.000Z"
  }
}

Pre-Order Validation

Always validate before sending orders:
async function validateAndSend(orderData) {
  // Step 1: Validate phone number
  try {
    await validateInternetNumber(orderData.type, orderData.number);
  } catch (error) {
    throw new Error(`Invalid phone number: ${error.message}`);
  }

  // Step 2: Check product availability
  const products = await loadInternetProducts(orderData.type);
  const product = products.find(
    p => p.value === orderData.value && p.available
  );
  
  if (!product) {
    throw new Error(`Product ${orderData.value} DA not available for ${orderData.type}`);
  }

  // Step 3: Check balance
  const balance = await getBalance();
  if (balance < product.cost) {
    throw new Error(
      `Insufficient balance. Required: ${product.cost} DA, Available: ${balance} DA`
    );
  }

  // Step 4: Send order
  console.log(`Sending ${orderData.type} ${orderData.value} DA to ${orderData.number}`);
  const result = await sendInternetTopup(orderData);
  
  return {
    topupId: result.topupId,
    topupRef: result.topupRef,
    cost: product.cost,
    type: orderData.type,
    number: orderData.number,
    value: orderData.value
  };
}

// Helper to get balance
async function getBalance() {
  const response = await fetch(
    "https://api.oneclickdz.com/v3/account/balance",
    {
      headers: { "X-Access-Token": process.env.API_KEY },
    }
  );
  const result = await response.json();
  return result.data.balance;
}

// Usage
try {
  const result = await validateAndSend({
    type: 'ADSL',
    number: '036362608',
    value: 1000,
    ref: `order-${Date.now()}`
  });
  
  console.log('✅ Order placed successfully');
  console.log(`  Top-up ID: ${result.topupId}`);
  console.log(`  Cost: ${result.cost} DA`);
} catch (error) {
  console.error('❌ Order failed:', error.message);
}

Transaction Tracking

Store order details in your database:
async function createOrderTransaction(userId, orderDetails) {
  const transaction = {
    userId,
    topupId: orderDetails.topupId,
    ref: orderDetails.topupRef,
    type: orderDetails.type,
    number: orderDetails.number,
    value: orderDetails.value,
    cost: orderDetails.cost,
    status: 'HANDLING',
    createdAt: new Date(),
    updatedAt: new Date()
  };
  
  await db.internetOrders.insertOne(transaction);
  
  console.log('Transaction saved:', transaction.topupId);
  return transaction;
}

// Usage
const orderResult = await validateAndSend(orderData);
await createOrderTransaction(userId, orderResult);

Generating Unique References

Ensure each order has a unique reference:
function generateOrderReference(userId, type) {
  const timestamp = Date.now();
  const random = Math.random().toString(36).substring(2, 8);
  return `${type.toLowerCase()}-${userId}-${timestamp}-${random}`;
}

// Usage
const ref = generateOrderReference(123, 'ADSL');
// Example: 'adsl-123-1730448000000-x7k2m9'

Error Handling

async function sendTopupSafely(orderData) {
  try {
    const result = await sendInternetTopup(orderData);
    return { success: true, data: result };
  } catch (error) {
    console.error('Order failed:', error);
    
    // Parse error type
    const message = error.message.toLowerCase();
    
    if (message.includes('err_phone')) {
      return {
        success: false,
        error: 'INVALID_PHONE',
        message: 'Invalid phone number for this service type'
      };
    }
    
    if (message.includes('err_stock')) {
      return {
        success: false,
        error: 'OUT_OF_STOCK',
        message: 'This card value is currently out of stock'
      };
    }
    
    if (message.includes('insufficient_balance')) {
      return {
        success: false,
        error: 'LOW_BALANCE',
        message: 'Insufficient account balance'
      };
    }
    
    if (message.includes('duplicated_ref')) {
      return {
        success: false,
        error: 'DUPLICATE_REF',
        message: 'This reference has already been used'
      };
    }
    
    return {
      success: false,
      error: 'UNKNOWN',
      message: 'Failed to process order. Please try again.'
    };
  }
}

Best Practices

Validate First

Always use /check-number before sending

Check Stock

Verify product availability before ordering

Unique References

Generate unique ref for each order

Store Immediately

Save topupId right after successful submission

After Submitting Order

1

Store Top-up ID

Save topupId to your database immediately
2

Start Polling

Begin checking status every 5-10 seconds
3

Update UI

Show “Processing order…” message to user
4

Wait for Final State

Continue polling until FULFILLED, REFUNDED, or QUEUED

Next Steps