Skip to main content
POST
/
v3
/
mobile
/
send
Send Mobile Top-Up
curl --request POST \
  --url https://api.oneclickdz.com/v3/mobile/send \
  --header 'Content-Type: application/json' \
  --header 'X-Access-Token: <api-key>' \
  --data '{
  "plan_code": "<string>",
  "MSSIDN": "<string>",
  "amount": 123,
  "ref": "<string>"
}'
{
  "success": true,
  "data": {
    "topupId": "<string>",
    "topupRef": "<string>"
  },
  "meta": {
    "timestamp": "<string>"
  }
}

Overview

Send instant mobile top-ups to Algerian operators (Mobilis, Djezzy, Ooredoo, Pixx) with real-time status tracking.
Recommended: Use unique ref parameter to prevent duplicate orders and enable easy tracking.

Request Body

plan_code
string
required
Plan code from /mobile/plans endpoint (e.g., PREPAID_DJEZZY, PIXX_500)
MSSIDN
string
required
Phone number in format 0[567][0-9]{8} (must be string, not number) Examples: "0778037340", "0665983439", "0556121212"
amount
integer
Top-up amount in DZD (required for dynamic plans, ignored for fixed plans) Must be between min_amount and max_amount from plan details
ref
string
Your unique order reference for tracking (auto-generated if not provided) Important: Prevents duplicate requests if same ref is submitted twice

Response

success
boolean
required
Indicates if the request was successfully submitted
data
object
required
meta
object
required

Examples

curl https://api.oneclickdz.com/v3/mobile/send \
  -X POST \
  -H "Content-Type: application/json" \
  -H "X-Access-Token: YOUR_API_KEY" \
  -d '{
    "plan_code": "PREPAID_DJEZZY",
    "MSSIDN": "0778037340",
    "amount": 500,
    "ref": "order-12345"
  }'

Success Response

{
  "success": true,
  "data": {
    "topupId": "6901616fe9e88196b4eb64b0",
    "topupRef": "API-+213665983439-test-1761698159224-success"
  },
  "meta": {
    "timestamp": "2025-10-29T00:35:59.454Z"
  }
}

Error Responses

Invalid request body or parameters
{
  "success": false,
  "error": {
    "code": "ERR_VALIDATION",
    "message": "body/MSSIDN must match pattern \"^0[567][0-9]{8}$\"",
    "details": {
      "field": "MSSIDN",
      "value": "778037340"
    }
  },
  "requestId": "req_1730160959_xyz789"
}
Common validation errors:
  • Missing plan_code or MSSIDN
  • Invalid phone number format
  • amount required for dynamic plans
  • amount outside min/max range
  • MSSIDN doesn’t match plan operator
Not enough balance for the operation
{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Your balance is insufficient for this operation",
    "details": {
      "required": 500,
      "available": 250
    }
  },
  "requestId": "req_1730160959_def456"
}
Reference already used
{
  "success": false,
  "error": {
    "code": "DUPLICATED-REF",
    "message": "This reference ID is already in use."
  },
  "requestId": "req_1730160959_ghi789"
}
Solution: Check the status of the existing top-up using the same reference
Server error (rare)
{
  "success": false,
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "Developer was notified and will check shortly"
  },
  "requestId": "req_1730160959_jkl012"
}
Action: Contact support with the requestId. Do NOT refund until investigated.

Phone Number Format

Phone number must be a string, not a number. Leading zero is required.
Valid formats:
  • "0778037340" (string with leading zero)
  • "0665983439"
  • "0556121212"
Invalid formats:
  • 778037340 (missing leading zero)
  • 0778037340 (number type instead of string)
  • "+213778037340" (international format)
  • "0778 037 340" (contains spaces)

Status Lifecycle

After sending a top-up, it goes through these states:
1

PENDING

Order created and queued for processing Duration: 2-15 seconds (typical)
2

HANDLING

Currently being processed by operator Duration: 3-8 seconds (typical)
3

Final State

FULFILLED: Successfully completed ✅ REFUNDED: Failed and refunded ❌ UNKNOWN_ERROR: Uncertain state (resolves in 24h) ⚠️
Learn about Status Tracking →
1

Create Order in Your DB

const order = await db.orders.create({
  id: generateOrderId(),
  userId: user.id,
  phone: '0778037340',
  amount: 500,
  status: 'PROCESSING'
});
2

Deduct User Balance

await db.users.update({
  id: user.id,
  balance: user.balance - 500
});
3

Return Order to User

res.json({
  orderId: order.id,
  status: 'PROCESSING',
  message: 'Top-up is being processed'
});
4

Async: Send to API

// In background job
const response = await sendTopup({
  plan_code: 'PREPAID_DJEZZY',
  MSSIDN: order.phone,
  amount: order.amount,
  ref: order.id
});

await db.orders.update({
  id: order.id,
  apiTopupId: response.data.topupId
});
5

Poll Status & Update

const status = await checkTopupStatus(order.id);

await db.orders.update({
  id: order.id,
  status: status.data.status
});

if (status.data.status === 'REFUNDED') {
  await refundUserBalance(user.id, order.amount);
}

Sandbox Testing

Enable sandbox mode to test without real transactions:

Normal Flow

Use any normal number (e.g., 0778037340) Flow: PENDING (5s) → HANDLING (15s) → FULFILLED

Refund with Message

Use: 0600000001 Returns: REFUNDED with refund_message

Plan Mismatch

Use: 0600000002 Returns: REFUNDED with suggested_offers

Unknown Error

Use: 0600000003 Returns: UNKNOWN_ERROR status
See the Mobile Top-Up Workflow Guide for complete sandbox testing instructions and examples.

Best Practices

Use Unique References

Always provide unique ref to prevent duplicates and enable easy tracking

Validate Before Submit

Check plan, phone format, and balance client-side to reduce errors

Handle Async

Process API calls asynchronously to avoid blocking user requests

Implement Retry Logic

Retry failed requests with exponential backoff for network errors