نظرة عامة
بعد إرسال طلب شحن الإنترنت، استعلم عن endpoint/check-id لتتبع الحالة واسترجاع تفاصيل البطاقة عند التنفيذ. تكتمل معظم الطلبات في 3-45 ثانية، لكن بعضها قد يكون في حالة QUEUED لمدة 12-48 ساعة.استعلم كل 5-10 ثوانٍ حتى يصل الطلب إلى حالة نهائية: FULFILLED أو REFUNDED أو QUEUED.
مرجع API
GET /v3/internet/check-id/{id}
التوثيق الكامل للـ endpoint
قيم حالة الطلب
HANDLING
HANDLING
الطلب قيد المعالجة مع المشغل. المدة المعتادة: 3-45 ثانية. استمر في الاستعلام كل 5-10 ثوانٍ.
FULFILLED
FULFILLED
نجاح! تم تسليم البطاقة.
card_code وnum_trans وdate_traitement متاحة. سلّم للعميل فوراً.QUEUED
QUEUED
مجدول لاحقاً. سيُعالَج الطلب خلال 12-48 ساعة. ليس فشلاً - جدوّل إعادة التحقق وأبلغ العميل.
REFUNDED
REFUNDED
فشل. أُلغي الطلب وأُعيد المبلغ تلقائياً. أبلغ العميل بالفشل.
فحص الحالة الأساسي
async function checkTopupStatus(topupId) {
const response = await fetch(
`https://api.oneclickdz.com/v3/internet/check-id/${topupId}`,
{
headers: {
"X-Access-Token": process.env.API_KEY,
},
}
);
if (!response.ok) {
throw new Error(`Failed to check status: ${response.status}`);
}
const result = await response.json();
return result.data;
}
// Usage
const topupId = "6901616fe9e88196b4eb64b2";
const order = await checkTopupStatus(topupId);
console.log(`Status: ${order.status}`);
console.log(`Type: ${order.type}`);
if (order.card_code) {
console.log(`Card Code: ${order.card_code}`);
console.log(`Transaction: ${order.num_trans}`);
}
import requests
import os
def check_topup_status(topup_id):
response = requests.get(
f'https://api.oneclickdz.com/v3/internet/check-id/{topup_id}',
headers={'X-Access-Token': os.getenv('API_KEY')}
)
response.raise_for_status()
return response.json()['data']
# Usage
topup_id = '6901616fe9e88196b4eb64b2'
order = check_topup_status(topup_id)
print(f"Status: {order['status']}")
if 'card_code' in order:
print(f"Card Code: {order['card_code']}")
print(f"Transaction: {order['num_trans']}")
<?php
function checkTopupStatus($topupId) {
$url = "https://api.oneclickdz.com/v3/internet/check-id/{$topupId}";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-Access-Token: ' . getenv('API_KEY')
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("Failed to check status: " . $httpCode);
}
$result = json_decode($response, true);
return $result['data'];
}
// Usage
$topupId = '6901616fe9e88196b4eb64b2';
$order = checkTopupStatus($topupId);
echo "Status: {$order['status']}\n";
if (isset($order['card_code'])) {
echo "Card Code: {$order['card_code']}\n";
}
?>
curl https://api.oneclickdz.com/v3/internet/check-id/6901616fe9e88196b4eb64b2 \
-H "X-Access-Token: YOUR_API_KEY"
أمثلة على الاستجابة
قيد المعالجة
{
"success": true,
"data": {
"_id": "6901616fe9e88196b4eb64b2",
"ref": "order-123456",
"status": "HANDLING",
"type": "ADSL",
"number": "036362608",
"topup_amount": 1000,
"created_at": "2025-11-01T12:00:00.000Z"
}
}
منفَّذ (نجاح)
{
"success": true,
"data": {
"_id": "6901616fe9e88196b4eb64b2",
"ref": "order-123456",
"status": "FULFILLED",
"type": "ADSL",
"number": "036362608",
"topup_amount": 1000,
"card_code": "123456789012",
"num_trans": "AT-2025-12345",
"date_traitement": "2025-11-01T12:00:45.000Z",
"created_at": "2025-11-01T12:00:00.000Z"
}
}
في قائمة الانتظار
{
"success": true,
"data": {
"_id": "6901616fe9e88196b4eb64b2",
"ref": "order-123456",
"status": "QUEUED",
"type": "ADSL",
"number": "036362608",
"topup_amount": 1000,
"created_at": "2025-11-01T12:00:00.000Z"
}
}
حلقة الاستعلام الأساسية
async function pollTopupUntilComplete(topupId, maxAttempts = 60) {
const pollInterval = 5000; // 5 seconds
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
console.log(`Polling attempt ${attempt}/${maxAttempts}`);
const order = await checkTopupStatus(topupId);
const finalStates = ['FULFILLED', 'REFUNDED', 'QUEUED'];
if (finalStates.includes(order.status)) {
return order;
}
if (attempt < maxAttempts) {
await new Promise(resolve => setTimeout(resolve, pollInterval));
}
}
throw new Error('Polling timeout - order still processing');
}
// Usage
try {
const order = await pollTopupUntilComplete('6901616fe9e88196b4eb64b2');
if (order.status === 'FULFILLED') {
console.log('✅ Card delivered:', order.card_code);
} else if (order.status === 'QUEUED') {
console.log('⏰ Order scheduled for later');
} else if (order.status === 'REFUNDED') {
console.log('❌ Order failed and refunded');
}
} catch (error) {
console.error('Polling failed:', error.message);
}
import time
def poll_topup_until_complete(topup_id, max_attempts=60):
poll_interval = 5 # 5 seconds
for attempt in range(1, max_attempts + 1):
print(f"Polling attempt {attempt}/{max_attempts}")
order = check_topup_status(topup_id)
final_states = ['FULFILLED', 'REFUNDED', 'QUEUED']
if order['status'] in final_states:
return order
if attempt < max_attempts:
time.sleep(poll_interval)
raise Exception('Polling timeout - order still processing')
# Usage
try:
order = poll_topup_until_complete('6901616fe9e88196b4eb64b2')
if order['status'] == 'FULFILLED':
print(f"✅ Card delivered: {order['card_code']}")
elif order['status'] == 'QUEUED':
print('⏰ Order scheduled for later')
elif order['status'] == 'REFUNDED':
print('❌ Order failed and refunded')
except Exception as e:
print(f"Polling failed: {e}")
<?php
function pollTopupUntilComplete($topupId, $maxAttempts = 60) {
$pollInterval = 5; // 5 seconds
for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
$order = checkTopupStatus($topupId);
$finalStates = ['FULFILLED', 'REFUNDED', 'QUEUED'];
if (in_array($order['status'], $finalStates)) {
return $order;
}
if ($attempt < $maxAttempts) {
sleep($pollInterval);
}
}
throw new Exception('Polling timeout - order still processing');
}
?>
استراتيجية الاستعلام المتكيفة
اضبط تكرار الاستعلام بناءً على الوقت المنقضي:async function pollTopupAdaptive(topupId, maxDuration = 5 * 60 * 1000) {
const startTime = Date.now();
let pollInterval = 3000; // Start with 3 seconds
while (Date.now() - startTime < maxDuration) {
const order = await checkTopupStatus(topupId);
// Check for final state
const finalStates = ['FULFILLED', 'REFUNDED', 'QUEUED'];
if (finalStates.includes(order.status)) {
return order;
}
// Adaptive interval: increase as time passes
const elapsed = Date.now() - startTime;
if (elapsed > 60000) {
pollInterval = 10000; // 10 seconds after 1 minute
} else if (elapsed > 30000) {
pollInterval = 5000; // 5 seconds after 30 seconds
}
await new Promise(resolve => setTimeout(resolve, pollInterval));
}
throw new Error('Order processing timeout');
}
// Usage
const order = await pollTopupAdaptive('6901616fe9e88196b4eb64b2');
معالجة نتائج الطلب
async function handleTopupResult(topupId, order) {
switch (order.status) {
case 'FULFILLED':
console.log(`✅ Order fulfilled`);
console.log(`Card: ${order.card_code}`);
console.log(`Transaction: ${order.num_trans}`);
// Update database
await db.internetOrders.updateOne(
{ topupId },
{
$set: {
status: 'FULFILLED',
cardCode: order.card_code,
numTrans: order.num_trans,
dateTraitement: order.date_traitement,
fulfilledAt: new Date()
}
}
);
// Deliver card to customer
await deliverCard(order);
break;
case 'QUEUED':
console.log(`⏰ Order scheduled for later delivery`);
// Update database
await db.internetOrders.updateOne(
{ topupId },
{
$set: {
status: 'SCHEDULED',
message: 'Card will be delivered within 48 hours',
nextCheckAt: new Date(Date.now() + 24 * 60 * 60 * 1000)
}
}
);
// Schedule recheck after 24 hours
await scheduleRecheck(topupId, 24 * 60 * 60 * 1000);
// Notify customer
await notifyCustomer(order,
'Your order is scheduled and will be delivered within 48 hours.'
);
break;
case 'REFUNDED':
console.log(`❌ Order failed and refunded`);
// Update database
await db.internetOrders.updateOne(
{ topupId },
{
$set: {
status: 'REFUNDED',
refundedAt: new Date()
}
}
);
// Notify customer of failure
await notifyCustomer(order,
'Your order could not be completed. A full refund has been issued.'
);
break;
}
}
from datetime import datetime, timedelta
async def handle_topup_result(topup_id, order):
if order['status'] == 'FULFILLED':
print('✅ Order fulfilled')
print(f"Card: {order['card_code']}")
print(f"Transaction: {order['num_trans']}")
db.internet_orders.update_one(
{'topupId': topup_id},
{
'$set': {
'status': 'FULFILLED',
'cardCode': order['card_code'],
'numTrans': order['num_trans'],
'dateTraitement': order['date_traitement'],
'fulfilledAt': datetime.now()
}
}
)
await deliver_card(order)
elif order['status'] == 'QUEUED':
print('⏰ Order scheduled for later delivery')
db.internet_orders.update_one(
{'topupId': topup_id},
{
'$set': {
'status': 'SCHEDULED',
'message': 'Card will be delivered within 48 hours',
'nextCheckAt': datetime.now() + timedelta(hours=24)
}
}
)
await schedule_recheck(topup_id, 24 * 60 * 60 * 1000)
await notify_customer(order,
'Your order is scheduled and will be delivered within 48 hours.'
)
elif order['status'] == 'REFUNDED':
print('❌ Order failed and refunded')
db.internet_orders.update_one(
{'topupId': topup_id},
{'$set': {'status': 'REFUNDED', 'refundedAt': datetime.now()}}
)
await notify_customer(order,
'Your order could not be completed. A full refund has been issued.'
)
<?php
function handleTopupResult($topupId, $order) {
switch ($order['status']) {
case 'FULFILLED':
error_log('✅ Order fulfilled');
error_log("Card: {$order['card_code']}");
error_log("Transaction: {$order['num_trans']}");
updateOrderStatus($topupId, 'FULFILLED', [
'cardCode' => $order['card_code'],
'numTrans' => $order['num_trans'],
'dateTraitement' => $order['date_traitement'],
'fulfilledAt' => date('Y-m-d H:i:s')
]);
deliverCard($order);
break;
case 'QUEUED':
error_log('⏰ Order scheduled for later delivery');
updateOrderStatus($topupId, 'SCHEDULED', [
'message' => 'Card will be delivered within 48 hours',
'nextCheckAt' => date('Y-m-d H:i:s', time() + 24 * 60 * 60)
]);
scheduleRecheck($topupId, 24 * 60 * 60);
notifyCustomer($order,
'Your order is scheduled and will be delivered within 48 hours.'
);
break;
case 'REFUNDED':
error_log('❌ Order failed and refunded');
updateOrderStatus($topupId, 'REFUNDED', [
'refundedAt' => date('Y-m-d H:i:s')
]);
notifyCustomer($order,
'Your order could not be completed. A full refund has been issued.'
);
break;
}
}
?>
معالجة حالة QUEUED
الطلبات في حالة QUEUED ليست فشلاً! إنها مجدولة للتسليم خلال 12-48 ساعة.
async function handleTopupResult(order) {
switch (order.status) {
case 'FULFILLED':
await storeCardSecurely(order._id, order);
await deliverCardToCustomer(order._id, order);
console.log('✅ Topup fulfilled and delivered');
break;
case 'QUEUED':
await updateOrderStatus(order._id, 'QUEUED');
await scheduleRecheck(order._id, 24 * 60 * 60 * 1000); // 24 hours
await notifyCustomerQueued(order._id);
console.log('⏰ Topup queued - will recheck in 24 hours');
break;
case 'REFUNDED':
await updateOrderStatus(order._id, 'FAILED');
await notifyCustomerRefunded(order._id);
console.log('❌ Topup failed and refunded');
break;
}
}
اختبار كل الحالات في sandbox
بمفتاح sandbox، الرقم الذي ترسله هو الذي يحدد سلوك الطلب — فتختبر كل مسار في كود الاستعلام لديك دون انتظار طلب حقيقي. تتقدم الحالات وحدها مع مرور الوقت؛ استعلم تمامًا كما تفعل في الإنتاج.| الرقم | المسار | تختبر به |
|---|---|---|
030000001 | HANDLING ← REFUNDED بعد 3 ثوانٍ | مسار الفشل/الاسترداد |
030000002 | HANDLING ← QUEUED بعد 3 ثوانٍ ← FULFILLED بعد 15 ثانية | مسار إعادة فحص QUEUED |
| أي رقم صالح آخر | HANDLING ← FULFILLED بعد 3 ثوانٍ | المسار الناجح وتسليم البطاقة |
030000000 | يُرفض في /send بالخطأ ERR_PHONE | مسار خطأ التحقق |
// نفس حلقة الاستعلام كما في الإنتاج — يتغير الرقم فقط
const { data } = await sendTopup({ type: 'ADSL', number: '030000002', value: 1000 });
await pollTopupStatus(data.topupId);
// t=0s HANDLING
// t=4s QUEUED ← هنا ينطلق مجدول إعادة الفحص لديك
// t=19s FULFILLED card_code: "TESTCARD", num_trans: "TESTTRANS"
الطلب المكتمل في sandbox يعيد
card_code: "TESTCARD" و\u200Enum_trans: "TESTTRANS" بدل القيم الحقيقية. وكل ما عدا ذلك — شكل الاستجابة وأسماء الحالات وسلوك الاستعلام — مطابق للإنتاج.أفضل الممارسات
الاستعلام كل 5-10 ثوانٍ
توازن بين الاستجابة وعدد طلبات API
معالجة QUEUED بشكل صحيح
لا تعامل QUEUED كفشل - جدوّل إعادة التحقق بعد 24 ساعة
تحديد حد أقصى للوقت
أوقف الاستعلام بأمان بعد 5 دقائق
تحديث قاعدة البيانات
سجّل تغييرات الحالة وبيانات البطاقة عند كل تحديث
الخطوات التالية
تسليم البطاقات
تسليم رموز البطاقات بأمان للعملاء
إرسال الشحنات
تقديم طلبات مع التحقق
مرجع API
التوثيق الكامل للـ endpoint

