1. Trang chủ
  2. eSIM API

MớiREST API kèm tệp OpenAPI 3.1

API eSIM cho đại lý du lịch, OTA và đơn vị bán lại

Bán eSIM du lịch qua một REST API. Liệt kê gói dữ liệu theo quốc gia với giá theo tiền tệ của đại lý, đặt eSIM cho du khách, gửi mã QR cho du khách, theo dõi dung lượng đã dùng và nạp thêm dữ liệu. Một Base URL phục vụ cả sandbox và Live. Hãy bắt đầu bằng khóa sandbox miễn phí; khóa Live hoạt động sau khi đại lý của bạn được duyệt.

Nhận khóa sandbox miễn phíĐọc hướng dẫn eSIM

Tài liệu được viết bằng tiếng Anh.

Base URL
https://api.fx-port.com/api/v1
Xác thực
Authorization: Bearer fxp_test_...
Tiền tố khóa
fxp_test_ / fxp_live_
Endpoint
12
Quốc gia có gói
190+
Ngôn ngữ mã mẫu
9

Trong trang này

  • Console
  • Năm bước
  • Giá
  • Sau khi bán
  • Endpoint
  • Môi trường thực tế
  • Sandbox
  • Ai xây trên API này
  • FAQ
  • API liên quan
  • Bắt đầu

API eSIM, từng lệnh gọi một

Theo dõi từng bước một lần bán eSIM khi mỗi yêu cầu được tạo, gửi và nhận phản hồi. Các phiên gồm bán eSIM, giữ du khách luôn kết nối, kiểm tra thiết bị và đơn đặt, cùng những lỗi đáng xử lý. Yêu cầu và phản hồi là ví dụ lấy từ tài liệu, và trang này không bao giờ gọi API thật.

3 yêu cầu: Liệt kê các gói, Đặt eSIM, Đọc dữ liệu cài đặt.

Phiên minh họa: phần body là ví dụ lấy từ tài liệu, ngày được dời về sau để luôn nằm sau hôm nay, và thời gian chỉ mang tính minh họa. Trang này không gửi yêu cầu nào.

Tải bộ sưu tập Postman

Tìm gói, đặt gói, đọc dữ liệu cài đặt

Bắt đầu với các gói của một quốc gia, đặt một gói cho du khách, rồi đọc dữ liệu cài đặt của đơn. Sandbox tạo một eSIM thử với mã kích hoạt giả và không trừ khoản nào, còn console hiển thị bản rút gọn của phản hồi danh mục gói.

  1. Liệt kê các gói

    Lệnh gọi danh mục nhận country và type rồi trả về các gói phù hợp, với giá theo tiền tệ của đại lý. Hãy giữ package_id của gói du khách chọn.

    Yêu cầu GET /esims/packages
    curl 'https://api.fx-port.com/api/v1/esims/packages?country=france&type=local' \
      -H "Authorization: Bearer fxp_test_YOUR_KEY"
    Phản hồi 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
      }
    }

    Ví dụ đã rút gọn để hiển thị

    • PASS Mã trạng thái là 200
    • PASS $.success bằng true
    • PASS $.data[0].package_id tồn tại
    • PASS $.data[0].balance_debit_amount tồn tại

    Tài liệu tham chiếu của GET /esims/packages

  2. Đặt eSIM

    Tạo đơn nhận package_id cùng địa chỉ email và số điện thoại của du khách. Hãy giữ booking_id và data.iccid trong phản hồi. Ở sandbox, balanceDebited, transactionCreated và payoutCreated đều là false.

    Yêu cầu 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"
    }'
    Phản hồi 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
    }

    Ví dụ đã rút gọn để hiển thị

    • PASS Mã trạng thái là 200
    • PASS $.environment bằng sandbox
    • PASS $.balance_debited bằng false
    • PASS $.data.iccid tồn tại

    Tài liệu tham chiếu của POST /esims/orders

  3. Đọc dữ liệu cài đặt

    Lệnh gọi dữ liệu cài đặt nhận booking_id và trả về mã QR, dữ liệu kích hoạt, liên kết cài đặt và các bước cài đặt của đơn. Chỉ hiển thị cho du khách sở hữu eSIM.

    Yêu cầu 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"
    Phản hồi 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"
      }
    }

    Ví dụ đã rút gọn để hiển thị

    • PASS Mã trạng thái là 200
    • PASS $.data.package_id bằng france-in-7days-1gb
    • PASS $.data.sims[0].iccid tồn tại

    Tài liệu tham chiếu của GET /esims/bookings/{booking_id}/setup-instructions

Đọc dung lượng đã dùng, rồi nạp thêm

Khi du khách đã có eSIM, hãy đọc dữ liệu còn lại, hỏi gói nào có thể thêm vào đúng eSIM đó, rồi tạo lệnh nạp thêm. Dung lượng đã dùng được lưu đệm, nên một con số có thể cũ vài phút. Lịch sử nạp thêm nằm ở thanh bên và trong bản ghi.

  1. Đọc dung lượng đã dùng

    Lệnh gọi dung lượng đã dùng nhận ICCID của đơn và trả về remaining và total tính bằng megabyte, cùng status và ngày hết hạn. Phản hồi đến từ bộ nhớ đệm, và force=true hỏi lại nhà cung cấp.

    Yêu cầu GET /esims/usage/{iccid}
    curl https://api.fx-port.com/api/v1/esims/usage/8900000540463077957 \
      -H "Authorization: Bearer fxp_test_YOUR_KEY"
    Phản hồi 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 Mã trạng thái là 200
    • PASS $.data.data.status bằng ACTIVE
    • PASS $.data.data.remaining tồn tại

    Tài liệu tham chiếu của GET /esims/usage/{iccid}

  2. Liệt kê gói nạp thêm

    Lệnh gọi này liệt kê các gói có thể thêm vào đúng eSIM này ngay hôm nay. Danh sách trống nghĩa là hiện không nạp thêm được. Hãy lấy package_id của gói nạp thêm từ danh sách này, không bao giờ từ đơn gốc.

    Yêu cầu GET /esims/topup-packages/{iccid}
    curl https://api.fx-port.com/api/v1/esims/topup-packages/8900000540463077957 \
      -H "Authorization: Bearer fxp_test_YOUR_KEY"
    Phản hồi 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
          }
        ]
      }
    }

    Ví dụ đã rút gọn để hiển thị

    • PASS Mã trạng thái là 200
    • PASS $.data.data có 2 phần tử
    • PASS $.data.data[0].type bằng topup

    Tài liệu tham chiếu của GET /esims/topup-packages/{iccid}

  3. Tạo lệnh nạp thêm

    Tạo lệnh nạp thêm nhận package_id từ danh sách đó và ICCID. Trên Live, số dư của bạn chỉ bị trừ sau khi nhà cung cấp chấp nhận. Ở sandbox, balance trong phản hồi bằng không và không có khoản nào bị trừ.

    Yêu cầu 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"
    }'
    Phản hồi 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 Mã trạng thái là 200
    • PASS $.environment bằng sandbox
    • PASS $.balance_debited bằng false
    • PASS $.data.balance.current bằng 0

    Tài liệu tham chiếu của POST /esims/topups

  4. Đọc lịch sử nạp thêm

    Lịch sử nạp thêm liệt kê các lần nạp thêm của một eSIM, mới nhất trước. Các lần nạp thêm không nằm trong danh sách đơn đặt, nên đây là nơi bạn tìm thấy chúng.

    Yêu cầu 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"
    Phản hồi 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 Mã trạng thái là 200
    • PASS $.data[0].type bằng topup

    Tài liệu tham chiếu của GET /esims/bookings/{iccid}/topup-history

Kiểm tra thiết bị, rồi đọc đơn đặt

Trước khi bán, hãy kiểm tra điện thoại của du khách có hỗ trợ eSIM không. Sau khi bán, hãy đọc các đơn đặt và kiểm tra mã đơn có phải của bạn không. Dung lượng đã dùng hàng loạt được liệt kê ở thanh bên.

  1. Kiểm tra danh sách thiết bị

    Lệnh gọi thiết bị tương thích trả về các thiết bị được biết là hỗ trợ eSIM, với brand, model và os. Hãy tra điện thoại của du khách trước khi bán.

    Yêu cầu GET /esims/compatible-devices
    curl https://api.fx-port.com/api/v1/esims/compatible-devices \
      -H "Authorization: Bearer fxp_test_YOUR_KEY"
    Phản hồi 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 Mã trạng thái là 200
    • PASS $.success bằng true
    • PASS $.data[0].model tồn tại

    Tài liệu tham chiếu của GET /esims/compatible-devices

  2. Liệt kê đơn đặt

    Danh sách đơn đặt trả về các đơn eSIM của đại lý bạn, mới nhất trước. Yêu cầu này chỉ lấy một đơn qua tham số limit, và pagination cho biết có bao nhiêu đơn khớp và còn trang tiếp theo không.

    Yêu cầu GET /esims/bookings
    curl 'https://api.fx-port.com/api/v1/esims/bookings?limit=1' \
      -H "Authorization: Bearer fxp_test_YOUR_KEY"
    Phản hồi 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 Mã trạng thái là 200
    • PASS $.data có 1 phần tử
    • PASS $.pagination.has_more bằng true

    Tài liệu tham chiếu của GET /esims/bookings

  3. Kiểm tra quyền sở hữu

    Lệnh kiểm tra quyền sở hữu trả is_owner là true khi đơn thuộc đại lý của bạn. Đơn của đại lý khác và đơn không tồn tại nhận cùng một phản hồi, nên không thể dùng lệnh này để dò mã đơn.

    Yêu cầu 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"
    Phản hồi 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 Mã trạng thái là 200
    • PASS $.is_owner bằng true

    Tài liệu tham chiếu của GET /esims/bookings/{booking_id}/verify

  4. Đọc dung lượng hàng loạt

    Một lệnh gọi đọc dung lượng đã dùng của nhiều eSIM liệt kê trong iccids và trả về một mục cho mỗi ICCID, mỗi mục có status riêng. Luôn gửi iccids.

    Yêu cầu GET /esims/usage/bulk
    curl 'https://api.fx-port.com/api/v1/esims/usage/bulk?iccids=8900000540463077957' \
      -H "Authorization: Bearer fxp_test_YOUR_KEY"
    Phản hồi 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 Mã trạng thái là 200
    • PASS $.data[0].status bằng success

    Tài liệu tham chiếu của GET /esims/usage/bulk

Các sự cố và cách xử lý từng loại

Mọi lỗi dùng chung một nội dung, và phần tử đầu của errors có code ổn định. Các lệnh đặt đơn này cố tình thất bại, mỗi lệnh vì một lý do khác nhau và với một cách xử lý khác nhau.

  1. Khóa chỉ đọc khi đặt đơn

    Khóa chỉ đọc gọi lệnh đặt đơn bị từ chối với 403 và read_write_permission_required, trước khi nội dung được đọc. Hãy chuyển sang khóa đọc + ghi.

    Yêu cầu 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"
    }'
    Phản hồi 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 Mã trạng thái là 403
    • PASS Mã lỗi là read_write_permission_required
    • PASS $.errors[0].type bằng permission_error

    Tài liệu tham chiếu của POST /esims/orders

  2. Địa chỉ email không hợp lệ

    Giá trị không phải địa chỉ email bị từ chối với 400 và invalid_email, và field nêu email. Hãy sửa giá trị trước khi gửi lại đơn: cùng yêu cầu sẽ thất bại như cũ.

    Yêu cầu 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"
    }'
    Phản hồi 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 Mã trạng thái là 400
    • PASS Mã lỗi là invalid_email
    • PASS $.errors[0].field bằng email

    Tài liệu tham chiếu của POST /esims/orders

  3. Đơn trùng lặp

    Đơn cho gói đang được xử lý bị từ chối với 409 và duplicate_request. Đừng gửi lại ngay: hãy tra đơn đặt trước, và chỉ đặt lại nếu chưa có đơn nào được tạo.

    Yêu cầu 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"
    }'
    Phản hồi 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 Mã trạng thái là 409
    • PASS Mã lỗi là duplicate_request
    • PASS $.errors[0].type bằng conflict

    Tài liệu tham chiếu của POST /esims/orders

  4. Quá nhiều yêu cầu

    Vượt giới hạn mỗi phút, lệnh gọi bị từ chối với 429 và rate_limit_exceeded, và header Retry-After cho biết phải chờ bao nhiêu giây. Sau đó hãy thử lại với backoff.

    Yêu cầu 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"
    }'
    Phản hồi 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 Mã trạng thái là 429
    • PASS Mã lỗi là rate_limit_exceeded
    • PASS Có header Retry-After
    • PASS $.errors[0].details.retry_after bằng 12

    Tài liệu tham chiếu của POST /esims/orders

Từ danh mục gói đến du khách có kết nối trong năm bước

Tích hợp chỉ là một lộ trình ngắn: đọc danh mục gói, tạo đơn, giao eSIM cho du khách, theo dõi dung lượng đã dùng và nạp thêm khi hết dữ liệu. Chỉ đơn đặt và lệnh nạp thêm làm thay đổi dữ liệu. Mọi lệnh gọi khác chỉ đọc.

Đọc danh mục gói của một điểm đến

Liệt kê các gói của một quốc gia, với giá đã tính sẵn theo tiền tệ của đại lý, rồi giữ lại package_id của gói du khách chọn. Luôn gửi country: toàn bộ danh mục là một phản hồi rất lớn và không phân trang. Hãy đọc mã gói từ phản hồi thay vì viết cứng, vì danh mục thay đổi.

  • GET /api/v1/esims/packages

Yêu cầu

curl 'https://api.fx-port.com/api/v1/esims/packages?country=france&type=local' \
  -H "Authorization: Bearer fxp_test_YOUR_KEY"

Phản hồi 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
  }
}

Danh mục gói theo quốc gia

Tạo đơn

Gửi package_id cùng địa chỉ email và số điện thoại của du khách. Một đơn tạo đúng một eSIM, và trên Live đơn trừ vào số dư đại lý của bạn. Hãy giữ booking_id và ICCID trong phản hồi, vì mọi lệnh gọi sau đó đều cần một trong hai.

  • POST /api/v1/esims/orders

Yêu cầu

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

Phản hồi 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
}
Phản hồi của đơn đặt chứa những gì
TrườngChứa gì
booking_id Mã tham chiếu FX-Port của đơn. Hãy giữ lại để dùng cho dữ liệu cài đặt, kiểm tra quyền sở hữu và hồ sơ của bạn.
data.iccid Mã định danh của eSIM. Dung lượng đã dùng, nạp thêm và hướng dẫn cài đặt đều tra cứu theo ICCID.
data.sim.qrcode data.sim.qrcode_url Chuỗi kích hoạt mà mã QR mã hóa, cùng liên kết tới hình ảnh mã QR.
data.sim.direct_apple_installation_url data.sim.sharing Liên kết bắt đầu cài đặt trên iPhone, và trang chia sẻ nơi du khách mở eSIM bằng mã truy cập. Lệnh gọi dữ liệu cài đặt bổ sung liên kết cho Android.
Dữ liệu kích hoạt rất nhạy cảm: chỉ hiển thị cho du khách sở hữu eSIM đó.
Nếu nhà cung cấp chưa trả eSIM, đơn vẫn tồn tại: ICCID bắt đầu bằng PENDING-, và dữ liệu có thể lấy từ lệnh gọi dữ liệu cài đặt khi nhà cung cấp đã có.

Tạo đơn eSIM

Giao eSIM cho du khách

Phản hồi chứa mã QR và chuỗi kích hoạt của mã đó, nên bạn có thể hiển thị trên màn hình của mình. FX-Port cũng yêu cầu nhà cung cấp gửi email kèm mã QR và liên kết chia sẻ tới địa chỉ của du khách, nên bạn không phải chuyển tiếp. Lệnh gọi dữ liệu cài đặt trả lại cùng dữ liệu đó vào lúc sau, kèm các bước cài đặt.

  • GET /api/v1/esims/bookings/{booking_id}/setup-instructions

Yêu cầu

curl https://api.fx-port.com/api/v1/esims/bookings/FX-1793546602916/setup-instructions \
  -H "Authorization: Bearer fxp_test_YOUR_KEY"

Phản hồi 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
  }
}

Dữ liệu cài đặt theo đơn hoặc ICCID

Theo dõi dung lượng đã dùng

Đọc dữ liệu còn lại và ngày hết hạn của một eSIM theo ICCID. Phản hồi được lưu đệm tối đa 15 phút, vì vậy hãy dùng cho một màn hình hoặc một lời nhắc, không dùng làm đồng hồ đo.

  • GET /api/v1/esims/usage/{iccid}

Yêu cầu

curl https://api.fx-port.com/api/v1/esims/usage/8900000540463077957 \
  -H "Authorization: Bearer fxp_test_YOUR_KEY"

Phản hồi 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"
    }
  }
}

Dung lượng eSIM đơn lẻ và hàng loạt

Nạp thêm dữ liệu khi hết

Liệt kê các gói có thể thêm vào đúng eSIM này, rồi tạo lệnh nạp thêm bằng một trong các gói đó. Nếu danh sách trống, eSIM hiện không nạp thêm được và du khách cần một eSIM mới.

  • GET /api/v1/esims/topup-packages/{iccid}
  • POST /api/v1/esims/topups

Yêu cầu

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

Phản hồi 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
}

Kiểm tra và tạo lệnh nạp thêm

Giá, hoa hồng và số dư của bạn

Mỗi gói đi kèm các trường về tiền, được tính trên máy chủ theo tiền tệ của đại lý. Giá trong nội dung yêu cầu bị bỏ qua, nên đơn luôn được tạo theo giá máy chủ tính.

Các trường về tiền của một gói eSIM
TrườngChứa gì
base_price price Giá gói trước hoa hồng của bạn. Đây không phải số tiền trừ vào số dư của bạn.
total_price retail_price Giá cần thu của du khách, đã gồm hoa hồng của bạn.
balance_debit_amount b2b_price Số tiền rời khỏi số dư đại lý khi bạn đặt gói trên Live. Hãy đọc giá trị này, đừng tự tính.
agency_commission commission_rate Tỷ lệ hoa hồng của bạn, dạng văn bản và dạng số. Đơn đặt trả về hoa hồng của bạn dưới dạng số tiền.

Trong ví dụ về danh mục gói, du khách trả 468.84 DZD. Một đơn trên Live trừ 418.60 DZD vào số dư của bạn, và phần chênh lệch, 50.24 DZD, là hoa hồng của bạn.

Tỷ lệ hoa hồng thuộc về đại lý của bạn

Tỷ lệ hoa hồng được trả về cùng mỗi gói, và không giống nhau ở mọi đại lý. Một đại lý doanh nghiệp có hợp đồng có thể có tỷ lệ bằng không, khi đó giá tổng bằng số tiền trừ.

Hãy đọc các trường, đừng tự dựng lại

Số tiền trừ có thể cao hơn giá gốc, vì đã gồm các khoản riêng của đại lý bạn. Vì vậy hãy đọc balance_debit_amount và không bao giờ tính từ base_price. Từ price là giá gốc trong danh mục nhưng là giá bán lẻ trong đơn đặt, gói nạp thêm và dữ liệu cài đặt: hãy dùng base_price và total_price ở mọi nơi, sự mơ hồ sẽ biến mất.

Định giá theo tiền tệ của đại lý

Mọi số tiền đều đã được quy đổi sang tiền tệ của đại lý, dù nhà cung cấp dùng tiền tệ nào. Phản hồi cũng cho biết tiền tệ của nhà cung cấp và tỷ giá, để bạn tự kiểm chứng tỷ giá và không cần quy đổi lại.

Cách hình thành giá eSIM

Sau khi bán: dung lượng đã dùng, nạp thêm và dữ liệu cài đặt

Một lần bán không kết thúc ở đơn đặt. Các lệnh gọi này giữ du khách luôn kết nối, và chỉ áp dụng cho eSIM mà đại lý của bạn đã đặt trong cùng môi trường với khóa của bạn.

Đọc dung lượng đã dùng và độ mới của số liệu

Lệnh gọi này trả về dữ liệu còn lại, hạn mức, trạng thái và ngày hết hạn của một eSIM, hoặc của tối đa 50 eSIM trong một lần gọi. FX-Port giữ phản hồi gần nhất tối đa 15 phút để bảo vệ giới hạn tốc độ của nhà cung cấp, nên một con số có thể cũ đến mức đó. Truyền force=true để hỏi lại nhà cung cấp, chẳng hạn ngay sau khi nạp thêm. Đừng làm vậy ở mọi yêu cầu, vì nhà cung cấp giới hạn tần suất đọc. Nếu nhà cung cấp không trả lời được, bạn nhận số liệu gần nhất đã biết, được đánh dấu là cũ.

Dung lượng eSIM đơn lẻ và hàng loạt

Nạp thêm dữ liệu: hỏi trước, tạo sau

Nạp thêm gồm hai lệnh gọi. Trước tiên liệt kê các gói có thể thêm vào đúng eSIM này, rồi tạo lệnh nạp thêm bằng một mã gói được trả về. Đừng dùng lại mã gói của đơn gốc, và đừng giữ sẵn gói nạp thêm để dùng sau: hãy hỏi lại khi du khách muốn nạp thêm. Nạp thêm bổ sung dữ liệu vào eSIM chứ không thay thế phần còn lại, nên hãy đọc kết quả qua lệnh gọi dung lượng đã dùng với force=true.

Kiểm tra và tạo lệnh nạp thêm

Khi không thể nạp thêm

Nhà cung cấp chọn nhà mạng phục vụ một quốc gia, và trong một số ít trường hợp họ đổi nhà mạng. Khi đó eSIM có thể tiếp tục hoạt động đến khi hết hạn, nhưng gói của nó không còn nạp thêm được. Danh sách gói nạp thêm trả về rỗng. Nếu nhà cung cấp từ chối lệnh nạp thêm, số dư của bạn không bị ảnh hưởng và lần thử được lưu thành một đơn thất bại. Phản hồi là supplier_error để bạn xử lý.

Vì sao có thể không nạp thêm được

Dữ liệu cài đặt và các bước cài đặt

Lệnh gọi dữ liệu cài đặt trả về mã QR, dữ liệu kích hoạt, liên kết cài đặt và các bước cài đặt của một đơn bất cứ khi nào bạn cần. Lệnh gọi hướng dẫn trả về các bước theo từng hệ điều hành, bằng ngôn ngữ bạn yêu cầu. Các bước này là văn bản chung của nhà cung cấp, nên hãy hiển thị chúng cạnh mã QR của đơn. Chỉ hiển thị cả hai cho du khách sở hữu eSIM.

Dữ liệu cài đặt theo đơn hoặc ICCID

Đơn đặt, lịch sử nạp thêm và quyền sở hữu

Danh sách đơn đặt trả về các đơn eSIM của đại lý bạn trong môi trường của khóa, mới nhất trước. Bạn có thể tìm theo mã đơn, tên du khách, địa chỉ email, tên gói hoặc ICCID. Các lần nạp thêm không nằm trong danh sách đó: hãy đọc chúng bằng lịch sử nạp thêm của một eSIM. Trước khi dựng liên kết hay màn hình quanh một mã đơn, lệnh kiểm tra quyền sở hữu cho bạn biết đơn đó có phải của bạn không. Đơn của đại lý khác và đơn không tồn tại nhận cùng một phản hồi.

Liệt kê và xác minh đơn eSIM

Mọi endpoint eSIM, kèm OpenAPI, Postman và mã mẫu

API eSIM có 12 endpoint dưới một Base URL. Mỗi dòng mở trang tham chiếu của lệnh gọi đó, với các trường yêu cầu, phản hồi, lỗi và ví dụ bằng 9 ngôn ngữ.

Các endpoint API eSIM kèm phương thức, đường dẫn, quyền của khóa và mục đích
EndpointChức năngKhóa
GET /api/v1/esims/packagesLiệt kê gói của một quốc gia hoặc khu vực, với giá đã tính sẵn theo tiền tệ của đại lý. Luôn gửi quốc gia: toàn bộ danh mục rất lớn và không phân trang.Đọc
GET /api/v1/esims/compatible-devicesCác thiết bị được biết là hỗ trợ eSIM, để kiểm tra trước khi du khách mua.Đọc
POST /api/v1/esims/ordersTạo một eSIM từ một gói cho du khách và cấp phát tại nhà cung cấp. Trên Live, lệnh này trừ vào số dư đại lý.Đọc + ghi
GET /api/v1/esims/topup-packages/{iccid}Các gói có thể thêm vào đúng một eSIM ngay hôm nay. Danh sách trống nghĩa là hiện không nạp thêm được.Đọc
POST /api/v1/esims/topupsThêm một gói nạp thêm vào eSIM hiện có. Trên Live, số dư của bạn chỉ bị trừ sau khi nhà cung cấp chấp nhận.Đọc + ghi
GET /api/v1/esims/usage/{iccid}Dữ liệu còn lại, hạn mức, trạng thái và ngày hết hạn của một eSIM. Phản hồi có thể cũ đến 15 phút.Đọc
GET /api/v1/esims/usage/bulkDung lượng đã dùng của tối đa 50 eSIM trong một lần gọi, mỗi ICCID một mục, mỗi mục có trạng thái riêng.Đọc
GET /api/v1/esims/bookingsCác đơn eSIM của đại lý bạn, mới nhất trước, có tìm kiếm và phân trang. Các lần nạp thêm không nằm trong danh sách này.Đọc
GET /api/v1/esims/bookings/{iccid}/topup-historyCác lần nạp thêm của một eSIM, mới nhất trước. Danh sách trống khi eSIM chưa có lần nào.Đọc
GET /api/v1/esims/bookings/{booking_id}/verifyKiểm tra mã đơn có thuộc đại lý của bạn không, trước khi dựng liên kết hay màn hình quanh mã đó.Đọc
GET /api/v1/esims/bookings/{booking_id}/setup-instructionsMã QR, dữ liệu kích hoạt, liên kết cài đặt và các bước cài đặt của một đơn, dạng JSON.Đọc
GET /api/v1/esims/instructions/{iccid}Hướng dẫn cài đặt từng bước cho một ICCID, theo hệ điều hành, bằng ngôn ngữ bạn yêu cầu.Đọc

OpenAPI 3.1

Một tệp mô tả mọi endpoint và mọi trường. Hãy tạo client từ tệp này, nhập vào công cụ API hoặc đưa cho trợ lý lập trình.

Tệp OpenAPI 3.1

Bộ sưu tập Postman

Bộ sưu tập eSIM bao phủ cả 12 endpoint trong các thư mục theo từng giai đoạn của một lần bán. Bộ này không chứa khóa, nên hãy thêm khóa của bạn.

Bộ sưu tập Postman cho eSIM

Mã mẫu bằng 9 ngôn ngữ

Mỗi trang tham chiếu in yêu cầu bằng cURL, Node.js, Python, PHP, Go, Java, C#, Swift và Kotlin, được tạo từ mô tả OpenAPI. Mọi yêu cầu eSIM đều có sẵn trong tất cả các ngôn ngữ đó.

Tài liệu tham chiếu API đầy đủ

Tài liệu cho trợ lý AI

llms.txt và llms-full.txt đưa tài liệu cho trợ lý AI dưới dạng văn bản thuần, và mọi trang tài liệu đều đọc được dưới dạng Markdown bằng cách thêm .md vào địa chỉ.

Chỉ mục llms.txt cho công cụ AI

Tài liệu API eSIM

Xây cho môi trường thực tế: khóa, lỗi, thử lại và lưu đệm

Một tích hợp eSIM được đánh giá ở môi trường thực tế qua xác thực, lỗi, thử lại, lưu đệm và giới hạn tốc độ. Dưới đây là những điều cần biết về từng mục.

Một Base URL, hai loại khóa

Mỗi yêu cầu mang một khóa dưới dạng Bearer token trong header Authorization. Tiền tố cho biết khóa dùng ở đâu: fxp_test_ cho sandbox và fxp_live_ cho Live. Cả hai cùng gọi một Base URL, và mỗi phản hồi JSON nêu môi trường nó đến từ trong environment. Khóa thuộc về máy chủ của bạn, không bao giờ để trong trình duyệt hay ứng dụng. FX-Port chỉ lưu mã băm của mỗi khóa, nên khóa đã mất không thể hiển thị lại. Thay đổi đối với khóa có thể mất vài phút để có hiệu lực.

Môi trường và bộ sưu tập Postman

Khóa nào gọi được lệnh nào

Khóa chỉ đọc có thể liệt kê gói, kiểm tra thiết bị, đọc dung lượng đã dùng và đọc đơn đặt. Tạo đơn hoặc lệnh nạp thêm cần khóa đọc + ghi, và khóa chỉ đọc thử làm vậy sẽ nhận read_write_permission_required. Mọi khóa đều có thể giới hạn theo danh sách địa chỉ IP, và lệnh gọi từ địa chỉ khác nhận ip_not_allowed. Hãy dùng khóa chỉ đọc ở nơi mã chỉ hiển thị kết quả.

Khóa và các mức quyền

Một định dạng lỗi cho mọi sự cố

Lệnh gọi thất bại trả về mảng errors. Phần tử đầu tiên có code ổn định, type cho biết cách xử lý và field gây lỗi. Hãy kiểm tra mã, đừng kiểm tra thông điệp. Danh sách lỗi dùng chung cho chuyến bay, khách sạn, eSIM và tài khoản có 180 mã. Khi nhà cung cấp từ chối một đơn hoặc một lệnh nạp thêm, phản hồi là supplier_error mang theo trạng thái HTTP riêng của nhà cung cấp. Không có khoản nào bị trừ và một đơn thất bại được lưu lại. Ngay sau khi khởi động lại, danh mục gói và danh sách thiết bị có thể trả 202 với success là false: hãy chờ vài giây rồi hỏi lại.

Danh sách đầy đủ mã lỗi

Thử lại mà không đặt hai lần

FX-Port không có khóa idempotency, nên không có header Idempotency-Key để gửi. Lệnh đọc có thể lặp lại an toàn; tạo đơn hoặc lệnh nạp thêm thì không. FX-Port từ chối bản trùng rõ ràng bằng 409 và duplicate_request: một đơn cho gói đang được xử lý. Trên Live, FX-Port còn từ chối cùng gói đó được đặt lại trong vòng 60 giây kể từ đơn đã xác nhận gần nhất của đại lý bạn, dù du khách là ai. Đơn thường được trả lời trong vài giây, nhưng nhà cung cấp chậm có thể mất lâu hơn nhiều. Nếu lệnh gọi hết thời gian chờ hoặc kết nối đứt, đừng gửi lại đơn ngay, vì eSIM có thể đã tồn tại. Hãy tìm bằng tham số search của danh sách đơn đặt, dùng địa chỉ email của du khách, và chỉ đặt lại nếu chưa có gì được tạo.

Thử lại an toàn sau khi hết thời gian chờ

Không có webhook: hãy hỏi khi cần

FX-Port không gọi một URL nào của bạn, ở sandbox hay Live. Một đơn trả lời bằng eSIM, hoặc bằng giá trị giữ chỗ PENDING- khi nhà cung cấp chưa trả eSIM. Mọi thứ khác bạn hỏi khi cần: dữ liệu cài đặt, dung lượng đã dùng hoặc danh sách đơn đặt.

Lưu đệm và tốc độ

Dung lượng đã dùng được giữ tối đa 15 phút và danh sách gói nạp thêm được giữ vài phút, còn force=true bỏ qua bộ nhớ đệm. Danh mục gói không lọc là một phản hồi rất lớn và không phân trang, nên hãy gửi country và chấp nhận nén bằng Accept-Encoding: gzip. Tên gói trả về theo ngôn ngữ của tham số locale; yêu cầu đầu tiên bằng ngôn ngữ khác tiếng Anh sẽ chậm hơn, vì văn bản được lấy lúc đó và lưu đệm cho các lần sau.

Giới hạn tốc độ

Giới hạn được tính theo từng khóa và từng phút, chia thành hai nhóm, và mọi phản hồi đều mang ratelimit-limit và ratelimit-remaining để bạn giảm tốc trước khi bị từ chối. Sau một lỗi 429, hãy chờ số giây ghi trong Retry-After rồi thử lại với backoff lũy thừa và jitter. Nếu một khóa hoặc một đại lý chạy quá nhiều đơn hoặc lệnh nạp thêm cùng lúc, phản hồi có thể là concurrency_limit_exceeded.

Giới hạn tốc độ eSIM theo khóa
Loại lệnh gọiMỗi phút
Tạo đơn và lệnh nạp thêm1,200
Mọi endpoint eSIM khác6,000

Hiện tại, mức trần cho số đơn và lệnh nạp thêm chạy cùng lúc đang ở chế độ quan sát: được đếm nhưng chưa áp dụng, nên chưa có gì bị từ chối vì nó, và changelog sẽ thông báo ngày bắt đầu áp dụng. Hãy xem các con số này là chính sách hiện hành chứ không phải cam kết. Khóa sandbox có cùng bộ đếm mỗi phút với khóa live, nên hãy lên lịch kiểm thử tải thay vì chạy trong vòng lặp.

Giới hạn tốc độ theo khóa

Tên và phiên bản

Các trường của yêu cầu viết theo snake_case, chẳng hạn first_name và agent_id. Các cách viết cũ vẫn dùng được: user_id được đọc như agent_id và thêm một mục warnings, còn customer_email được chấp nhận như email mà không có cảnh báo. Nhiều phản hồi giữ khóa cũ bên cạnh bản snake_case cùng giá trị, chẳng hạn order_id cạnh code, và ?naming=snake chỉ trả về các khóa snake_case. Phiên bản nằm trong đường dẫn, /api/v1: thay đổi phá vỡ tương thích sẽ dùng tiền tố mới, còn trường và cách viết mới chỉ là bổ sung.

Bắt đầu ở sandbox miễn phí, rồi chuyển sang Live

Mọi thứ trên trang này hiện đều chạy được ở sandbox. Khóa sandbox tự tạo được và miễn phí, và không bao giờ chạm vào số dư thật của bạn.

  1. 1

    Tạo tài khoản

    Đăng ký tài khoản FX-Port. Khóa sandbox miễn phí, và các đặt chỗ trên sandbox không phát sinh khoản phí thực nào.

    Tạo tài khoản FX-Port của bạn

  2. 2

    Tạo khóa sandbox

    Tại trang API trong bảng điều khiển, hãy tạo một khóa bắt đầu bằng fxp_test_. Khóa chỉ đọc có thể tìm kiếm và đọc dữ liệu; khóa đọc + ghi còn tạo được các đặt chỗ thử nghiệm.

    Mở trang API trong bảng điều khiển

  3. 3

    Gửi yêu cầu đầu tiên

    Chỉ có một base URL, và khóa được đặt trong header Authorization dưới dạng bearer token. Hướng dẫn bắt đầu nhanh sẽ đưa bạn qua lần gọi đầu tiên.

    Đọc hướng dẫn bắt đầu nhanh về API

  4. 4

    Chuyển sang Live khi bạn sẵn sàng

    Thay bằng khóa fxp_live_. Live hoạt động khi đại lý của bạn được phê duyệt; trước đó API trả về 403 agency_not_active. Các đặt chỗ thực được thanh toán từ số dư đã nạp tiền.

    Đọc cách chuyển sang Live

Yêu cầu danh mục gói đầu tiên bằng cURL. Tài liệu in cùng yêu cầu này bằng mọi ngôn ngữ được hỗ trợ.

Yêu cầu

curl 'https://api.fx-port.com/api/v1/esims/packages?country=france&type=local' \
  -H "Authorization: Bearer fxp_test_YOUR_KEY"

Hướng dẫn bắt đầu nhanh: lệnh sandbox đầu tiên

Sandbox làm gì

Một đơn ở sandbox tạo một eSIM thử thật tại nhà cung cấp, với mã kích hoạt giả, nên không thể cài lên điện thoại. Không có khoản nào bị trừ, và phản hồi nói rõ điều đó: balanceDebited, transactionCreated và payoutCreated đều là false. Lệnh nạp thêm trả về số dư bằng không. Dung lượng đã dùng là cố định: eSIM mới hiển thị đủ hạn mức và trạng thái ACTIVE. Đơn đặt ở sandbox chỉ khóa sandbox mới thấy.

eSIM trong sandbox

Chỉ Live mới kiểm thử được gì

Kiểm tra số dư, kiểm tra trùng lặp và khóa số dư chỉ chạy trên Live. Vì vậy các phản hồi 402 với insufficient_balance, 409 cho cùng gói được đặt lại trong vòng 60 giây, và 503 với balance_lock_timeout không bao giờ xuất hiện ở sandbox. Hãy viết cách xử lý chúng dựa trên danh sách mã lỗi.

Danh sách đầy đủ mã lỗi

Chuyển sang Live

Khóa Live gắn với việc duyệt đại lý: cho đến khi đại lý của bạn được duyệt, khóa Live trả agency_not_active và khóa sandbox vẫn hoạt động. Đơn Live được thanh toán từ số dư đại lý đã nạp tiền. Chuyển sang Live chỉ đổi khóa, không đổi mã, vì sandbox và Live dùng chung một Base URL.

Khóa Live cần được duyệt

Ai xây dựng trên API eSIM

Mỗi nhóm khách hàng dựa vào một phần khác nhau của cùng các lệnh gọi.

Đại lý bán chuyến đi

Đại lý bán eSIM bên cạnh chuyến bay và khách sạn. Họ đặt bằng chính địa chỉ email của du khách, để nhà cung cấp gửi mã QR và liên kết chia sẻ, và đọc dung lượng đã dùng khi du khách hỏi. Tỷ lệ hoa hồng được trả về cùng mỗi gói, và agent_id ghi lại người dùng nào của đại lý bạn đã đặt đơn.

OTA và sàn giao dịch

Sàn giao dịch dựng trang duyệt gói trước: từng quốc gia một, gói nội địa hoặc khu vực, nhà mạng và hạn mức dữ liệu của từng gói, cùng bước kiểm tra thiết bị trước khi du khách mua. Một màn hình liệt kê các eSIM của du khách có thể đọc dung lượng đã dùng của tối đa 50 eSIM trong một lần gọi.

Đội công nghệ du lịch và doanh nghiệp

Đội công nghệ du lịch và bộ phận du lịch công tác của doanh nghiệp tự xây công cụ đặt chỗ. Mọi thứ cần để bắt đầu đều công khai: tệp OpenAPI, bộ sưu tập Postman và tài liệu văn bản thuần mà trợ lý lập trình AI đọc được, nên nguyên mẫu đầu tiên xuất phát từ hợp đồng thật.

API eSIM: câu hỏi thường gặp

API eSIM của FX-Port là gì và dành cho ai?

Đây là một REST API giúp đại lý du lịch, OTA hoặc đơn vị bán lại bán eSIM dữ liệu du lịch từ một lần tích hợp. Bạn liệt kê các gói của một điểm đến với giá theo tiền tệ của đại lý và đặt một gói cho du khách. Bạn gửi mã QR cho du khách, theo dõi dung lượng đã dùng và nạp thêm dữ liệu. Mọi thứ là JSON qua HTTPS, và một tệp OpenAPI mô tả từng endpoint.

Có sandbox miễn phí không, và lấy khóa bằng cách nào?

Có. Hãy tạo tài khoản FX-Port, mở trang API trong bảng điều khiển và tạo khóa sandbox; bạn tự làm được, không mất phí. Một đơn ở sandbox tạo eSIM thử với mã kích hoạt giả, nên không thể cài lên điện thoại. Không có khoản nào bị trừ khỏi số dư của bạn. Sandbox và Live dùng chung một Base URL, nên mã bạn thử nghiệm cũng là mã bạn đưa vào vận hành.

Chuyển sang Live cần những gì?

Đại lý của bạn phải được duyệt thì khóa Live mới hoạt động. Cho đến lúc đó, khóa Live bị từ chối và khóa sandbox vẫn dùng được. Đơn Live được thanh toán từ số dư đại lý đã nạp tiền, điều mà sandbox không bao giờ chạm tới, và mọi khóa đều có thể giới hạn theo danh sách địa chỉ IP. Chuyển đổi chỉ là đổi khóa; mỗi phản hồi đều nêu môi trường nó đến từ.

Tôi có thể bán gói của những quốc gia nào?

Có gói cho 190+ quốc gia, và các gói khu vực nằm dưới khu vực của chúng. Các gói khác nhau về hạn mức dữ liệu, thời hạn, nhà mạng và khả năng nạp thêm. Hãy đọc các trường này và mã gói từ phản hồi danh mục thay vì viết cứng. Hãy hỏi từng quốc gia một, vì toàn bộ danh mục là một phản hồi rất lớn. Một danh sách thiết bị riêng cho phép kiểm tra điện thoại của du khách trước khi bán.

Du khách nhận eSIM bằng cách nào?

Phản hồi của đơn chứa mã QR, chuỗi kích hoạt của mã đó, liên kết cài đặt cho iPhone và một trang chia sẻ. Bạn có thể hiển thị chúng trên màn hình của mình. FX-Port cũng yêu cầu nhà cung cấp gửi email kèm mã QR và liên kết chia sẻ tới địa chỉ của du khách ngay khi eSIM được tạo. Nếu nhà cung cấp chưa trả eSIM, đơn vẫn tồn tại và dữ liệu có thể lấy sau từ lệnh gọi dữ liệu cài đặt.

Giá, hoa hồng và số dư của tôi liên hệ với nhau thế nào?

Mỗi gói đi kèm các trường về tiền sau, tính theo tiền tệ của đại lý: giá gốc trước hoa hồng, giá tổng thu của du khách, số tiền trừ khỏi số dư và tỷ lệ hoa hồng của bạn. Hoa hồng của bạn bằng giá tổng trừ đi số tiền bị trừ. Hãy đọc các trường này thay vì tự dựng lại, vì số tiền trừ là riêng của đại lý bạn. Ở sandbox không có khoản nào bị trừ; trên Live, khoản trừ rời khỏi số dư đại lý.

Tôi có nạp thêm cho eSIM được không, và xem phần còn lại bằng cách nào?

Được, bằng hai lệnh gọi: liệt kê các gói có thể thêm vào đúng eSIM đó, rồi tạo lệnh nạp thêm bằng một trong các gói. Không phải lúc nào cũng nạp thêm được, vì nhà cung cấp có thể đổi nhà mạng của một quốc gia. Khi đó danh sách trống nghĩa là du khách cần một eSIM mới. Dung lượng đã dùng được lưu đệm tối đa 15 phút, nên hãy xem đó là số liệu gần đây, và một lệnh gọi đọc được tối đa 50 eSIM.

Lỗi được báo cáo thế nào, và có webhook không?

Lỗi được trả về trong một định dạng với mã lỗi ổn định, và chương trình của bạn nên kiểm tra mã đó, không phải nội dung thông điệp. Lệnh đọc lặp lại an toàn với backoff. Tạo đơn hoặc lệnh nạp thêm thì khác: không có khóa idempotency, nên sau khi hết thời gian chờ hãy tra đơn đặt trước khi thử lại. FX-Port chỉ từ chối một đơn trùng lặp hiển nhiên, chẳng hạn cùng gói đặt hai lần trong vòng 60 giây trên Live. Không có webhook.

Tôi có thể hủy hoặc hoàn tiền một đơn eSIM qua API không?

Không. API không có endpoint để hủy hoặc hoàn tiền một đơn eSIM. Mỗi đơn tạo đúng một eSIM, vì vậy hãy kiểm tra gói và thông tin du khách trước khi gửi. Nếu nhà cung cấp từ chối đơn, không có khoản nào bị trừ và một đơn thất bại được lưu lại. Với sự cố của một đơn cụ thể, hãy viết cho đội phát triển và nêu mã đơn.

Tôi cần gì để bắt đầu, và công cụ nào hỗ trợ?

Bạn cần một khóa sandbox và một HTTP client. Tài liệu bổ sung tệp OpenAPI 3.1, bộ sưu tập Postman, mã mẫu bằng 9 ngôn ngữ và bản xuất văn bản thuần cho trợ lý AI. Hãy giữ khóa trên máy chủ của bạn, không để trong trình duyệt hay ứng dụng. Phần tốn thời gian hơn là quy trình thanh toán của riêng bạn, việc gửi mã QR cho du khách và xử lý lỗi.

Các API khác của FX-Port

Một eSIM thường đi cùng một chuyến đi. Chuyến bay và khách sạn dùng cùng khóa, cùng nội dung lỗi và cùng quy ước như eSIM, và đơn đặt của chúng nằm trong cùng lịch sử tài khoản.

  • API chuyến bay

    Tìm kiếm, định giá và đặt vé máy bay, thanh toán đơn đang giữ, hủy và đọc vé.

  • API khách sạn

    Tìm khách sạn, kiểm tra giá phòng, đặt trước và đặt phòng, đọc voucher và hủy.

  • API đưa đón sân bayXem trước

    Báo giá, đặt, theo dõi và hủy các chuyến đưa đón sân bay.

Không muốn viết mã? Đại lý cũng có thể bán eSIM ngay từ bảng điều khiển FX-Port. Bán eSIM từ bảng điều khiển

Chạy đơn eSIM đầu tiên của bạn ở sandbox

Hãy tạo tài khoản, tạo khóa sandbox, liệt kê gói, tạo đơn và đọc dung lượng đã dùng ngay hôm nay. Khóa Live sẽ có sau khi đại lý của bạn được duyệt.

Tạo tài khoản của bạnGửi email cho đội phát triển

Hỏi trợ lý AI về API này

Mở trang này trong một trợ lý AI và nhờ lập kế hoạch tích hợp từng bước.

FX-PORT

Nền tảng phân phối du lịch B2B đáng tin cậy của bạn. Truy cập kho dự trữ toàn cầu và phát triển doanh nghiệp của bạn với giá cả tốt hơn và các công cụ dễ sử dụng.

  • Điều khoản
  • Quyền riêng tư
  • Liên hệ với chúng tôi
  • Doanh nghiệp
  • Blog
  • API Chuyến Bay B2B
  • API Đưa Đón B2B
  • API Phà B2B
  • API Khách Sạn B2B
  • B2B eSIM API
  • Bed Bank B2B
  • Nhà Cung Cấp Chuyến Bay B2B
  • Hãng Hàng Không
  • Sân Bay
  • Quốc Gia
  • eSIM

Dịch vụ chuyến bay

FX-Port là nền tảng phân phối chuyến bay B2B toàn diện cho phép đại lý du lịch truy cập và bán vé máy bay trên toàn thế giới. Với kết nối với hơn 500 hãng hàng không, đại lý có thể cung cấp giá sỉ cạnh tranh với xác nhận ngay lập tức và quy trình đặt vé tự động.

Nền tảng của chúng tôi cung cấp khả năng có sẵn trong thời gian thực, công cụ so sánh giá và quản lý đặt chỗ tự động. Đại lý du lịch có thể truy cập các giá vé máy bay B2B độc quyền, quản lý hoa hồng và tối ưu hóa hoạt động chuyến bay thông qua hệ thống tích hợp của chúng tôi.

Dịch vụ lưu trú

Truy cập mạng lưới rộng lớn của chúng tôi với hơn 1,5 triệu tài sản trên toàn thế giới thông qua nền tảng đặt khách sạn B2B của chúng tôi. Đại lý du lịch có thể cung cấp giá cạnh tranh với lợi nhuận đảm bảo và xác nhận phòng ngay lập tức trên tất cả các danh mục chỗ ở.

Từ các khu nghỉ dưỡng sang trọng đến các tùy chọn tiết kiệm, nền tảng của chúng tôi cung cấp thông tin chi tiết về tài sản, giá cả linh hoạt và quản lý đặt chỗ tự động cho phân phối khách sạn mượt mà.

Giải pháp du lịch

Dịch vụ chuyển đổi toàn diện với mạng lưới toàn cầu các nhà cung cấp đã xác minh, cung cấp dịch vụ chuyển sân bay, tham quan thành phố và dịch vụ lái xe chuyên nghiệp. Hệ thống đặt vé phà của chúng tôi kết nối các tuyến đường hàng hải chính với khả năng đặt chỗ ngay lập tức và giá B2B cạnh tranh.

Các gói Umrah chuyên biệt với dịch vụ từ đầu đến cuối bao gồm xử lý thị thực, lưu trú và vận tải. Các gói du lịch tùy chỉnh với giá cả linh hoạt và quản lý kho dự trữ tự động cho đại lý du lịch.

FX-Port cách mạng hóa phân phối du lịch B2B với công nghệ tiên tiến và các giải pháp toàn diện. Nền tảng của chúng tôi cho phép đại lý du lịch truy cập kho dự trữ toàn cầu, quản lý đặt chỗ hiệu quả và phát triển doanh nghiệp với giá cả cạnh tranh và các công cụ tự động.

Với hỗ trợ cho nhiều loại tiền tệ, xử lý thanh toán địa phương và dịch vụ khách hàng 24/7, chúng tôi đảm bảo hoạt động mượt mà cho đại lý du lịch trên toàn thế giới. Nền tảng của chúng tôi có các tính năng khả năng có sẵn trong thời gian thực, xác nhận ngay lập tức và các công cụ quản lý đặt chỗ toàn diện.

Đại lý du lịch có thể sử dụng nền tảng của chúng tôi để cung cấp toàn bộ loạt các dịch vụ du lịch, bao gồm đặt chỗ chuyến bay, đặt khách sạn, dịch vụ chuyển đổi, vé phà, các gói Umrah và các trải nghiệm du lịch tùy chỉnh. Chợ B2B của chúng tôi kết nối đại lý với các nhà cung cấp đã xác minh trên toàn thế giới.

FX-Port cung cấp bảo mật cấp doanh nghiệp, quản lý hoa hồng tự động và phân tích chi tiết cho sự phát triển doanh nghiệp. Tham gia cùng hàng trăm đại lý thành công đang sử dụng nền tảng của chúng tôi để tối ưu hóa hoạt động và mở rộng sự hiện diện thị trường của họ.

© 2026 FX-PORT. Tất cả các quyền được bảo lưu.

Chuyển đến nội dung
FX-Port cho nhà cung cấpVé máy bay—Hãng hàng không·Đơn vị gom vé·OTA·Đại lý GDSKhách sạn—Bed bank·PMS/CMS·Khách sạnTất cả nhà cung cấp du lịch
Doanh nghiệpAPI
Đăng Nhập
Truy cập ngay bây giờ
Bảng điều khiển