جديدواجهة REST مع ملف وصف بصيغة OpenAPI 3.1
واجهة API لبطاقات eSIM لوكالات السفر وشركات OTA والموزعين
بِع بطاقات eSIM للمسافرين عبر واجهة REST واحدة. اعرض باقات البيانات حسب الدولة بأسعار بعملة وكالتك، واطلب إحداها للمسافر، وسلّمه رمز QR، وتابع الاستهلاك وأعد الشحن. عنوان URL أساسي واحد يخدم Sandbox وLive. ابدأ بمفتاح Sandbox مجاني؛ وتعمل المفاتيح الحية بعد اعتماد وكالتك.
التوثيق مكتوب باللغة الإنجليزية.
- عنوان URL الأساسي
https://api.fx-port.com/api/v1- المصادقة
Authorization: Bearer fxp_test_...- بادئات المفاتيح
fxp_test_ / fxp_live_- نقاط النهاية
- 12
- الدول التي لها باقات
- 190+
- لغات الأمثلة البرمجية
- 9
واجهة eSIM، استدعاءً بعد استدعاء
تابع عملية بيع eSIM خطوة بخطوة، من بناء كل طلب إلى إرساله وتلقي الإجابة. تغطي الجلسات بيع eSIM، وإبقاء المسافر متصلًا، وفحص الأجهزة والحجوزات، والأخطاء التي تستحق المعالجة. الطلبات والإجابات أمثلة من التوثيق، وهذه الصفحة لا تستدعي الواجهة فعليًا.
3 طلبات: اعرض الباقات, اطلب الـ eSIM, اقرأ بيانات الإعداد.
جلسة توضيحية: المحتوى أمثلة من التوثيق، وتُقدَّم التواريخ إلى الأمام لتبقى بعد تاريخ اليوم، والأزمنة توضيحية. هذه الصفحة لا ترسل أي طلب.
ابحث عن باقة، واطلبها، واقرأ بيانات الإعداد
ابدأ بباقات دولة واحدة، ثم اطلب إحداها لمسافر، ثم اقرأ بيانات الإعداد الخاصة بالطلب. ينشئ Sandbox بطاقة eSIM اختبارية برمز تفعيل وهمي ولا يخصم شيئًا، وتعرض وحدة التحكم نسخة مقتطعة من إجابة الكتالوج.
اعرض الباقات
يأخذ استدعاء الكتالوج
countryوtypeويعيد الباقات المطابقة بأسعار بعملة وكالتك. احتفظ بـpackage_idللباقة التي يختارها المسافر.الطلب GET /esims/packages curl 'https://api.fx-port.com/api/v1/esims/packages?country=france&type=local' \ -H "Authorization: Bearer fxp_test_YOUR_KEY"الردّ 200 OK · 180 ms · 3.6 KB 200 OK Content-Type: application/json Cache-Control: private, no-store X-Environment: sandbox ratelimit-limit: 6000 ratelimit-policy: 6000;w=60 { "environment": "sandbox", "success": true, "endpoint": "/packages", "data": [ { "id": "france-in-7days-1gb", "package_id": "france-in-7days-1gb", "type": "sim", "price": 402.5, "base_price": 402.5, "amount": 1024, "day": 7, "is_unlimited": false, "title": "1 GB - 7 days", "is_fair_usage_policy": false, "fair_usage_policy": null, "data": "1 GB", "voice": null, "text": null, "country_name": "France", "country_code": "FR", "country_slug": "france", // ... "operator_name": "KPN France Data only", "operator_id": 1704, // ... "operator_type": "local", "operator_is_prepaid": false, "operator_esim_type": "Prepaid", "operator_warning": null, "operator_apn_type": "automatic", "operator_is_roaming": true, // ... "operator_plan_type": "data", "operator_activation_policy": "first-usage", "operator_is_kyc_verify": false, "operator_rechargeability": true, // ... // ... 1 more // ... "is_regional": false, // ... 10 more }, // ... ], "meta": { "total_packages": 12, "filters_applied": { // ... 2 more }, "locale": "en", "agency_currency": "DZD", "currency": "DZD", "supplier_currency": "USD", "exchange_rate": 250, "commission_percentage": "12 %", "commission_rate": 12 } }مثال مختصر للعرض
- PASS رمز الحالة هو 200
- PASS $.success يساوي true
- PASS $.data[0].package_id موجود
- PASS $.data[0].balance_debit_amount موجود
اطلب الـ eSIM
يأخذ إنشاء الطلب
package_idمع البريد الإلكتروني ورقم هاتف المسافر. احتفظ بـbooking_idوdata.iccidمن الإجابة. في Sandbox تكونbalanceDebitedوtransactionCreatedوpayoutCreatedكلهاfalse.الطلب POST /esims/orders curl https://api.fx-port.com/api/v1/esims/orders \ -H "Authorization: Bearer fxp_test_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "package_id": "france-in-7days-1gb", "first_name": "John", "last_name": "Smith", "email": "[email protected]", "phone": "+15555550123", "description": "Order for John Smith" }'الردّ 200 OK · 900 ms · 1.5 KB 200 OK Content-Type: application/json Cache-Control: private, no-store X-Environment: sandbox ratelimit-limit: 1200 ratelimit-policy: 1200;w=60 x-fx-limit-class: booking { "environment": "sandbox", "success": true, "data": { "order": { "code": "20261101-106852", "order_id": "20261101-106852", "package_id": "france-in-7days-1gb", "type": "sim", "description": "Order for John Smith", "esim_type": "local", "created_at": "2026-11-09 15:23:22", "package": "KPN France Data only-1 GB - 7 days", "data": "1 GB", "validity": 7, "price": 468.84, "currency": "DZD", "total_price": 468.84, "retail_price": 468.84, "agency_currency": "DZD", "supplier_currency": "USD", "exchange_rate": 250, "voice": null, "text": null, "coverage": "" }, "sim": { "iccid": "8900000540463077957", "created_at": "2026-11-09 15:23:22", "lpa": "lpa.airalo.com", "imsis": null, "qrcode": "LPA:1$lpa.airalo.com$DUMMY-2610301358-iKFxr-44741", // ... "direct_apple_installation_url": "https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.airalo.com$DUMMY-2610301358-iKFxr-44741", "apn_type": "automatic", "apn_value": "N/A", "apn": { // ... 2 more }, "is_roaming": true, "confirmation_code": null, "msisdn": null, "sharing": { "access_code": 8803, "link": "https://esims.cloud/v8hy7-usgkq6wg" } }, "iccid": "8900000540463077957" }, "booking_id": "FX-1793546602916", "message": "eSIM order placed successfully", "balanceDebited": false, "balance_debited": false, "transactionCreated": false, "transaction_created": false, "payoutCreated": false, "payout_created": false }مثال مختصر للعرض
- PASS رمز الحالة هو 200
- PASS $.environment يساوي sandbox
- PASS $.balance_debited يساوي false
- PASS $.data.iccid موجود
اقرأ بيانات الإعداد
يأخذ استدعاء بيانات الإعداد
booking_idويعيد رمز QR وبيانات التفعيل وروابط التثبيت وخطوات التثبيت للطلب. اعرضها فقط للمسافر الذي يملك الـ eSIM.الطلب GET /esims/bookings/{booking_id}/setup-instructions curl https://api.fx-port.com/api/v1/esims/bookings/FX-1793546602916/setup-instructions \ -H "Authorization: Bearer fxp_test_YOUR_KEY"الردّ 200 OK · 210 ms · 1.8 KB 200 OK Content-Type: application/json Cache-Control: private, no-store X-Environment: sandbox ratelimit-limit: 6000 ratelimit-policy: 6000;w=60 { "environment": "sandbox", "success": true, "data": { "code": "20261101-106852", "order_id": "20261101-106852", "currency": "DZD", "package_id": "france-in-7days-1gb", "quantity": 1, "type": "sim", "description": "Order for John Smith", "esim_type": "local", "validity": 7, "package": "KPN France Data only-1 GB - 7 days", "data": "1 GB", "price": 468.84, "created_at": "2026-11-09 15:23:22", // ... "installation_guides": { "en": "https://www.airalo.com/help/getting-started-with-airalo" }, "text": null, "voice": null, "sims": [ { "created_at": "2026-11-09 15:23:22", "iccid": "8900000540463077957", "lpa": "lpa.airalo.com", "imsis": null, "qrcode": "LPA:1$lpa.airalo.com$DUMMY-2610301358-iKFxr-44741", // ... "apn_type": "automatic", "apn_value": "N/A", "is_roaming": true, "confirmation_code": null, "apn": { "ios": { "apn_type": "automatic", "apn_value": "N/A" }, "android": { "apn_type": "automatic", "apn_value": "N/A" } }, "msisdn": null, "direct_apple_installation_url": "https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.airalo.com$DUMMY-2610301358-iKFxr-44741", "direct_android_installation_url": "https://esimsetup.android.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.airalo.com$DUMMY-2610301358-iKFxr-44741", "sharing": { "access_code": 8803, "link": "https://esims.cloud/v8hy7-usgkq6wg" } } ], "total_price": 468.84, "retail_price": 468.84, "agency_currency": "DZD" } }مثال مختصر للعرض
- PASS رمز الحالة هو 200
- PASS $.data.package_id يساوي france-in-7days-1gb
- PASS $.data.sims[0].iccid موجود
مرجع GET /esims/bookings/{booking_id}/setup-instructions في التوثيق
اقرأ الاستهلاك ثم أعد الشحن
بعد أن يحصل المسافر على eSIM، اقرأ كم بقي من البيانات، واسأل عن الباقات التي يمكن إضافتها إلى هذه الـ eSIM تحديدًا، ثم أنشئ إعادة الشحن. الاستهلاك مخزَّن مؤقتًا، فقد يكون الرقم قديمًا بدقائق. سجل إعادة الشحن في الشريط الجانبي وفي النص المسجّل.
اقرأ الاستهلاك
يأخذ استدعاء الاستهلاك رقم ICCID الخاص بالطلب ويعيد
remainingوtotalبالميغابايت، معstatusوتاريخ الانتهاء. تأتي الإجابة من ذاكرة مؤقتة، ويطلبforce=trueمن المورّد مجددًا.الطلب GET /esims/usage/{iccid} curl https://api.fx-port.com/api/v1/esims/usage/8900000540463077957 \ -H "Authorization: Bearer fxp_test_YOUR_KEY"الردّ 200 OK · 160 ms · 261 B 200 OK { "environment": "sandbox", "success": true, "data": { "data": { "remaining": 1024, "total": 1024, "expired_at": "2026-11-16 15:23:29", "is_unlimited": false, "status": "ACTIVE", "remaining_voice": 0, "remaining_text": 0, "total_voice": 0, "total_text": 0 }, "meta": { "message": "success" } } }- PASS رمز الحالة هو 200
- PASS $.data.data.status يساوي ACTIVE
- PASS $.data.data.remaining موجود
اعرض باقات إعادة الشحن
يعرض هذا الاستدعاء الباقات التي يمكن إضافتها اليوم إلى هذه الـ eSIM تحديدًا. القائمة الفارغة تعني أنه لا يمكن إعادة شحنها الآن. خذ
package_idالخاص بإعادة الشحن من هذه القائمة، لا من الطلب الأصلي.الطلب GET /esims/topup-packages/{iccid} curl https://api.fx-port.com/api/v1/esims/topup-packages/8900000540463077957 \ -H "Authorization: Bearer fxp_test_YOUR_KEY"الردّ 200 OK · 240 ms · 1.1 KB 200 OK { "environment": "sandbox", "success": true, "data": { "data": [ { "id": "france-in-7days-1gb-topup", "package_id": "france-in-7days-1gb-topup", "type": "topup", "price": 468.84, "amount": 1024, "day": 7, "is_unlimited": false, "title": "1 GB - 7 days", "data": "1 GB", "short_info": null, // ... 12 more }, { // ... 22 more } ] } }مثال مختصر للعرض
- PASS رمز الحالة هو 200
- PASS $.data.data يحتوي عنصرين
- PASS $.data.data[0].type يساوي topup
أنشئ إعادة الشحن
يأخذ إنشاء إعادة الشحن
package_idمن تلك القائمة مع رقم ICCID. وفي Live لا يُخصم رصيدك إلا بعد أن يقبلها المورّد. أما في Sandbox فقيمةbalanceفي الإجابة صفر ولا يُخصم شيء.الطلب POST /esims/topups curl https://api.fx-port.com/api/v1/esims/topups \ -H "Authorization: Bearer fxp_test_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "package_id": "france-in-7days-1gb-topup", "iccid": "8900000540463077957", "first_name": "John", "last_name": "Smith", "email": "[email protected]", "phone": "+15555550123" }'الردّ 200 OK · 900 ms · 682 B 200 OK { "environment": "sandbox", "success": true, "data": { "topup": { "code": "20261101-106853", "order_id": "20261101-106853", "package_id": "france-in-7days-1gb-topup", // ... 10 more }, "iccid": "8900000540463077957", "balance": { // ... 3 more } }, "booking_id": "FX-1793546625391", "message": "eSIM topup completed successfully", "balanceDebited": false, "balance_debited": false, "transactionCreated": false, "transaction_created": false, "payoutCreated": false, "payout_created": false }- PASS رمز الحالة هو 200
- PASS $.environment يساوي sandbox
- PASS $.balance_debited يساوي false
- PASS $.data.balance.current يساوي 0
اقرأ سجل إعادة الشحن
يعرض سجل إعادة الشحن عمليات إعادة الشحن لـ eSIM واحدة، الأحدث أولًا. هذه العمليات ليست في قائمة الحجوزات، فهنا تجدها.
الطلب GET /esims/bookings/{iccid}/topup-history curl https://api.fx-port.com/api/v1/esims/bookings/8900000540463077957/topup-history \ -H "Authorization: Bearer fxp_test_YOUR_KEY"الردّ 200 OK · 130 ms · 615 B 200 OK { "environment": "sandbox", "success": true, "data": [ { "id": "bd6ff7d7-392f-4d56-8dea-4f0f3dff0af9", "booking_id": "FX-1793546625391", "order_id": "20261101-106853", "status": "confirmed", "currency": "DZD", "total_price": 468.84, "agency_commission": 50.24, "type": "topup", "package_name": "1 GB - 7 days", "iccid": "8900000540463077957", "customer_email": "[email protected]", "customer_first_name": "John", "customer_last_name": "Smith", "customer_phone": "+15555550123", "provider_name": "Airalo", // ... 4 more } ] }- PASS رمز الحالة هو 200
- PASS $.data[0].type يساوي topup
افحص جهازًا ثم اقرأ حجوزاتك
قبل البيع، تحقق من أن هاتف المسافر يدعم eSIM. وبعد البيع، اقرأ حجوزاتك وتحقق من أن مرجع حجز ما يخصك. استهلاك مجموعة من البطاقات مدرج في الشريط الجانبي.
افحص قائمة الأجهزة
يعيد استدعاء الأجهزة المتوافقة الأجهزة المعروف أنها تدعم eSIM، مع
brandوmodelوos. ابحث عن هاتف المسافر قبل أن تبيع.الطلب GET /esims/compatible-devices curl https://api.fx-port.com/api/v1/esims/compatible-devices \ -H "Authorization: Bearer fxp_test_YOUR_KEY"الردّ 200 OK · 120 ms · 283 B 200 OK { "environment": "sandbox", "success": true, "data": [ { "model": "T803D", "os": "android", "brand": "Alcatel", "name": "V3 Ultra" }, { "model": "iPhone15,2", "os": "ios", "brand": "Apple", "name": "iPhone 14 Pro" } ], "meta": { "total_devices": 631, "cached_at": "2026-11-09T15:07:43.957236", "cache_age_days": 0.01 } }- PASS رمز الحالة هو 200
- PASS $.success يساوي true
- PASS $.data[0].model موجود
اعرض حجوزاتك
تعيد قائمة الحجوزات طلبات eSIM الخاصة بوكالتك، الأحدث أولًا. يطلب هذا الطلب حجزًا واحدًا بالمعامل
limit، ويبيّنpaginationعدد الطلبات المطابقة وهل تليها صفحة أخرى.الطلب GET /esims/bookings curl 'https://api.fx-port.com/api/v1/esims/bookings?limit=1' \ -H "Authorization: Bearer fxp_test_YOUR_KEY"الردّ 200 OK · 150 ms · 714 B 200 OK { "environment": "sandbox", "success": true, "data": [ { "id": "639417b4-b103-4ece-bd5d-850315322278", "booking_id": "FX-1793546602916", "order_id": "20261101-106852", "status": "confirmed", "currency": "DZD", // ... 4 more "iccid": "8900000540463077957", // ... 9 more } ], "pagination": { "total": 61, "page": 1, "limit": 1, "pages": 61, "total_pages": 61, "has_more": true } }- PASS رمز الحالة هو 200
- PASS $.data يحتوي عنصرًا واحدًا
- PASS $.pagination.has_more يساوي true
تحقق من الملكية
يجيب التحقق من الملكية بـ
is_ownerبقيمة true حين يخص الحجز وكالتك. وحجز وكالة أخرى وحجز غير موجود يحصلان على الإجابة نفسها، فلا يمكن استخدام الاستدعاء لاكتشاف المراجع.الطلب GET /esims/bookings/{booking_id}/verify curl https://api.fx-port.com/api/v1/esims/bookings/FX-1793546602916/verify \ -H "Authorization: Bearer fxp_test_YOUR_KEY"الردّ 200 OK · 90 ms · 167 B 200 OK { "environment": "sandbox", "isOwner": true, "is_owner": true, "userAgencyId": "0b1c2d3e-4f50-4a6b-8c7d-9e0f1a2b3c4d", "bookingAgencyId": "0b1c2d3e-4f50-4a6b-8c7d-9e0f1a2b3c4d" }- PASS رمز الحالة هو 200
- PASS $.is_owner يساوي true
اقرأ الاستهلاك دفعة واحدة
يقرأ استدعاء واحد استهلاك عدة بطاقات eSIM مدرجة في
iccidsويعيد عنصرًا لكل ICCID، لكل منهاstatusخاص بها. أرسلiccidsدائمًا.الطلب GET /esims/usage/bulk curl 'https://api.fx-port.com/api/v1/esims/usage/bulk?iccids=8900000540463077957' \ -H "Authorization: Bearer fxp_test_YOUR_KEY"الردّ 200 OK · 220 ms · 321 B 200 OK { "environment": "sandbox", "success": true, "data": [ { "iccid": "8900000540463077957", "data": { "data": { "remaining": 1024, "total": 1024, "expired_at": "2026-11-16 15:23:29", "is_unlimited": false, "status": "ACTIVE", "remaining_voice": 0, // ... 3 more }, "meta": { "message": "success" } }, "status": "success" } ] }- PASS رمز الحالة هو 200
- PASS $.data[0].status يساوي success
حالات الإخفاق وكيف تتصرف مع كل منها
تشترك كل حالات الإخفاق في جسم واحد، ويحمل أول عنصر في errors رمز code ثابتًا. تفشل استدعاءات الطلب هذه عمدًا، كل منها لسبب مختلف وبتصرف مختلف.
مفتاح قراءة على طلب
يُرفض مفتاح القراءة على استدعاء الطلب بالرمز
403معread_write_permission_required، قبل قراءة الجسم. انتقل إلى مفتاح قراءة + كتابة.الطلب POST /esims/orders curl https://api.fx-port.com/api/v1/esims/orders \ -H "Authorization: Bearer fxp_test_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "package_id": "france-in-7days-1gb", "first_name": "John", "last_name": "Smith", "email": "[email protected]", "phone": "+15555550123", "description": "Order for John Smith" }'الردّ 403 Forbidden · 90 ms · 456 B 403 Forbidden { "environment": "sandbox", "success": false, "errors": [ { "code": "read_write_permission_required", "type": "permission_error", "title": "Read write permission required", "message": "This endpoint requires an API key with read_write permission.", "field": null, "details": {}, "documentation_url": "https://fx-port.com/docs/errors#read_write_permission_required" } ], "meta": { "request_id": "req_7f0c2e9a41b84d6e8a35c1d2", "status": 403 }, "request_id": "req_7f0c2e9a41b84d6e8a35c1d2" }- PASS رمز الحالة هو 403
- PASS رمز الخطأ هو read_write_permission_required
- PASS $.errors[0].type يساوي permission_error
بريد إلكتروني غير صالح
تُرفض القيمة التي ليست بريدًا إلكترونيًا بالرمز
400معinvalid_email، ويسمّيfieldالحقلemail. صحّح القيمة قبل إرسال الطلب مرة أخرى: فالطلب نفسه يفشل بالطريقة نفسها.الطلب POST /esims/orders curl https://api.fx-port.com/api/v1/esims/orders \ -H "Authorization: Bearer fxp_test_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "package_id": "france-in-7days-1gb", "first_name": "John", "last_name": "Smith", "email": "traveler-at-example.com", "phone": "+15555550123", "description": "Order for John Smith" }'الردّ 400 Bad Request · 100 ms · 381 B 400 Bad Request { "environment": "sandbox", "success": false, "errors": [ { "code": "invalid_email", "type": "validation_error", "title": "Invalid email", "message": "email is not a valid email address", "field": "email", "details": {}, "documentation_url": "https://fx-port.com/docs/errors#invalid_email" } ], "meta": { "request_id": "req_7f0c2e9a41b84d6e8a35c1d2", "status": 400 }, "request_id": "req_7f0c2e9a41b84d6e8a35c1d2" }- PASS رمز الحالة هو 400
- PASS رمز الخطأ هو invalid_email
- PASS $.errors[0].field يساوي email
طلب مكرر
يُرفض طلب لباقة قيد المعالجة بالفعل بالرمز
409معduplicate_request. لا ترسله مرة أخرى فورًا: ابحث عن الحجز أولًا، ولا تطلب من جديد إلا إذا لم يُنشأ أي حجز.الطلب POST /esims/orders curl https://api.fx-port.com/api/v1/esims/orders \ -H "Authorization: Bearer fxp_test_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "package_id": "france-in-7days-1gb", "first_name": "John", "last_name": "Smith", "email": "[email protected]", "phone": "+15555550123", "description": "Order for John Smith" }'الردّ 409 Conflict · 110 ms · 423 B 409 Conflict { "environment": "sandbox", "success": false, "errors": [ { "code": "duplicate_request", "type": "conflict", "title": "Duplicate request", "message": "An identical order is already being processed. Please wait before retrying.", "field": null, "details": {}, "documentation_url": "https://fx-port.com/docs/errors#duplicate_request" } ], "meta": { "request_id": "req_7f0c2e9a41b84d6e8a35c1d2", "status": 409 }, "request_id": "req_7f0c2e9a41b84d6e8a35c1d2" }- PASS رمز الحالة هو 409
- PASS رمز الخطأ هو duplicate_request
- PASS $.errors[0].type يساوي conflict
طلبات كثيرة جدًا
عند تجاوز الحد في الدقيقة، يُرفض الاستدعاء بالرمز
429معrate_limit_exceeded، وتبيّن ترويسةRetry-Afterعدد الثواني الواجب انتظارها. ثم أعد المحاولة مع التراجع (backoff).الطلب POST /esims/orders curl https://api.fx-port.com/api/v1/esims/orders \ -H "Authorization: Bearer fxp_test_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "package_id": "france-in-7days-1gb", "first_name": "John", "last_name": "Smith", "email": "[email protected]", "phone": "+15555550123", "description": "Order for John Smith" }'الردّ 429 Too Many Requests · 80 ms · 504 B 429 Too Many Requests Retry-After: 12 { "environment": "sandbox", "success": false, "errors": [ { "code": "rate_limit_exceeded", "type": "rate_limit_error", "title": "Rate limit exceeded", "message": "Too many requests hit the API too quickly. Please retry your request after the time specified in the `ratelimit-reset` header.", "field": null, "details": { "retry_after": 12 }, "documentation_url": "https://fx-port.com/docs/errors#rate_limit_exceeded" } ], "meta": { "request_id": "req_7f0c2e9a41b84d6e8a35c1d2", "status": 429 }, "request_id": "req_7f0c2e9a41b84d6e8a35c1d2" }- PASS رمز الحالة هو 429
- PASS رمز الخطأ هو rate_limit_exceeded
- PASS الترويسة Retry-After موجودة
- PASS $.errors[0].details.retry_after يساوي 12
من الكتالوج إلى مسافر متصل في خمس خطوات
التكامل مسار قصير: اقرأ الكتالوج، وأنشئ الطلب، وسلّم المسافر الـ eSIM، وتابع الاستهلاك، وأعد الشحن عند نفاد البيانات. الطلب وإعادة الشحن وحدهما يغيّران شيئًا. أما كل استدعاء آخر فيقرأ فقط.
اقرأ الكتالوج لوجهة واحدة
اعرض باقات دولة واحدة بأسعار محوّلة مسبقًا إلى عملة وكالتك، واحتفظ بـ package_id للباقة التي يختارها المسافر. أرسل country دائمًا: فالكتالوج كاملًا إجابة كبيرة جدًا بلا ترقيم للصفحات. اقرأ معرّفات الباقات من الإجابة بدل كتابتها ثابتة في الكود، لأن الكتالوج يتغيّر.
الطلب
curl 'https://api.fx-port.com/api/v1/esims/packages?country=france&type=local' \
-H "Authorization: Bearer fxp_test_YOUR_KEY"الردّ 200 OK
{
"environment": "sandbox",
"success": true,
"endpoint": "/packages",
"data": [
{
"id": "france-in-7days-1gb",
"package_id": "france-in-7days-1gb",
"type": "sim",
"price": 402.5,
"base_price": 402.5,
// ... 28 more
"total_price": 468.84,
"balance_debit_amount": 418.6,
"b2b_price": 418.6,
"agency_commission": "12 %",
"commission_rate": 12,
"currency": "DZD",
// ... 2 more
},
// ...
],
"meta": {
"total_packages": 12,
"filters_applied": {
// ... 2 more
},
"locale": "en",
"agency_currency": "DZD",
"currency": "DZD",
"supplier_currency": "USD",
"exchange_rate": 250,
"commission_percentage": "12 %",
"commission_rate": 12
}
}أنشئ الطلب
أرسل package_id مع البريد الإلكتروني ورقم هاتف المسافر. الطلب الواحد ينشئ eSIM واحدة بالضبط، وفي Live يخصم من رصيد وكالتك. احتفظ بـ booking_id ورقم ICCID من الإجابة، فكل استدعاء لاحق يحتاج إلى أحدهما.
الطلب
curl https://api.fx-port.com/api/v1/esims/orders \
-H "Authorization: Bearer fxp_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"package_id": "france-in-7days-1gb",
"first_name": "John",
"last_name": "Smith",
"email": "[email protected]",
"phone": "+15555550123",
"description": "Order for John Smith"
}'الردّ 200 OK
{
"environment": "sandbox",
"success": true,
"data": {
"order": {
"code": "20261101-106852",
"order_id": "20261101-106852",
"package_id": "france-in-7days-1gb",
// ... 17 more
},
"sim": {
// ... 4 more
"qrcode": "LPA:1$lpa.airalo.com$DUMMY-2610301358-iKFxr-44741",
// ... 7 more
"sharing": {
"access_code": 8803,
"link": "https://esims.cloud/v8hy7-usgkq6wg"
}
},
"iccid": "8900000540463077957"
},
"booking_id": "FX-1793546602916",
"message": "eSIM order placed successfully",
"balanceDebited": false,
"balance_debited": false,
"transactionCreated": false,
"transaction_created": false,
"payoutCreated": false,
"payout_created": false
}| الحقل | ما يحمله |
|---|---|
booking_id | مرجع FX-Port للطلب. احتفظ به لبيانات الإعداد وللتحقق من الملكية ولسجلاتك. |
data.iccid | معرّف الـ eSIM. يُطلب الاستهلاك وإعادة الشحن وتعليمات التثبيت كلها برقم ICCID. |
data.sim.qrcode data.sim.qrcode_url | سلسلة التفعيل التي يشفّرها رمز QR، ورابط إلى صورة رمز QR. |
data.sim.direct_apple_installation_url data.sim.sharing | رابط يبدأ التثبيت على iPhone، وصفحة مشاركة يفتح منها المسافر الـ eSIM برمز الوصول الخاص بها. ويضيف استدعاء بيانات الإعداد رابط Android. |
PENDING-، وتتوافر البيانات من استدعاء بيانات الإعداد حين يحصل عليها المورّد.سلّم المسافر الـ eSIM
تحمل الإجابة رمز QR وسلسلة التفعيل الخاصة به، فيمكنك عرضهما في شاشاتك. كما يطلب FX-Port من المورّد إرسال رمز QR ورابط مشاركة بالبريد الإلكتروني إلى عنوان المسافر، فلا تحتاج إلى نقله بنفسك. ويعيد استدعاء بيانات الإعداد البيانات نفسها لاحقًا مع خطوات التثبيت.
الطلب
curl https://api.fx-port.com/api/v1/esims/bookings/FX-1793546602916/setup-instructions \
-H "Authorization: Bearer fxp_test_YOUR_KEY"الردّ 200 OK
{
"environment": "sandbox",
"success": true,
"data": {
"code": "20261101-106852",
"order_id": "20261101-106852",
"currency": "DZD",
"package_id": "france-in-7days-1gb",
"quantity": 1,
"type": "sim",
"description": "Order for John Smith",
"esim_type": "local",
"validity": 7,
"package": "KPN France Data only-1 GB - 7 days",
"data": "1 GB",
// ... 5 more
"sims": [
{
"created_at": "2026-11-09 15:23:22",
"iccid": "8900000540463077957",
// ... 2 more
"qrcode": "LPA:1$lpa.airalo.com$DUMMY-2610301358-iKFxr-44741",
// ... 6 more
"direct_apple_installation_url": "https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.airalo.com$DUMMY-2610301358-iKFxr-44741",
// ... 2 more
}
],
// ... 3 more
}
}تابع الاستهلاك
اقرأ البيانات المتبقية وتاريخ انتهاء eSIM برقم ICCID. تُخزَّن الإجابة مؤقتًا حتى 15 دقيقة، فاستخدمها لشاشة أو تذكير، لا كعدّاد.
الطلب
curl https://api.fx-port.com/api/v1/esims/usage/8900000540463077957 \
-H "Authorization: Bearer fxp_test_YOUR_KEY"الردّ 200 OK
{
"environment": "sandbox",
"success": true,
"data": {
"data": {
"remaining": 1024,
"total": 1024,
"expired_at": "2026-11-16 15:23:29",
"is_unlimited": false,
"status": "ACTIVE",
"remaining_voice": 0,
"remaining_text": 0,
"total_voice": 0,
"total_text": 0
},
"meta": {
"message": "success"
}
}
}أعد الشحن عند نفاد البيانات
اعرض الباقات التي يمكن إضافتها إلى هذه الـ eSIM تحديدًا، ثم أنشئ إعادة الشحن بإحداها. إذا كانت القائمة فارغة فلا يمكن إعادة شحن الـ eSIM الآن ويحتاج المسافر إلى واحدة جديدة.
الطلب
curl https://api.fx-port.com/api/v1/esims/topups \
-H "Authorization: Bearer fxp_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"package_id": "france-in-7days-1gb-topup",
"iccid": "8900000540463077957",
"first_name": "John",
"last_name": "Smith",
"email": "[email protected]",
"phone": "+15555550123"
}'الردّ 200 OK
{
"environment": "sandbox",
"success": true,
"data": {
"topup": {
"code": "20261101-106853",
"order_id": "20261101-106853",
"package_id": "france-in-7days-1gb-topup",
"package": "KPN France Data only-1 GB - 7 days",
"data": "1 GB",
"validity": 7,
"price": 468.84,
// ... 6 more
},
"iccid": "8900000540463077957",
"balance": {
"previous": 0,
"current": 0,
"currency": "DZD"
}
},
"booking_id": "FX-1793546625391",
"message": "eSIM topup completed successfully",
"balanceDebited": false,
"balance_debited": false,
"transactionCreated": false,
"transaction_created": false,
"payoutCreated": false,
"payout_created": false
}الأسعار والعمولة ورصيدك
تحمل كل باقة حقولها المالية، محسوبة على الخادم بعملة وكالتك. يُتجاهل أي سعر يرد في جسم الطلب، فيُنشأ الطلب دائمًا بالسعر الذي يحسبه الخادم.
| الحقل | ما يحمله |
|---|---|
base_price price | سعر الباقة قبل عمولتك. وليس المبلغ الذي يُخصم من رصيدك. |
total_price retail_price | السعر الذي تحاسب به المسافر، وعمولتك مشمولة فيه. |
balance_debit_amount b2b_price | ما يغادر رصيد وكالتك عند طلب الباقة في Live. اقرأه ولا تحسبه. |
agency_commission commission_rate | نسبة عمولتك، كنص وكرقم. أما الحجوزات فتعيد عمولتك كمبلغ. |
في مثال الكتالوج يدفع المسافر 468.84 DZD. وعند الطلب في Live يُخصم من رصيدك 418.60 DZD، والفرق، أي 50.24 DZD، هو عمولتك.
النسبة خاصة بوكالتك
تعود نسبة العمولة مع كل باقة، وهي ليست واحدة لكل الوكالات. قد تكون نسبة الوكالة المؤسسية المتعاقدة صفرًا، وعندها يساوي السعر الإجمالي المبلغ المخصوم.
اقرأ الحقول ولا تعِد بناءها
قد يزيد المبلغ المخصوم عن السعر الأساسي، لأن مبالغ خاصة بوكالتك تدخل فيه. لذا اقرأ balance_debit_amount ولا تحسبه أبدًا من base_price. الكلمة price هي السعر الأساسي في الكتالوج لكنها سعر البيع في الطلبات وباقات إعادة الشحن وبيانات الإعداد: استخدم base_price وtotal_price في كل مكان فيزول اللبس.
الأسعار بعملة وكالتك
كل مبلغ محوّل مسبقًا إلى عملة وكالتك، أيًّا كانت العملة التي يستخدمها المورّد. وتعرض الإجابة أيضًا عملة المورّد وسعر الصرف، فتتحقق من السعر بنفسك ولا تحتاج إلى التحويل مرة أخرى.
بعد البيع: الاستهلاك وإعادة الشحن وبيانات الإعداد
لا تنتهي عملية البيع بالطلب. هذه الاستدعاءات تُبقي المسافر متصلًا، وهي تعمل فقط على بطاقات eSIM التي طلبتها وكالتك في البيئة نفسها التي ينتمي إليها مفتاحك.
قراءة الاستهلاك ومدى حداثته
يعيد استدعاء الاستهلاك البيانات المتبقية والحصة والحالة وتاريخ الانتهاء لبطاقة eSIM واحدة، أو لما يصل إلى 50 بطاقة في استدعاء واحد. يحتفظ FX-Port بآخر إجابة حتى 15 دقيقة لحماية حدود معدّل الطلبات لدى المورّد، فقد يكون الرقم قديمًا بهذا القدر. مرّر force=true لتسأل المورّد من جديد، مثلًا بعد إعادة الشحن مباشرة. لا تفعل ذلك في كل طلب، لأن المورّد يحدّ من عدد مرات قراءة الاستهلاك. وإذا تعذّر على المورّد الإجابة، تحصل على آخر رقم معروف موسومًا بأنه قديم.
إعادة الشحن: اسأل أولًا ثم أنشئ
إعادة الشحن استدعاءان. اعرض أولًا الباقات التي يمكن إضافتها إلى هذه الـ eSIM تحديدًا، ثم أنشئ إعادة الشحن بأحد معرّفات الباقات المعادة. لا تعِد استخدام معرّف باقة الطلب الأصلي، ولا تحتفظ بباقة إعادة شحن لوقت لاحق: اسأل من جديد حين يريد المسافر إعادة الشحن. تضيف إعادة الشحن بيانات إلى الـ eSIM ولا تستبدل ما بقي، فاقرأ النتيجة من الاستهلاك مع force=true.
حين لا تكون إعادة الشحن ممكنة
يختار المورّدون مشغّلي الاتصالات الذين يخدمون الدولة، وفي حالات نادرة يغيّرون أحدهم. عندها قد تواصل الـ eSIM العمل حتى انتهاء صلاحيتها بينما لا يمكن إعادة شحن باقتها. وتعود قائمة باقات إعادة الشحن فارغة. وإذا رفض المورّد إعادة الشحن فلا يُمسّ رصيدك وتُحفظ المحاولة كحجز فاشل. والإجابة هي supplier_error يمكنك التعامل معها.
بيانات الإعداد وخطوات التثبيت
يعيد استدعاء بيانات الإعداد رمز QR وبيانات التفعيل وروابط التثبيت وخطوات التثبيت لأي طلب متى احتجت إليها. ويعيد استدعاء التعليمات الخطوات لكل نظام تشغيل وباللغة التي تطلبها. الخطوات نص عام من المورّد، فاعرضها بجانب رمز QR الخاص بالطلب. واعرض الاثنين للمسافر الذي يملك الـ eSIM فقط.
الحجوزات وسجل إعادة الشحن والملكية
تعيد قائمة الحجوزات طلبات eSIM الخاصة بوكالتك في بيئة مفتاحك، الأحدث أولًا. يمكنك البحث فيها بمعرّف الحجز أو اسم المسافر أو بريده الإلكتروني أو اسم الباقة أو رقم ICCID. إعادة الشحن ليست في هذه القائمة: اقرأها من سجل إعادة الشحن لبطاقة eSIM. وقبل أن تبني رابطًا أو شاشة حول معرّف حجز، يخبرك التحقق من الملكية إن كان يخصّك. حجز وكالة أخرى وحجز غير موجود يحصلان على الإجابة نفسها.
كل نقاط نهاية eSIM مع OpenAPI وPostman وأمثلة برمجية
تضم واجهة eSIM 12 نقطة نهاية تحت عنوان URL أساسي واحد. يفتح كل صف صفحة المرجع لذلك الاستدعاء، مع حقول الطلب والإجابات والأخطاء والأمثلة بـ 9 لغات.
| نقطة النهاية | وظيفتها | المفتاح |
|---|---|---|
GET /api/v1/esims/packages | اعرض باقات دولة أو منطقة واحدة بأسعار محوّلة مسبقًا إلى عملة وكالتك. أرسل دولة دائمًا: فالكتالوج كاملًا ضخم جدًا وبلا ترقيم صفحات. | قراءة |
GET /api/v1/esims/compatible-devices | الأجهزة المعروف أنها تدعم eSIM، للفحص قبل أن يشتري المسافر. | قراءة |
POST /api/v1/esims/orders | أنشئ eSIM واحدة من باقة لمسافر وجهّزها لدى المورّد. وفي Live تخصم من رصيد وكالتك. | قراءة + كتابة |
GET /api/v1/esims/topup-packages/{iccid} | الباقات التي يمكن إضافتها اليوم إلى eSIM محددة بعينها. القائمة الفارغة تعني أنه لا يمكن إعادة شحنها الآن. | قراءة |
POST /api/v1/esims/topups | أضف باقة إعادة شحن إلى eSIM قائمة. وفي Live لا يُخصم رصيدك إلا بعد أن يقبلها المورّد. | قراءة + كتابة |
GET /api/v1/esims/usage/{iccid} | البيانات المتبقية والحصة والحالة وتاريخ الانتهاء لـ eSIM واحدة. قد يبلغ عمر الإجابة حتى 15 دقيقة. | قراءة |
GET /api/v1/esims/usage/bulk | استهلاك ما يصل إلى 50 من بطاقات eSIM في استدعاء واحد، بعنصر لكل ICCID وبحالة خاصة لكل منها. | قراءة |
GET /api/v1/esims/bookings | طلبات eSIM الخاصة بوكالتك، الأحدث أولًا، مع بحث وترقيم صفحات. عمليات إعادة الشحن ليست في هذه القائمة. | قراءة |
GET /api/v1/esims/bookings/{iccid}/topup-history | عمليات إعادة الشحن لـ eSIM واحدة، الأحدث أولًا. تكون القائمة فارغة إن لم تُجرَ لها أي عملية. | قراءة |
GET /api/v1/esims/bookings/{booking_id}/verify | تحقق من أن مرجع الحجز يخص وكالتك، قبل أن تبني حوله رابطًا أو شاشة. | قراءة |
GET /api/v1/esims/bookings/{booking_id}/setup-instructions | رمز QR وبيانات التفعيل وروابط التثبيت وخطوات التثبيت للطلب، بصيغة JSON. | قراءة |
GET /api/v1/esims/instructions/{iccid} | تعليمات تثبيت خطوة بخطوة لرقم ICCID واحد، لكل نظام تشغيل، باللغة التي تطلبها. | قراءة |
OpenAPI 3.1
ملف واحد يصف كل نقطة نهاية وكل حقل. أنشئ منه عميلًا برمجيًا، أو استورده في أداة API، أو سلّمه إلى مساعد برمجة.
مجموعة Postman
تغطي مجموعة eSIM نقاط النهاية كلها (12 نقطة نهاية) في مجلدات تتبع مراحل البيع. لا تحتوي على أي مفاتيح، فأضف مفاتيحك.
أمثلة برمجية بـ 9 لغات
تطبع كل صفحة مرجع طلبها بلغات cURL وNode.js وPython وPHP وGo وJava وC# وSwift وKotlin، وتُولَّد من وصف OpenAPI. كل طلب eSIM متاح بها جميعًا.
توثيق لمساعدي الذكاء الاصطناعي
يمنح llms.txt وllms-full.txt مساعدي الذكاء الاصطناعي التوثيق كنص عادي، ويمكن قراءة كل صفحة توثيق بصيغة Markdown بإضافة .md إلى عنوانها.
مصمَّمة للإنتاج: المفاتيح والأخطاء وإعادة المحاولة والتخزين المؤقت
يُقاس تكامل eSIM في الإنتاج بالمصادقة والأخطاء وإعادة المحاولة والتخزين المؤقت وحدود معدّل الطلبات. إليك ما يجب معرفته عن كل منها.
عنوان URL أساسي واحد ونوعان من المفاتيح
يحمل كل طلب مفتاحًا بوصفه رمز Bearer في ترويسة Authorization. تدل البادئة على البيئة التي يعمل فيها المفتاح: fxp_test_ لـ Sandbox وfxp_live_ لـ Live. يتصل الاثنان بعنوان URL الأساسي نفسه، وتذكر كل إجابة JSON البيئة التي صدرت عنها في الحقل environment. مكان المفاتيح هو خادمك، لا المتصفح ولا التطبيق. يحتفظ FX-Port ببصمة (hash) كل مفتاح فقط، لذا لا يمكن عرض مفتاح ضاع مرة أخرى. وقد يستغرق تطبيق أي تغيير على المفتاح بضع دقائق.
أي مفتاح ينفّذ أي استدعاء
يستطيع مفتاح القراءة عرض الباقات وفحص الأجهزة وقراءة الاستهلاك والحجوزات. أما إنشاء طلب أو إعادة شحن فيحتاج إلى مفتاح قراءة + كتابة، ومفتاح القراءة الذي يحاول ذلك يتلقى read_write_permission_required. ويمكن قصر أي مفتاح على قائمة عناوين IP، وأي استدعاء من عنوان آخر يتلقى ip_not_allowed. استخدم مفتاح القراءة حيثما يكتفي الكود بعرض النتائج.
صيغة خطأ واحدة لكل إخفاق
يعيد الاستدعاء الفاشل مصفوفة errors. يحمل أول عنصر فيها code ثابتًا، وtype يبيّن كيف تتصرف، وfield يحدد الحقل المسبب. اختبر الرمز، لا الرسالة. تضم قائمة الأخطاء المشتركة بين الرحلات والفنادق وبطاقات eSIM والحساب 180 رمزًا. وعندما يرفض المورّد طلبًا أو إعادة شحن، تكون الإجابة supplier_error مع حالة HTTP التي أعادها المورّد نفسه. لا يُخصم أي مبلغ ويُحفظ الحجز الفاشل. وبعد إعادة تشغيل مباشرة، قد يجيب الكتالوج وقائمة الأجهزة بالرمز 202 مع success بقيمة false: انتظر بضع ثوانٍ ثم اسأل مجددًا.
إعادة المحاولة دون طلب مزدوج
لا يملك FX-Port مفتاح idempotency، فلا توجد ترويسة Idempotency-Key لإرسالها. القراءات آمنة التكرار، أما إنشاء طلب أو إعادة شحن فليس كذلك. يرفض FX-Port التكرار الواضح بالرمز 409 مع duplicate_request: أي طلب لباقة ما زالت قيد المعالجة. وفي Live يرفض أيضًا طلب الباقة نفسها مرة أخرى خلال 60 ثانية من آخر طلب مؤكد لوكالتك، أيًّا كان المسافر. تجيب الطلبات عادةً خلال بضع ثوانٍ، لكن المورّد البطيء قد يستغرق وقتًا أطول بكثير. إذا انتهت مهلة الاستدعاء أو انقطع الاتصال، فلا ترسل الطلب مرة أخرى فورًا، لأن الـ eSIM قد تكون أُنشئت. ابحث عنها بالمعامل search في قائمة الحجوزات باستخدام البريد الإلكتروني للمسافر، ولا تطلب من جديد إلا إذا لم يُنشأ شيء.
لا Webhooks: اسأل عند الحاجة
لا يستدعي FX-Port أي عنوان URL لديك، لا في Sandbox ولا في Live. يجيب الطلب بالـ eSIM، أو بعنصر نائب يبدأ بـ PENDING- ما دام المورّد لم يُعدها بعد. وتطلب أي شيء آخر عند حاجتك إليه: بيانات الإعداد أو الاستهلاك أو قائمة الحجوزات.
التخزين المؤقت والسرعة
يُحتفظ بالاستهلاك حتى 15 دقيقة، وبقائمة باقات إعادة الشحن بضع دقائق، ويتجاوز force=true التخزين المؤقت. الكتالوج غير المصفّى إجابة ضخمة جدًا بلا ترقيم صفحات، لذا أرسل country واقبل الضغط عبر Accept-Encoding: gzip. تعود عناوين الباقات بلغة المعامل locale؛ والطلب الأول بلغة غير الإنجليزية أبطأ، لأن النص يُجلب حينها ثم يُخزَّن مؤقتًا بعد ذلك.
حدود معدّل الطلبات
تُحتسب الحدود لكل مفتاح وفي الدقيقة ضمن مجموعتين، وتحمل كل إجابة ratelimit-limit وratelimit-remaining، فتستطيع التباطؤ قبل أن تُرفض طلباتك. بعد الرمز 429، انتظر عدد الثواني المذكور في Retry-After ثم أعد المحاولة بتراجع أسّي (exponential backoff) مع تأخير عشوائي (jitter). وقد تُجاب الطلبات أو عمليات إعادة الشحن الكثيرة لمفتاح واحد أو وكالة واحدة والجارية في آن واحد بالرمز concurrency_limit_exceeded.
| نوع الاستدعاء | في الدقيقة |
|---|---|
| إنشاء الطلبات وعمليات إعادة الشحن | 1,200 |
| كل نقطة نهاية eSIM أخرى | 6,000 |
سقف الطلبات وعمليات إعادة الشحن الجارية في آن واحد يعمل حاليًا في وضع المراقبة: يُحتسب ولا يُطبَّق، فلا يُرفض شيء بسببه بعد، وسيعلن سجل التغييرات عن يوم تطبيقه. اعتبر هذه الأرقام السياسة الحالية لا وعدًا. لمفاتيح Sandbox عدّادات الدقيقة نفسها لمفاتيح Live، فجدوِل اختبارات الحمل بدل تشغيلها في حلقة متكررة.
الأسماء والإصدارات
حقول الطلب بصيغة snake_case، مثل first_name وagent_id. وما زالت الصيغ الأقدم تعمل: يُقرأ user_id على أنه agent_id ويضيف إدخالًا إلى warnings، ويُقبل customer_email بوصفه email دون إدخال كهذا. تُبقي كثير من الإجابات مفتاحًا أقدم بجانب نظيره بصيغة snake_case بالقيمة نفسها، مثل order_id بجانب code، ويعيد ?naming=snake مفاتيح snake_case فقط. يقع الإصدار في المسار /api/v1: فأي تغيير كاسر سيحمل بادئة جديدة، أما الحقول والصيغ الجديدة فإضافية.
ابدأ في Sandbox المجاني ثم انتقل إلى Live
كل ما في هذه الصفحة يعمل اليوم في Sandbox. مفتاح Sandbox ذاتي الإصدار ومجاني، ولا يمسّ رصيدك الحقيقي أبدًا.
أنشئ حسابًا
سجّل حسابًا في FX-Port. مفاتيح Sandbox مجانية، وحجوزات Sandbox لا تترتب عليها رسوم فعلية.
أنشئ مفتاح Sandbox
من صفحة API في لوحة التحكم، أنشئ مفتاحًا يبدأ بـ
fxp_test_. يستطيع مفتاح القراءة البحث والقراءة، ويستطيع مفتاح القراءة + الكتابة إنشاء حجوزات تجريبية أيضًا.أرسل أول طلب
هناك عنوان URL أساسي واحد، ويُرسَل المفتاح في الترويسة
Authorizationبوصفه رمز Bearer. يشرح دليل البدء السريع كيفية إجراء أول استدعاء.انتقل إلى Live عندما تكون جاهزًا
استبدل المفتاح بمفتاح
fxp_live_. يعمل Live بعد اعتماد وكالتك؛ وإلى ذلك الحين تردّ الواجهة بالخطأ403 agency_not_active. تُدفع الحجوزات الفعلية من رصيد ممول.
أول طلب كتالوج بصيغة cURL. تعرض الوثائق الطلب نفسه بكل اللغات المدعومة.
الطلب
curl 'https://api.fx-port.com/api/v1/esims/packages?country=france&type=local' \
-H "Authorization: Bearer fxp_test_YOUR_KEY"البدء السريع: أول استدعاء في Sandbox
ما الذي يفعله Sandbox
الطلب في Sandbox ينشئ لدى المورّد eSIM اختبارية حقيقية برمز تفعيل وهمي، فلا يمكن تثبيتها على هاتف. لا يُخصم أي مبلغ، وتصرّح الإجابات بذلك: balanceDebited وtransactionCreated وpayoutCreated كلها false. وتجيب إعادة الشحن برصيد صفر. الاستهلاك ثابت: تُظهر الـ eSIM الجديدة حصتها الكاملة والحالة ACTIVE. وحجوزات Sandbox لا تظهر إلا لمفاتيح Sandbox.
ما لا يختبره إلا Live
فحص الرصيد وفحص التكرار وقفل الرصيد تعمل في Live وحده. لذا لا تظهر في Sandbox أبدًا الإجابات 402 مع insufficient_balance، ولا 409 عند طلب الباقة نفسها خلال 60 ثانية، ولا 503 مع balance_lock_timeout. اكتب معالجتها اعتمادًا على قائمة رموز الأخطاء.
الانتقال إلى Live
ترتبط مفاتيح Live باعتماد الوكالة: إلى أن تُعتمد وكالتك، يجيب مفتاح Live بـ agency_not_active ويواصل مفتاح Sandbox عمله. تُدفع طلبات Live من رصيد وكالة ممول. والانتقال إلى Live يغيّر المفتاح لا الكود، لأن Sandbox وLive يشتركان في عنوان URL أساسي واحد.
من يبني على واجهة eSIM API
تعتمد كل فئة على جزء مختلف من الاستدعاءات نفسها.
وكالات تبيع رحلات السفر
تبيع الوكالات eSIM إلى جانب الرحلة الجوية والفندق. تطلبها بالبريد الإلكتروني الخاص بالمسافر، فيرسل المورّد رمز QR ورابط المشاركة، وتقرأ الاستهلاك حين يسأل المسافر. وتعود نسبة العمولة مع كل باقة، ويسجّل agent_id أي مستخدم في وكالتك أنشأ الطلب.
شركات OTA والأسواق الإلكترونية
تبني الأسواق الإلكترونية صفحة التصفح أولًا: دولة واحدة في كل مرة، وباقات محلية أو إقليمية، والشبكات وحصة البيانات لكل باقة، وفحص الجهاز قبل أن يشتري المسافر. ويمكن لشاشة تعرض بطاقات eSIM الخاصة بمسافر أن تقرأ استهلاك ما يصل إلى 50 منها في استدعاء واحد.
فرق تقنيات السفر والشركات
تبني فرق تقنيات السفر وأقسام سفر الشركات أدوات حجز خاصة بها. وكل ما يلزم للبدء متاح للعموم: ملف OpenAPI ومجموعة Postman ووثائق نصية يستطيع مساعد برمجة بالذكاء الاصطناعي قراءتها، فينطلق النموذج الأول من العقد الحقيقي.
واجهة eSIM API: الأسئلة الشائعة
ما واجهة eSIM API من FX-Port، ولمن هي؟
هي واجهة REST تتيح لوكالة سفر أو شركة OTA أو موزّع بيع باقات بيانات eSIM للسفر عبر تكامل واحد. تعرض باقات وجهة ما بأسعار بعملة وكالتك، وتطلب إحداها لمسافر. وتسلّم المسافر رمز QR، وتتابع الاستهلاك، وتعيد الشحن. كل شيء بصيغة JSON عبر HTTPS، ويصف ملف OpenAPI كل نقطة نهاية.
هل يوجد Sandbox مجاني، وكيف أحصل على مفتاح؟
نعم. أنشئ حسابًا في FX-Port، وافتح صفحة API في لوحة التحكم، وأنشئ مفتاح Sandbox؛ يمكنك فعل ذلك بنفسك ودون أي تكلفة. الطلب في Sandbox ينشئ eSIM اختبارية برمز تفعيل وهمي، فلا يمكن تثبيتها على هاتف. ولا يُخصم شيء من رصيدك. يشترك Sandbox وLive في عنوان URL أساسي واحد، فالكود الذي تختبره هو الكود الذي تطلقه.
ماذا يتطلب الانتقال إلى Live؟
يجب أن تُعتمد وكالتك قبل أن يعمل مفتاح Live. وإلى ذلك الحين يُرفض مفتاح Live ويواصل مفتاح Sandbox عمله. تُدفع طلبات Live من رصيد وكالة ممول لا يمسّه Sandbox أبدًا، ويمكن قصر أي مفتاح على قائمة عناوين IP. والتبديل يعني تغيير المفتاح فقط؛ فكل إجابة تذكر البيئة التي صدرت عنها.
أي الدول والباقات يمكنني بيعها؟
الباقات متاحة لأكثر من 190 دولة، وتظهر الباقات الإقليمية تحت منطقتها. تختلف الباقات في حصة البيانات ومدة الصلاحية والشبكات وإمكانية إعادة الشحن. اقرأ هذه الحقول ومعرّف الباقة من إجابة الكتالوج بدل كتابتها ثابتة في الكود. واطلب دولة واحدة في كل مرة، لأن الكتالوج كاملًا إجابة ضخمة جدًا. وتتيح قائمة أجهزة منفصلة فحص هاتف المسافر قبل البيع.
كيف يستلم المسافر الـ eSIM؟
تحمل إجابة الطلب رمز QR وسلسلة التفعيل الخاصة به ورابط تثبيت لجهاز iPhone وصفحة مشاركة. يمكنك عرضها في شاشاتك. كما يطلب FX-Port من المورّد إرسال رمز QR ورابط مشاركة بالبريد الإلكتروني إلى عنوان المسافر فور إنشاء الـ eSIM. وإذا لم يُعد المورّد الـ eSIM بعد، فالطلب موجود مع ذلك وتتوافر البيانات لاحقًا من استدعاء بيانات الإعداد.
كيف تترابط الأسعار والعمولة ورصيدي؟
تحمل كل باقة هذه الحقول المالية بعملة وكالتك: السعر الأساسي قبل عمولتك، والسعر الإجمالي الذي تحاسب به المسافر، والمبلغ المخصوم من رصيدك، ونسبة عمولتك. عمولتك هي السعر الإجمالي ناقص المبلغ المخصوم. اقرأ هذه الحقول بدل إعادة بنائها، لأن المبلغ المخصوم خاص بوكالتك. وفي Sandbox لا يُخصم شيء؛ أما في Live فيغادر المبلغ المخصوم رصيد وكالتك.
هل يمكنني إعادة شحن eSIM، وكيف أعرف كم بقي؟
نعم، باستدعاءين: اعرض الباقات التي يمكن إضافتها إلى الـ eSIM المحددة، ثم أنشئ إعادة الشحن بإحداها. إعادة الشحن ليست ممكنة دائمًا، لأن المورّد قد يغيّر مشغّل الشبكة في دولة ما. وتعني القائمة الفارغة حينها أن المسافر يحتاج إلى eSIM جديدة. الاستهلاك مخزَّن مؤقتًا حتى 15 دقيقة، فعامله على أنه رقم حديث، ويقرأ استدعاء واحد حتى 50 من بطاقات eSIM.
كيف يُبلَّغ عن الإخفاق، وهل توجد Webhooks؟
يعود الإخفاق بصيغة واحدة مع رمز خطأ ثابت، وهذا الرمز هو ما يجب أن يختبره برنامجك لا نص الرسالة. القراءات آمنة التكرار مع التراجع (backoff). أما إنشاء طلب أو إعادة شحن فمختلف: لا يوجد مفتاح idempotency، لذا ابحث عن الحجز بعد انتهاء المهلة قبل أن تحاول مجددًا. ويرفض FX-Port التكرار الواضح، كطلب الباقة نفسها مرتين خلال 60 ثانية في Live. ولا توجد Webhooks.
هل يمكنني إلغاء طلب eSIM أو استرداده عبر API؟
لا. لا تملك الواجهة نقطة نهاية لإلغاء طلب eSIM أو استرداده. كل طلب ينشئ eSIM واحدة بالضبط، فتحقق من الباقة وبيانات المسافر قبل إرساله. وإذا رفض المورّد طلبًا فلا يُخصم شيء ويُحفظ حجز فاشل. وفي حال وجود مشكلة في طلب بعينه، راسل فريق المطورين واذكر معرّف حجزه.
ماذا أحتاج للبدء، وما الأدوات المساعدة؟
تحتاج إلى مفتاح Sandbox وعميل HTTP. تضيف الوثائق ملف OpenAPI 3.1 ومجموعة Postman وأمثلة برمجية بـ 9 لغات وملفات نصية لمساعدي الذكاء الاصطناعي. احتفظ بمفاتيحك على خادمك، لا في متصفح ولا في تطبيق. والجزء الذي يستغرق وقتًا أطول هو عملية الدفع لديك وتسليم رمز QR للمسافر ومعالجة الأخطاء.
واجهات FX-Port الأخرى
ترافق eSIM عادةً رحلة. تستخدم الرحلات الجوية والفنادق المفاتيح نفسها وجسم الأخطاء نفسه والأعراف نفسها المعتمدة مع بطاقات eSIM، وتقع حجوزاتها في سجل الحساب نفسه.
ابحث عن الرحلات وسعّرها واحجزها، وادفع الطلبات المحجوزة مؤقتًا، وألغِ، واقرأ التذاكر.
ابحث عن الفنادق، وتحقق من الأسعار، واحجز مسبقًا وأكّد الحجز، واقرأ القسائم وألغِ.
- واجهة API للنقلمعاينة
احصل على عروض أسعار النقل من المطار وإليه، واحجزه وتتبّعه وألغِه.
تفضّل ألا تكتب كودًا؟ يمكن للوكالات أيضًا بيع بطاقات eSIM من لوحة تحكم FX-Port. بيع بطاقات eSIM من لوحة التحكم
نفّذ أول طلب eSIM في Sandbox
أنشئ حسابًا، وأصدر مفتاح Sandbox، واعرض الباقات، وأنشئ طلبًا، واقرأ الاستهلاك اليوم. وتتبعها مفاتيح Live حين تُعتمد وكالتك.