التحقق من الحالة بالمعرّف
curl --request GET \
--url https://api.oneclickdz.com/v3/mobile/check-id/{id} \
--header 'X-Access-Token: <api-key>'import requests
url = "https://api.oneclickdz.com/v3/mobile/check-id/{id}"
headers = {"X-Access-Token": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-Access-Token': '<api-key>'}};
fetch('https://api.oneclickdz.com/v3/mobile/check-id/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.oneclickdz.com/v3/mobile/check-id/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-Access-Token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.oneclickdz.com/v3/mobile/check-id/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-Access-Token", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.oneclickdz.com/v3/mobile/check-id/{id}")
.header("X-Access-Token", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.oneclickdz.com/v3/mobile/check-id/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-Access-Token"] = '<api-key>'
response = http.request(request)
puts response.read_bodyشحن الهاتف
التحقق من الحالة بالمعرّف
التحقق من حالة شحن الهاتف المحمول باستخدام المعرّف الداخلي
GET
/
v3
/
mobile
/
check-id
/
{id}
التحقق من الحالة بالمعرّف
curl --request GET \
--url https://api.oneclickdz.com/v3/mobile/check-id/{id} \
--header 'X-Access-Token: <api-key>'import requests
url = "https://api.oneclickdz.com/v3/mobile/check-id/{id}"
headers = {"X-Access-Token": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-Access-Token': '<api-key>'}};
fetch('https://api.oneclickdz.com/v3/mobile/check-id/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.oneclickdz.com/v3/mobile/check-id/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-Access-Token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.oneclickdz.com/v3/mobile/check-id/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-Access-Token", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.oneclickdz.com/v3/mobile/check-id/{id}")
.header("X-Access-Token", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.oneclickdz.com/v3/mobile/check-id/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-Access-Token"] = '<api-key>'
response = http.request(request)
puts response.read_bodyنظرة عامة
يُرجع حالة شحن هاتف محمول باستخدامtopupId المُرجع في استجابة إرسال الشحن.إذا حددت
ref عند إرسال الشحن، يُفضَّل استخدام check-by-ref إذ يعتمد على معرّفاتك الخاصة.المعلمات
string
مطلوب
المعرّف الداخلي للشحن المُرجع في استجابة send-topup
الاستجابة
boolean
مطلوب
true إذا تم العثور على الشحن وإرجاع حالتهobject
مطلوب
إظهار properties
إظهار properties
string
معرّف الشحن الداخلي
string
مرجعك الداخلي (إذا أُوفِّر عند الإرسال)
string
الحالة الحالية للشحن:
PENDING: قيد المعالجةSUCCESS: اكتمل الشحنFAILED: فشل بشكل نهائي (الرصيد مُسترد)UNKNOWN_ERROR: حالة غير محددة - انتظر، لا تسترد الأموال
string
رقم الهاتف الذي تم شحنه
string
مشغّل الشبكة:
Mobilis، Djezzy، أو Ooredoostring
رمز الخطة المستخدمة
string
الاسم المقروء للخطة
number
مبلغ الشحن بالدينار الجزائري
number
التكلفة الفعلية من رصيدك
string
طابع زمني للإنشاء (ISO 8601)
string
طابع زمني لآخر تحديث للحالة (ISO 8601)
قيم الحالة
| الحالة | المعنى | الإجراء |
|---|---|---|
PENDING | الشحن قيد المعالجة | تحقق مجددًا بعد 5-10 ثوانٍ |
SUCCESS | الشحن اكتمل بنجاح | أبلغ المستخدم بالنجاح |
FAILED | الشحن فشل نهائيًا | الرصيد مُسترد - يمكن المحاولة مجددًا |
UNKNOWN_ERROR | حالة غير محددة | انتظر 24 ساعة - لا تسترد الأموال |
إذا رأيت
UNKNOWN_ERROR، لا تسترد الأموال فورًا ولا ترسل الشحن مجددًا. تحقق من الحالة مرة أخرى بعد 24 ساعة. غالبًا ما تُكمل العملية في النهاية.الأمثلة
curl https://api.oneclickdz.com/v3/mobile/topup/6901616fe9e88196b4eb64b0 \
-H "X-Access-Token: YOUR_API_KEY"
const topupId = "6901616fe9e88196b4eb64b0";
const response = await fetch(
`https://api.oneclickdz.com/v3/mobile/topup/${topupId}`,
{
headers: { "X-Access-Token": "YOUR_API_KEY" },
}
);
const data = await response.json();
console.log("Status:", data.data.status);
import requests
topup_id = '6901616fe9e88196b4eb64b0'
response = requests.get(
f'https://api.oneclickdz.com/v3/mobile/topup/{topup_id}',
headers={'X-Access-Token': 'YOUR_API_KEY'}
)
data = response.json()
print('Status:', data['data']['status'])
<?php
$topupId = '6901616fe9e88196b4eb64b0';
$ch = curl_init("https://api.oneclickdz.com/v3/mobile/topup/{$topupId}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['X-Access-Token: YOUR_API_KEY']);
$data = json_decode(curl_exec($ch), true);
echo 'Status: ' . $data['data']['status'];
?>
مثال على الاستجابة — تم التنفيذ (FULFILLED)
{
"success": true,
"data": {
"_id": "6901616fe9e88196b4eb64b0",
"ref": "order-12345",
"status": "FULFILLED",
"plan_code": "PREPAID_DJEZZY",
"MSSIDN": "0778037340",
"topup_amount": 500,
"balance_amount": 490,
"created_at": "2025-10-29T00:35:59.378Z"
},
"meta": { "timestamp": "2025-10-29T00:36:15.606Z" },
"requestId": "req_1730160975_abc123"
}
مثال على الاستجابة — مُسترَد (REFUNDED)
{
"success": true,
"data": {
"_id": "6901616fe9e88196b4eb64b0",
"ref": "order-12345",
"status": "REFUNDED",
"plan_code": "PREPAID_DJEZZY",
"MSSIDN": "0778037340",
"topup_amount": 500,
"balance_amount": 490,
"created_at": "2025-10-29T00:35:59.378Z",
"refund_message": "الرصيد المطلوب غير متوفر لهذا الرقم"
},
"meta": { "timestamp": "2025-10-29T00:36:15.606Z" },
"requestId": "req_1730160975_def456"
}
مُسترَد مع عروض مقترحة
عندما لا يتطابق كود الخطة مع نوع رقم الهاتف، ستتلقى بدائل مقترحة:{
"success": true,
"data": {
"_id": "6901616fe9e88196b4eb64b0",
"ref": "order-12345",
"status": "REFUNDED",
"plan_code": "PREPAID_DJEZZY",
"MSSIDN": "0778037340",
"topup_amount": 500,
"balance_amount": 490,
"created_at": "2025-10-29T00:35:59.378Z",
"refund_message": "هذا العرض غير متوافق مع هذا الرقم جرب فاتورة",
"suggested_offers": [
{
"typename": "📋 FACTURE | فاتورة",
"plan_code": "FACTURE_DJEZZY",
"amount": 500
}
]
},
"meta": { "timestamp": "2025-10-29T00:36:15.606Z" },
"requestId": "req_1730160975_ghi789"
}
ملاحظة:
suggested_offers مصفوفة ويمكن أن تحتوي على عدة عناصر، مثلاً عند إرسال خطط GETMENU.استراتيجية الاستعلام
مزامنة API مع قاعدة بياناتك
1
ابدأ الاستعلام
ابدأ التحقق من الحالة فور إرسال الشحن. يمكنك ضبط interval كل 5-10 ثوانٍ على واجهتك للتحقق من الحالة. عند الوصول إلى FULFILLED أو REFUNDED أو UNKNOWN_ERROR، أوقف الاستعلام.
2
فترة الاستعلام
تحقق كل 5-10 ثوانٍ طالما الحالة PENDING أو HANDLING.
async function pollStatus(topupId, maxAttempts = 60) {
for (let i = 0; i < maxAttempts; i++) {
const { data } = await checkTopupStatus(topupId);
if (['FULFILLED', 'REFUNDED', 'UNKNOWN_ERROR'].includes(data.status)) {
return data;
}
await sleep(5000); // Wait 5 seconds
}
throw new Error('Timeout');
}
3
معالجة النتيجة
حدّث الطلب بناءً على الحالة النهائية
if (status === 'FULFILLED') {
await markOrderComplete(orderId);
} else if (status === 'REFUNDED') {
await refundUser(orderId);
await notifyUser(refund_message);
} else if (status === 'UNKNOWN_ERROR') {
await markForReview(orderId);
// DO NOT refund yet - wait for daily cronjob
}
مثال الاستعلام الكامل
async function pollTopupStatus(topupId) {
const maxAttempts = 60; // 5 minutes max
const pollInterval = 5000; // 5 seconds
for (let i = 0; i < maxAttempts; i++) {
const response = await fetch(
`https://api.oneclickdz.com/v3/mobile/check-id/${topupId}`,
{ headers: { "X-Access-Token": process.env.API_KEY } }
);
const { data } = await response.json();
if (["FULFILLED", "REFUNDED", "UNKNOWN_ERROR"].includes(data.status)) {
return data;
}
console.log(`Attempt ${i + 1}: Status is ${data.status}`);
await new Promise((resolve) => setTimeout(resolve, pollInterval));
}
throw new Error("Polling timeout after 5 minutes");
}
// Usage
try {
const result = await pollTopupStatus("6901616fe9e88196b4eb64b0");
console.log("Final status:", result.status);
} catch (error) {
console.error("Polling failed:", error.message);
}
import requests
import time
def poll_topup_status(topup_id, max_attempts=60, poll_interval=5):
url = f'https://api.oneclickdz.com/v3/mobile/check-id/{topup_id}'
headers = {'X-Access-Token': 'YOUR_API_KEY'}
for attempt in range(max_attempts):
response = requests.get(url, headers=headers)
data = response.json()['data']
if data['status'] in ['FULFILLED', 'REFUNDED', 'UNKNOWN_ERROR']:
return data
print(f"Attempt {attempt + 1}: Status is {data['status']}")
time.sleep(poll_interval)
raise TimeoutError('Polling timeout after 5 minutes')
# Usage
try:
result = poll_topup_status('6901616fe9e88196b4eb64b0')
print(f"Final status: {result['status']}")
except TimeoutError as e:
print(f"Error: {e}")
معالجة UNKNOWN_ERROR
async function handleTopUpStatus(topupId) {
const response = await fetch(
`https://api.oneclickdz.com/v3/mobile/topup/${topupId}`,
{
headers: { "X-Access-Token": API_KEY },
}
);
const data = await response.json();
const { status } = data.data;
switch (status) {
case "SUCCESS":
await markOrderComplete(topupId);
await notifyUser("success");
break;
case "FAILED":
await markOrderFailed(topupId);
await notifyUser("failed");
// Balance is refunded - safe to retry
break;
case "UNKNOWN_ERROR":
// DO NOT refund or retry immediately
// Schedule a re-check after 24 hours
await scheduleStatusRecheck(topupId, 24 * 60 * 60 * 1000);
await notifyUser("pending_review");
break;
case "PENDING":
// Still processing - check again later
break;
}
}
الاستطلاع مع Backoff الأسي
async function pollTopUpByIdWithBackoff(topupId) {
const delays = [5000, 10000, 20000, 30000, 60000]; // ms
for (const delay of delays) {
const response = await fetch(
`https://api.oneclickdz.com/v3/mobile/topup/${topupId}`,
{
headers: { "X-Access-Token": API_KEY },
}
);
const data = await response.json();
const { status } = data.data;
if (status === "SUCCESS" || status === "FAILED" || status === "UNKNOWN_ERROR") {
return data.data;
}
// Still PENDING - wait before next check
await new Promise((resolve) => setTimeout(resolve, delay));
}
// After all retries, schedule a long-term check
return { status: "TIMEOUT", requiresManualReview: true };
}
أفضل الممارسات
تخزين الحالة مؤقتاً
خزّن الحالة في قاعدة البيانات لتقليل استدعاءات API. استعلم من API الخاصة بنا فقط عندما لا تكون الحالة نهائية (PENDING/HANDLING).
أوقف عند الحالة النهائية
لا تستمر بالاستعلام بعد FULFILLED أو REFUNDED أو UNKNOWN_ERROR
حماية من المهلة الزمنية
حدد حداً أقصى لمحاولات الاستعلام (عادة 60 = 5 دقائق)
معالجة الأخطاء
تعامل مع أخطاء الشبكة بمنطق إعادة المحاولة
أظهر الرسائل بالعربية
أظهر دائماً
refund_message للمستخدمين — وهي بالعربية وتشرح المشكلةعرض بدائل
عند وجود
suggested_offers، حدّث واجهتك لإظهار هذه الخطط بدلاً من جميع الخططمعالجة الاسترداد
سيُضافrefund_message (رسالة باللغة العربية) إلى عملية الشحن، ويجب عرضه كما هو للعميل.أمثلة على السيناريوهات:رقم هاتف خاطئ
إذا أدخل العميل رقم هاتف خاطئ:refund_message: "رقم الهاتف خاطئ، يرجى التأكد مع العميل"
عدم تطابق الخطة
عند إرسال PREPAID_DJEZZY إلى رقم فاتورة (postpaid):{
"refund_message": "هذا العرض غير متوافق مع هذا الرقم جرب فاتورة",
"suggested_offers": [
{
"typename": "📋 FACTURE | فاتورة",
"plan_code": "FACTURE_DJEZZY",
"amount": 500
}
]
}
مصفوفة suggested_offers
تُظهر المصفوفةsuggested_offers الخطط الصحيحة لرقم الهاتف. حدّث واجهة تطبيقك لعرض هذه الخطط الجديدة بدلاً من عرض جميع الخطط.مصفوفة
suggested_offers يمكن أن تحتوي على عدة عناصر، خاصة عند إرسال طلبات GETMENU.الاختبار في بيئة Sandbox
فعّل وضع Sandbox من صفحة الإعدادات لاختبار الطلبات دون التأثير على رصيدك.جميع العمليات ستحاكي عملية حقيقية:1
السير الطبيعي
أي رقم هاتف عادي:
- أول 5 ثوانٍ: الحالة
PENDING - أول 15 ثانية: الحالة
HANDLING - ثم: الحالة
FULFILLED
2
اختبار الاسترداد مع رسالة
الهاتف: 0600000001اختبار حالة REFUNDED مع
refund_message يجب عرضه للعميل3
اختبار الاسترداد مع اقتراحات
الهاتف: 0600000002اختبار حالة REFUNDED مع
refund_message وsuggested_offers4
اختبار الخطأ غير المعروف
الهاتف: 0600000003اختبار حالة
UNKNOWN_ERROR للتأكد من صحة منطق cron job اليوميEndpoints ذات الصلة
التحقق من الحالة بالمرجع
البحث باستخدام مرجعك الداخلي
إرسال الشحن
إرسال شحن هاتف محمول

