Skip to main content
GET
/
v3
/
mobile
/
check-id
/
{id}
Check Status by ID
curl --request GET \
  --url https://api.oneclickdz.com/v3/mobile/check-id/{id} \
  --header 'X-Access-Token: <api-key>'
{
  "success": true,
  "data": {
    "_id": "<string>",
    "ref": "<string>",
    "status": "<string>",
    "plan_code": "<string>",
    "MSSIDN": "<string>",
    "topup_amount": 123,
    "balance_amount": 123,
    "created_at": "<string>",
    "refund_message": "<string>",
    "suggested_offers": [
      {
        "typename": "<string>",
        "plan_code": "<string>",
        "amount": 123
      }
    ],
    "follow_orderid": "<string>",
    "retry_orderid": "<string>"
  },
  "meta": {
    "timestamp": "<string>"
  }
}

Overview

Track mobile top-up status using the topupId returned from the send endpoint. Generally, our servers will process your request in about 5-30 seconds.
Important: It’s mandatory to understand all possible statuses to properly handle updating and notifying your users.

Path Parameters

id
string
required
Internal top-up ID from /mobile/send response

Response

success
boolean
required
Indicates if the request was successful
data
object
required
meta
object
required

Status Values

The PENDING status indicates that the order has been created and is currently in the queue, awaiting processing by one of our servers. It will be processed as soon as possible.Typical duration: 2-15 secondsAction: Continue polling every 5-10 seconds
The HANDLING status indicates that the order is currently being processed by one of our servers.Typical duration: 3-8 secondsAction: Continue polling every 5-10 seconds
The FULFILLED status indicates that the mobile top-up has been successfully sent. ✅Action: Update order status to completed, notify user
The REFUNDED status indicates that the mobile top-up has been refunded. ❌Fields available:
  • refund_message: Show this to user (in Arabic)
  • suggested_offers: Alternative plans (if plan mismatch)
Action: Refund user, display message, offer alternatives
The UNKNOWN_ERROR status indicates that the mobile top-up might have been successful or failed. The status will update within 1 to 12 hours to either FULFILLED or REFUNDED after manual check by our support team. We will be notified immediately and no action from your part is required. ⚠️Such errors happen due to the nature of AT Commands and unexpected behaviors from operators (new messages, network issues, etc.).
YOU SHOULD NOT REFUND THE AMOUNT to your user at this status!
Action:
  • Show refund_message to user
  • DO NOT refund immediately
  • Set a daily cronjob to check UNKNOWN_ERROR orders and update to FULFILLED or REFUNDED
  • Check again after 24 hours
  • Then handle refunds if status becomes REFUNDED

Examples

curl https://api.oneclickdz.com/v3/mobile/check-id/6901616fe9e88196b4eb64b0 \
  -H "X-Access-Token: YOUR_API_KEY"

Fulfilled Response

{
  "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 Response

{
  "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"
}

Refunded with Suggested Offers

When the plan code doesn’t match the phone number type, you’ll receive suggested alternatives:
{
  "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"
}
PLEASE NOTE: suggested_offers is an array and can contain multiple items, for example when you send GETMENU plans.

Polling Strategy

Syncing Our API with Your Backend

1

Start Polling

Begin checking status immediately after sending top-up. One simple approach is setting an interval of 5-10 seconds on your frontend to check the status. Once the status is FULFILLED, REFUNDED, or UNKNOWN_ERROR, clear the interval and stop sending requests.
const topupId = response.data.topupId;
const status = await pollStatus(topupId);
2

Poll Interval

Check every 5-10 seconds while PENDING or HANDLING. This approach will keep requests minimal (5-10 per transaction).On each GET request from your users, you can read the status in your database. Only if the status is not FULFILLED, REFUNDED, or UNKNOWN_ERROR, send a check request to our API, update your database, then reply to your user.
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

Handle Result

Update order based on final status
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
}

Complete Polling Example

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();

    // Final states
    if (["FULFILLED", "REFUNDED", "UNKNOWN_ERROR"].includes(data.status)) {
      return data;
    }

    // Still processing
    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);
}

Handling UNKNOWN_ERROR

Do NOT refund immediately when status is UNKNOWN_ERROR!
The UNKNOWN_ERROR status indicates uncertainty about whether the top-up succeeded or failed. This happens due to the nature of AT Commands and unexpected behaviors from operators (new messages, network issues, etc.).
1

Show Message

Display refund_message to user explaining the delayExample message: “هذه العملية حالتها غير معروفة، يرجى التأكد مع عميلك، ولن نتحمل أي مسؤولية عن أي خسائر. إذا فشلت العملية بالفعل، فلا تقلق، سيتم استرداد أموالك خلال 24 ساعة”
2

Mark for Review

Flag the order for manual review or automated recheck. We will be notified immediately and no action from your part is required.
3

Automated Recheck

Set up daily cronjob to check uncertain orders. The status will update within 1-12 hours (up to 24h) to either FULFILLED or REFUNDED after manual check by our support team.
// Daily at midnight
cron.schedule('0 0 * * *', async () => {
  const uncertainOrders = await db.orders.find({
    status: 'UNKNOWN_ERROR',
    createdAt: { $lt: new Date(Date.now() - 24*60*60*1000) }
  });
  
  for (const order of uncertainOrders) {
    const status = await checkTopupStatus(order.apiTopupId);
    await updateOrderStatus(order.id, status.data.status);
    
    // Now handle refund if status is REFUNDED
    if (status.data.status === 'REFUNDED') {
      await processRefund(order);
    }
  }
});
4

Final Resolution

Status will update to FULFILLED or REFUNDED within 24 hours. Only then should you process refunds if the final status is REFUNDED.

Best Practices

Cache Status

Store status in your database to minimize API calls. Only query our API when status is not final (PENDING/HANDLING).

Stop on Final State

Don’t poll after FULFILLED, REFUNDED, or UNKNOWN_ERROR

Timeout Protection

Set maximum polling attempts (typically 60 = 5 minutes)

Error Handling

Handle network errors with retry logic

Show Arabic Messages

Always display refund_message to users - it’s in Arabic and explains the issue

Offer Alternatives

When suggested_offers is present, update your UI to show these plans instead of all plans

Handling Refunds

A refund_message (Arabic message) will be added to the top-up operation, and you should show it as-is to your client. Example scenarios:

Wrong Phone Number

If your client types a wrong phone number:
refund_message: "رقم الهاتف خاطئ، يرجى التأكد مع العميل"

Plan Mismatch

If trying to send PREPAID_DJEZZY to a facture (postpaid) phone number:
{
  "refund_message": "هذا العرض غير متوافق مع هذا الرقم جرب فاتورة",
  "suggested_offers": [
    {
      "typename": "📋 FACTURE | فاتورة",
      "plan_code": "FACTURE_DJEZZY",
      "amount": 500
    }
  ]
}

Suggested Offers Array

The suggested_offers array shows the correct plans for the phone number. Update your app UI to represent these new plans instead of showing all plans.
suggested_offers is an array and can contain multiple items, especially when you send GETMENU requests.

Sandbox Testing

Enable the sandbox at your settings page to test requests without affecting your balance. All operations will emulate a real operation:
1

Normal Flow

Any normal phone number:
  • First 5 seconds: status PENDING
  • First 15 seconds: status HANDLING
  • Then: status FULFILLED
After integrating the fulfilled flow, proceed to test other statuses.
2

Test Refund with Message

Phone: 0600000001Test REFUNDED status with refund_message that should be shown to client
3

Test Refund with Suggestions

Phone: 0600000002Test REFUNDED status with refund_message and suggested_offers
4

Test Unknown Error

Phone: 0600000003Test UNKNOWN_ERROR status to ensure your daily cronjob logic works correctly