المطورون/التكامل
شحن رصيد الهاتف المحمول
يشحن هذا المنتج رقم هاتف مدفوعًا مسبقًا بشكل مباشر. يحصل عميلك على رصيد مكالمات أو بيانات على خطه، ولا يوجد كود لتسليمه. وتدفع القيمة من محفظتك لدى CardV، تمامًا كما في الطلبات الأخرى.
ذات صلة: المصادقة · القواعد العامة · Webhook
#كيف يعمل
GET /recharge/countries الدول التي يمكنك الشحن فيها
GET /recharge/operators?country=US المشغّلون وأنواع الشحن والمبالغ
POST /recharge/quote سعرك، وقيمة quote_token صالحة لمدة 300 ثانية
POST /recharge/orders إرسال الطلب، ويُدفع من محفظتك
GET /recharge/orders/{order_id} الاستعلام عن الحالة، أو انتظار Webhook- تبدأ كل المسارات بـ
/api/v1. أرسل الترويسات نفسها كما في كل استدعاء. - يجب توقيع استدعاءي
POST. وقّعهما بالطريقة نفسها المتبعة معPOST/orders، لكن استخدم مسار كل منهما، مثل/api/v1/recharge/quote. - طلبات الشحن منفصلة عن طلبات بطاقات الهدايا. استخدم نقاط النهاية
/rechargeلقراءتها. - نوفّر الشحن المباشر فقط، ولا نوفّر منتجات PIN (كود يُدخله العميل بنفسه).
#الدول
يعرض GET/api/v1/recharge/countries الدول التي يمكنك الشحن فيها الآن.
{
"count": 2,
"results": [
{"code": "MX", "name": "Mexico", "currency_codes": ["MXN"], "operator_count": 4, "offer_count": 37},
{"code": "US", "name": "United States", "currency_codes": ["USD"], "operator_count": 6, "offer_count": 52}
]
}codeهو رمز الدولة وفق ISO 3166-1 alpha-2. أرسله في الحقلcountryفي الاستدعاءات التالية.currency_codesهي العملات المحلية التي يبيع بها المشغّلون في هذه الدولة.- تتغيّر القائمة عند إضافة مشغّلين أو توقّف توفّرهم. حمّلها من جديد كل بضع ساعات.
#المشغّلون
يعرض GET/api/v1/recharge/operators?country=US مشغّلي الاتصالات في دولة واحدة.
أضف search=att للتصفية حسب اسم المشغّل.
{
"count": 1,
"results": [
{
"operator_key": "us-att",
"name": "AT&T",
"country": "US",
"country_name": "United States",
"logo_url": "https://b2b.cardv.net/api/v1/catalog-assets/3f5c...a1.png",
"subtypes": ["airtime", "data"],
"amount_model": "range",
"currency_codes": ["USD"],
"amounts": [
{"min": "5.0000", "max": "100.0000", "currency": "USD", "subtype": "airtime", "label": "5.0000-100.0000 USD"},
{"min": "15.0000", "max": "15.0000", "currency": "USD", "subtype": "data", "label": "15.0000 USD"}
],
"offer_count": 3
}
]
}| الحقل | المعنى |
|---|---|
operator_key | الرقم الذي ترسله في عرض السعر وفي الطلب، مثل us-att. احفظه كنص. |
subtypes | ما يمكنك شراؤه: airtime (رصيد مكالمات) أو data أو bundle (مكالمات وبيانات). |
amount_model | fixed إذا كانت كل المبالغ قيمًا محددة، وrange إذا كان أي مبلغ منها نطاقًا. |
amounts[] | كل خيار متاح. إذا تساوى min وmax فهو مبلغ ثابت، وإلا فأي مبلغ بينهما. |
amounts[].currency | العملة المحلية لهذا الخيار. أرسلها في الحقل local_currency. |
logo_url | صورة تستضيفها CardV، أو "". |
- المبالغ مبالغ محلية: أي ما يصل إلى خط الهاتف، بالعملة المحلية.
- قيمة
countryغير معروفة أو بصيغة غير صحيحة تُرجع HTTP 400.
#عرض السعر
يُرجع POST/api/v1/recharge/quote سعرك لعملية شحن واحدة. ويجب توقيع هذا الاستدعاء.
{
"country": "US",
"operator_key": "us-att",
"amount": "10.00",
"local_currency": "USD",
"subtype": "airtime"
}| الحقل | إلزامي؟ | المعنى |
|---|---|---|
country | نعم | رمز الدولة من قائمة الدول. |
operator_key | نعم | من قائمة المشغّلين. |
amount | نعم | المبلغ المحلي كنص. في المبلغ الثابت: إحدى القيم المدرجة. في النطاق: بين min وmax. |
local_currency | موصى به | رمز ISO 4217 لعملة amount، من amounts[].currency. أرسله إذا كان المشغّل يعرض أكثر من عملة. |
subtype | لا | airtime (الافتراضي) أو data أو bundle. |
الرد:
{
"country": "US",
"country_name": "United States",
"operator": {"operator_key": "us-att", "name": "AT&T", "logo_url": ""},
"subtype": "airtime",
"local_amount": "10.0000",
"local_currency": "USD",
"merchant_price": "9.6200",
"merchant_currency": "USD",
"expires_at": "2026-09-30T08:20:30.123456+00:00",
"quote_token": "eyJ2ZXJzaW9uIjox...:1uXyZa:8c1f..."
}merchant_priceهو ما تدفعه من محفظتك، بعملةmerchant_currency.- تثبّت قيمة
quote_tokenهذا السعر لمدة 300 ثانية، حتىexpires_at. أرسلها مع الطلب دون تغيير. - ترتبط هذه القيمة بحسابك وبالدولة والمشغّل والنوع والمبلغ نفسها.
- تأكد من أن
local_currencyهي العملة التي تتوقعها قبل إرسال الطلب. - عرض السعر لا يحجز أي مبلغ، ويمكنك طلب عرض سعر جديد في أي وقت.
#إرسال طلب شحن
يشحن POST/api/v1/recharge/orders الهاتف، ويدفع القيمة من محفظتك. ويجب توقيع هذا الاستدعاء.
{
"external_order_id": "SHOP-RC-20260930-0001",
"country": "US",
"operator_key": "us-att",
"amount": "10.00",
"local_currency": "USD",
"subtype": "airtime",
"account": "12125550100",
"quote_token": "eyJ2ZXJzaW9uIjox...:1uXyZa:8c1f..."
}| الحقل | إلزامي؟ | المعنى |
|---|---|---|
external_order_id | نعم | رقم طلبك، ولا يتكرر بين كل طلباتك، بما فيها طلبات بطاقات الهدايا. |
country، operator_key، amount، local_currency، subtype | نعم | القيم نفسها التي أرسلتها في عرض السعر. |
account | نعم | رقم الهاتف المراد شحنه: أرقام فقط، مع رمز الدولة، دون + أو مسافات. |
quote_token | نعم | من عرض السعر، قبل انتهاء صلاحيته. |
أمثلة على أرقام الهواتف: 12125550100 (الولايات المتحدة)، و525512345678 (المكسيك).
تأكد من أن الرقم تابع للمشغّل الذي اخترته، فالشحن المرسل إلى رقم خاطئ لا يمكن التراجع عنه.
تتحقق CardV من عرض السعر، وتخصم merchant_price من محفظتك فورًا، ثم تبدأ الشحن في الخلفية.
الطلب الجديد يُرجع HTTP 201:
{
"idempotent_replay": false,
"order": {
"order_id": "O-00005678",
"external_order_id": "SHOP-RC-20260930-0001",
"status": "accepted",
"status_title": "Recharge accepted",
"poll_after_seconds": 12,
"account": "12***00",
"local_amount": "10.0000",
"local_currency": "USD",
"merchant_price": "9.6200",
"merchant_currency": "USD",
"...": "more fields"
}
}- احفظ
order.order_id. - يُرجَع رقم الهاتف مخفيًا جزئيًا، ولا يُرجَع كاملًا أبدًا.
#إعادة المحاولة بأمان
يحميك external_order_id من شحن الهاتف مرتين.
| ما ترسله | ما تحصل عليه |
|---|---|
| رقم طلب جديد | HTTP 201. طلب جديد، ويُخصم المبلغ من محفظتك. |
| رقم الطلب نفسه وعملية الشحن نفسها | HTTP 200 و"idempotent_replay": true. الطلب الموجود، دون أي خصم. |
| رقم الطلب نفسه لكن بعملية شحن مختلفة | HTTP 400 على external_order_id. لا يحدث شيء. |
"عملية الشحن نفسها" تعني الدولة والمشغّل والنوع والمبلغ ورقم الهاتف نفسها.
تتعرّف CardV على الطلب المكرر قبل التحقق من عرض السعر، لذلك تُرجع الطلب الأول حتى لو انتهت صلاحية quote_token.
- بعد انتهاء المهلة أو خطأ 5xx أو انقطاع الاتصال، أرسل المحتوى نفسه برقم الطلب نفسه. ووقّعه من جديد بطابع زمني وقيمة nonce جديدين.
- لا تنشئ رقم طلب جديدًا لمجرد أن الرد لم يصلك. فقد يؤدي ذلك إلى شحن الهاتف مرتين.
#قراءة طلبات الشحن
يُرجع GET/api/v1/recharge/orders/{order_id} طلبًا واحدًا.
ويمكنك استخدام رقم طلب CardV (O-00005678).
{
"order_id": "O-00005678",
"external_order_id": "SHOP-RC-20260930-0001",
"status": "processing",
"order_status": "processing",
"status_title": "Recharge processing",
"status_message": "The recharge request is being processed. Delivery is not confirmed yet.",
"next_step": "Keep this order open and wait for confirmation before placing another recharge.",
"poll_after_seconds": 12,
"country": "US",
"operator": {"operator_key": "us-att", "name": "AT&T", "logo_url": ""},
"subtype": "airtime",
"account": "12***00",
"local_amount": "10.0000",
"local_currency": "USD",
"merchant_price": "9.6200",
"merchant_currency": "USD",
"attempts": [{"attempt_no": 1, "status": "processing", "error_message": "", "submitted_at": "2026-09-30T08:16:02.511201Z", "completed_at": null}],
"created_at": "2026-09-30T08:16:01.004211Z",
"updated_at": "2026-09-30T08:16:02.611978Z",
"...": "more fields"
}- رقم طلب غير معروف، أو طلب يخص حسابًا آخر، يُرجع HTTP 404.
status_titleوstatus_messageوnext_stepنصوص باللغة الإنجليزية يمكنك عرضها على موظفيك.poll_after_secondsهي المدة التي تنتظرها قبل الاستعلام التالي. والقيمة0تعني أن الطلب اكتمل.
#قائمة طلبات الشحن
يعرض GET/api/v1/recharge/orders طلبات الشحن الخاصة بك، من الأحدث إلى الأقدم.
GET /api/v1/recharge/orders?status=processing&limit=50&offset=0{"count": 3, "limit": 50, "results": ["..."]}- عوامل التصفية:
status، وsearch(رقم طلب CardV أو رقم طلبك أو اسم المشغّل). - القيمة الافتراضية لـ
limitهي 20، والحد الأقصى 100. أي قيمة أكبر تُخفَّض إلى 100. - إذا كانت
limitأوoffsetسالبة أو ليست رقمًا، تحصل على HTTP 400.
#الحالة
accepted ──► processing ──► succeeded
│
├──► manual_review ──► succeeded أو refunded
│
└──► failed ──► refunded (أُعيد المبلغ إلى محفظتك)| الحالة | هل اكتمل؟ | ما الذي تفعله |
|---|---|---|
accepted | لا | انتظر. خُصم المبلغ من المحفظة، ولم يبدأ الشحن بعد. |
processing | لا | انتظر. قد يستغرق الأمر عدة دقائق. لا ترسل الطلب مرة أخرى. |
manual_review | لا | تتحقق CardV من النتيجة مع المشغّل. انتظر. |
succeeded | نعم | شُحن الهاتف. أبلغ عميلك. |
failed | ليس بعد | لم تتم عملية الشحن. انتظر refunded. |
refunded | نعم | عاد المبلغ إلى محفظتك. يمكنك إرسال طلب جديد. |
- استعلم بعد
poll_after_seconds، ثم باعد بين الاستعلامات: 30 ثانية، ثم 60 ثانية، ثم كل 5 دقائق. والتزم بحد الطلبات. - اعتبر أي حالة غير معروفة "لم يكتمل بعد".
- ما دام الطلب لم يكتمل، لا ترسل عملية شحن أخرى إلى الرقم نفسه برقم طلب جديد. فإذا نجح الطلب الأول أيضًا، سيُشحن الهاتف مرتين.
#Webhook والاسترداد
ترسل طلبات الشحن رسائل Webhook نفسها التي ترسلها الطلبات الأخرى:
order.succeeded وorder.failed وorder.refunded.
تحتوي رسالة Webhook على رقم طلب CardV ورقم طلبك، وقائمة items فارغة.
بعد وصول الرسالة، اقرأ الطلب باستخدام GET/api/v1/recharge/orders/{order_id}.
الاسترداد تلقائي. عندما يؤكد المشغّل فشل العملية، تعيد CardV قيمة
merchant_price كاملة إلى محفظتك، وتصبح حالة الطلب refunded.
يمكنك رؤية المبلغ المسترد في صفحة الحركات بالبوابة.
عملية الشحن الناجحة لا يمكن استردادها أو إلغاؤها.
#الأخطاء
تتبع الأخطاء القواعد العامة. عرض السعر أو الطلب المرفوض يُرجع HTTP 400 ولا يُخصم أي مبلغ.
| المفتاح | أين يظهر | ما الذي تفعله |
|---|---|---|
detail | عرض السعر، الطلب | الدولة أو المشغّل أو النوع أو المبلغ غير متاح. راجع قائمة المشغّلين. |
amount | عرض السعر، الطلب | ليس رقمًا، أو صفر، أو خارج النطاق. |
local_currency | عرض السعر، الطلب | ليس رمز ISO 4217 من 3 أحرف. |
account | الطلب | رقم الهاتف مفقود. |
quote_token | الطلب | مفقود أو منتهي الصلاحية أو معدّل أو غير مطابق. راجع code، ثم اطلب عرض سعر جديدًا. |
balance | الطلب | اشحن محفظتك من البوابة. |
risk | الطلب | بلغت أحد حدود الطلبات. تواصل مع CardV. |
external_order_id | الطلب | مستخدم لطلب مختلف. راجع إعادة المحاولة بأمان. |
wallet | الطلب | لا توجد محفظة نشطة. تواصل مع CardV. |
تأتي أخطاء quote_token مع الحقل code:
{"code": "quote_expired", "quote_token": "This quote expired. Refresh the price and confirm again."}code | المعنى |
|---|---|
quote_required | لم تُرسَل قيمة quote_token. |
quote_expired | مضى عليها أكثر من 300 ثانية. اطلب عرض سعر جديدًا. |
quote_invalid | معدّلة، أو تخص عملية شحن مختلفة. اطلب عرض سعر جديدًا. |
price_changed | تغيّر سعرك منذ عرض السعر. اطلب عرضًا جديدًا وأكّد السعر الجديد. |
HTTP 403 يعني مشكلة في بيانات الاعتماد أو التوقيع أو عنوان IP أو الموافقة. راجع المصادقة.
هل لديك سؤال حول التكامل؟ راسلنا على [email protected] مع ذكر Merchant ID ومعرّف الطلب أو الاستدعاء.