1. Получить все устройства
Возвращает полный список всех модемов на сервере с их текущим статусом.
GET /apix/show_status_json
2. Получить свободные устройства с учетом Dedicated/Shared логики
Возвращает список свободных устройств. Для Dedicated/Mix: устройство свободно если нет портов или все порты просрочены. Для Shared: устройство свободно если активных портов меньше 5.
GET /apix/show_status_json +
GET /apix/list_ports_json
3. Получить занятые устройства с учетом Dedicated/Shared логики
Возвращает список занятых устройств согласно логике типа сервера.
GET /apix/show_status_json +
GET /apix/list_ports_json
4. Создать порт с автогенерацией credentials и на выбор OS Fingerprint
Создает новый порт на выбранном устройстве. Автоматически генерирует уникальные логин, пароль и назначает свободные порты.
POST /crud/store_port +
GET /apix/apply_port?arg={portID}
5. Получить proxy, OpenVPN, reset link
Получает полные данные доступа для существующего порта.
GET /apix/list_ports_json +
GET /get_vpn_profile/{portID}.ovpn
6. Изменить OS Fingerprint без изменения других параметров
Обновляет только OS fingerprint для активного порта, сохраняя все остальные настройки.
POST /crud/store_port +
GET /apix/apply_port?arg={portID}
7. Продлить порт с опциональной ротацией устройства
Продлевает срок действия порта. При включенной ротации переносит порт на свободное устройство.
POST /crud/store_port +
GET /apix/apply_port?arg={portID}
8. Удалить порт конкретный или все просроченные
Удаляет указанный порт или все порты с истекшим сроком действия.
GET /apix/purge_port?arg={portID}
9. Получить все активные порты с кредами и ссылками
Возвращает список всех активных портов (с датой окончания больше текущей) включая данные доступа.
GET /apix/list_ports_json
10. Перезагрузка устройства которое принадлежит порту
Перезагружает устройство. Устройство определяется через порт автоматически.
GET /apix/reboot_modem_by_imei?IMEI={IMEI}
11. Включение автоматической ротации IP адреса на устройстве
Включает автоматическую смену IP через заданный интервал. Устройство определяется через порт.
POST /crud/store_modem +
POST /modem/settings
12. Получить статистику сервера
Собирает статистику на основе данных устройств и портов согласно описанной логике.
GET /apix/show_status_json +
GET /apix/list_ports_json
13. Перенос порта на другое устройство
Переносит порт на другое устройство путем пересоздания.
POST /crud/store_port +
GET /apix/apply_port?arg={portID}
Архитектура решения
Proxysmart - это система управления мобильными прокси-серверами, построенная на физических устройствах с SIM-картами различных операторов.
Структура системы
Глоссарий терминов
Локация
Географическое расположение серверного оборудования.
- USA, New York
- USA, Los Angeles
- USA, Chicago
Оператор
Мобильный оператор, предоставляющий SIM-карты.
- Verizon
- AT&T
- T-Mobile
- Sprint
Сервер
Физический сервер расположенный в локации с выделенным оптоволоконным каналом фул дуплекс не менее 1 гигабита/с, к которому подключаются устройства с сим-картами. В одной локации может быть несколько серверов, у каждого будет уникальный статический IP адрес для интеграции.
- New York + Verizon = "US-NY-Verizon"
- Chicago + (AT&T + T-Mobile) = "US-Chicago-Mix"
Типы серверов
Dedicated сервер
Одно устройство - один порт. Доступен только один оператор.
Максимальное количество портов на устройство: 1
Shared сервер
Одно устройство - до 5 портов. Доступен только один оператор.
Максимальное количество портов на устройство: 5
Mix сервер
То же что Dedicated, но могут быть разные операторы (Verizon, T-Mobile, AT&T).
Максимальное количество портов на устройство: 1
Устройство
Физическое оборудование: модем, роутер, телефон.
- Модем: MC8010CA, E3372, MR6400
- Роутер: DW5811e, USB модемы
- Телефон: Android устройства
- IMEI: 15 цифр (например: 353990074165890)
- Nickname: Произвольное имя (например: dongle_101)
Порт
Виртуальная точка доступа для клиента.
Включает: HTTP proxy, SOCKS5 proxy, OpenVPN.
Порты: HTTP (8100-8999), SOCKS (5100-5999)
IMEI
International Mobile Equipment Identity - уникальный 15-значный идентификатор устройства.
Пример: 353990074165890
Proxy
Промежуточный сервер для маршрутизации интернет-трафика через мобильное устройство.
VPN (OpenVPN)
Virtual Private Network - зашифрованное соединение через мобильное устройство.
OS Fingerprint
Эмуляция отпечатка операционной системы для обхода детекции, может быть добавлен новый по запросу.
Ротация IP
Процесс смены IP адреса путем переподключения к сети оператора.
- Смена через защищенную ссылку, которая генерируется для порта
- Автоматическая по таймеру
- По API запросу через IMEI
Важные заметки
- Device replacement: Устройство может поменяться по ряду причин (поломка, профилактика, ротация)
- Api speed: API достаточно медленный, подумайте над тем чтобы ожидать завершения или разрывать сеанс
- Device ownership: Всегда проверяйте принадлежность устройства перед операциями
-
Ограничения скорости:
- Не меняйте IP чаще чем раз в минуту
- Не перегружайте устройство чаще чем раз в час
- Port rotation: При продлении порта желательно ротировать устройство на свободное
Быстрый старт
Этот интерфейс предназначен для тестирования интеграции с Proxysmart API. Все операции выполняются на тестовом сервере http://96.253.78.35:8080/ с учетными данными proxy:proxy.
Основной процесс работы:
- Получите список свободных устройств
- Создайте порт на свободном устройстве
- Получите данные доступа (HTTP proxy, SOCKS5 proxy, OpenVPN)
- При необходимости измените OS fingerprint
- При необходимости продлите порт
- При необходимости перенесите порт на другое устройство
- При необходимости перезагрузите устройство которое принадлежит порту
- Удалите порт после использования
Получить все устройства
Возвращает полный список всех устройств (модемов) на сервере с их текущим статусом, сетевыми параметрами и характеристиками.
Выполняет запрос к эндпоинту /apix/show_status_json и возвращает массив всех устройств. Каждое устройство содержит информацию о модеме (IMEI, модель, никнейм) и сетевые данные (IP, оператор, статус подключения).
Пример кода:
// Get all devices
$api = new ProxysmartAPI();
$devices = $api->getAllDevices();
// Process each device
foreach ($devices as $device) {
echo "IMEI: " . $device['modem_details']['IMEI'] . "\n";
echo "Nickname: " . $device['modem_details']['NICK'] . "\n";
echo "Model: " . $device['modem_details']['MODEL'] . "\n";
echo "Status: " . $device['net_details']['IS_ONLINE'] . "\n";
echo "External IP: " . $device['net_details']['EXT_IP'] . "\n";
echo "Operator: " . $device['net_details']['CELLOP'] . "\n\n";
}
Пример ответа:
[
{
"N": 1,
"IS_LOCKED": "false",
"modem_details": {
"IMEI": "867428050495154",
"NICK": "modem_02",
"MODEL": "MC8010CA",
"MODEL_SHOWN": "MC8010CA",
"UPTIME": "unknown",
"PHONE_NUMBER": "",
"AT_PORT": "/dev/ttyUSB2",
"ADDED_TIME": "57 minutes",
"REBOOT_SCORE": "0"
},
"net_details": {
"DEV": "lanmodem2",
"GW": "192.168.50.1",
"LOCAL_IP": "192.168.50.250",
"LOCAL_IP6": "",
"EXT_IP": "172.56.223.238",
"EXT_IPV6": "2607:fb91:e35:933b::95:53",
"IS_ONLINE": "yes",
"CurrentNetworkType": "5G",
"SimStatus": "SIM OK",
"ICCID": "8901260400728839802",
"ConnectionStatus": "OK, ipv4_ipv6_connected",
"SIGNAL_STRENGTH": "5",
"CELLOP": "T-Mobile",
"BAND": "66",
"APN": "fast.t-mobile.com"
},
"proxy_creds": {
"HTTP_PORT": 30202,
"SOCKS_PORT": null,
"LOGIN": "def294246",
"PASS": "def294246"
}
}
]
Получить свободные устройства
Возвращает список свободных устройств с учетом типа сервера (Dedicated/Shared/Mix).
Получает все устройства и порты, затем фильтрует по логике типа сервера. Для Dedicated/Mix: устройство свободно если нет портов или все порты просрочены. Для Shared: устройство свободно если активных портов меньше 5.
Пример кода:
// Get free devices based on server type logic
$api = new ProxysmartAPI();
$freeDevices = $api->getFreeDevices();
echo "Found " . count($freeDevices) . " free devices\n\n";
foreach ($freeDevices as $device) {
echo "IMEI: " . $device['modem_details']['IMEI'] . "\n";
echo "Model: " . $device['modem_details']['MODEL'] . "\n";
echo "Online: " . $device['net_details']['IS_ONLINE'] . "\n";
echo "IP: " . $device['net_details']['EXT_IP'] . "\n\n";
}
Пример ответа:
// Response is array of devices that are free according to server type logic
[
{
"modem_details": {
"IMEI": "353990074165890",
"NICK": "sierra",
"MODEL": "DW5811e"
},
"net_details": {
"IS_ONLINE": "yes",
"EXT_IP": "178.163.151.102",
"CELLOP": "A1 BY"
}
}
]
Получить занятые устройства
Возвращает список занятых устройств с учетом типа сервера.
Получает все устройства и вычитает из них свободные. Устройство считается занятым если на нем есть активные порты согласно логике типа сервера.
Пример кода:
// Get busy devices
$api = new ProxysmartAPI();
$busyDevices = $api->getBusyDevices();
echo "Found " . count($busyDevices) . " busy devices\n\n";
// Show busy devices with their active ports
$ports = $api->getActivePorts();
foreach ($busyDevices as $device) {
$imei = $device['modem_details']['IMEI'];
$devicePorts = array_filter($ports, function($p) use ($imei) {
return $p['imei'] === $imei;
});
echo "IMEI: " . $imei . "\n";
echo "Active ports: " . count($devicePorts) . "\n\n";
}
Пример ответа:
// Response is array of busy devices (same structure as getAllDevices)
Создать порт
Создает новый порт на указанном устройстве с автоматической генерацией учетных данных.
Генерирует уникальный portID, логин, пароль, назначает свободные HTTP и SOCKS порты. Сохраняет порт через /crud/store_port, затем применяет настройки через /apix/apply_port.
Пример кода:
// Create new port on device
$api = new ProxysmartAPI();
// Get first free device
$freeDevices = $api->getFreeDevices();
if (empty($freeDevices)) {
die("No free devices available\n");
}
$imei = $freeDevices[0]['modem_details']['IMEI'];
$portName = "ClientPort_" . date('Ymd');
$expiryDate = date('Y-m-d\TH:i', strtotime('+30 days')); // 30 days validity
$osFingerprint = 'android:3'; // Optional OS fingerprint
// Create port
$result = $api->createPort($imei, $portName, $expiryDate, $osFingerprint);
if ($result['success']) {
echo "Port created successfully!\n";
echo "Port ID: " . $result['portID'] . "\n";
echo "Login: " . $result['credentials']['login'] . "\n";
echo "Password: " . $result['credentials']['password'] . "\n";
echo "HTTP Proxy: " . $result['credentials']['http_proxy'] . "\n";
echo "SOCKS5 Proxy: " . $result['credentials']['socks_proxy'] . "\n";
} else {
echo "Error: " . $result['error'] . "\n";
}
Пример ответа:
{
"success": true,
"portID": "portABC1234567890",
"credentials": {
"login": "user12345",
"password": "pass67890abc",
"http_port": 8543,
"socks_port": 5543,
"http_proxy": "http://user12345:pass67890abc@96.253.78.35:8543",
"socks_proxy": "socks5://user12345:pass67890abc@96.253.78.35:5543"
}
}
Получить данные доступа
Получает полные данные доступа для существующего порта.
Ищет порт по portID в списке всех портов через /apix/list_ports_json. Возвращает прокси credentials, ссылку для смены IP и ссылку на скачивание OpenVPN конфига.
Пример кода:
// Get port access details
$api = new ProxysmartAPI();
$portId = 'portABC1234567890';
$details = $api->getPortDetails($portId);
if ($details['success']) {
echo "Port found on device: " . $details['imei'] . "\n";
echo "HTTP Proxy: " . $details['http_proxy'] . "\n";
echo "SOCKS5 Proxy: " . $details['socks_proxy'] . "\n";
echo "Reset IP Link: " . $details['reset_link'] . "\n";
echo "Link valid until: " . $details['reset_valid_until'] . "\n";
echo "OpenVPN download: " . $details['vpn_link'] . "\n";
// Download OpenVPN config file
$vpnConfig = file_get_contents($details['vpn_link'], false, stream_context_create([
'http' => ['header' => 'Authorization: Basic ' . base64_encode('proxy:proxy')]
]));
file_put_contents($portId . '.ovpn', $vpnConfig);
echo "OpenVPN config saved to " . $portId . ".ovpn\n";
} else {
echo "Error: " . $details['error'] . "\n";
}
Пример ответа:
{
"success": true,
"port": {
"portID": "portABC1234567890",
"portName": "ClientPort_20231225",
"LOGIN": "user12345",
"PASSWORD": "pass67890abc",
"HTTP_PORT": "8543",
"SOCKS_PORT": "5543",
"PROXY_VALID_BEFORE": "2024-01-25T15:30",
"RESET_SECURE_LINK": {
"URL": "http://96.253.78.35:8080/apix/reset_ip_secure?hash=KNQWY5DFMR...",
"VALID_UNTIL": "2024-01-25@15:30:00 +03"
}
},
"http_proxy": "http://user12345:pass67890abc@96.253.78.35:8543",
"socks_proxy": "socks5://user12345:pass67890abc@96.253.78.35:5543",
"reset_link": "http://96.253.78.35:8080/apix/reset_ip_secure?hash=KNQWY5DFMR...",
"reset_valid_until": "2024-01-25@15:30:00 +03",
"vpn_link": "http://96.253.78.35:8080/get_vpn_profile/portABC1234567890.ovpn",
"imei": "867428050495154"
}
Изменить OS Fingerprint
Изменяет OS fingerprint для активного порта без изменения других параметров.
Получает текущие данные порта, сохраняет все параметры кроме OS, обновляет только OS fingerprint через /crud/store_port и применяет изменения.
Пример кода:
// Change OS fingerprint for existing port
$api = new ProxysmartAPI();
$portId = 'portABC1234567890';
// Change to Windows 10
$result = $api->changeOSFingerprint($portId, 'windows:1');
if ($result['success']) {
echo "OS Fingerprint changed successfully to Windows 10\n";
} else {
echo "Error: " . $result['error'] . "\n";
}
// Remove OS fingerprint (no spoofing)
$result = $api->changeOSFingerprint($portId, '');
if ($result['success']) {
echo "OS Fingerprint removed\n";
}
Пример ответа:
{
"success": true,
"message": "OS fingerprint updated"
}
Продлить порт
Продлевает срок действия порта с опциональной ротацией на новое устройство.
При ротации ищет свободное устройство. Создает порт заново с теми же credentials на новом устройстве через POST /crud/store_port, затем применяет изменения.
Пример кода:
// Extend port validity
$api = new ProxysmartAPI();
$portId = 'portABC1234567890';
$newExpiryDate = date('Y-m-d\TH:i', strtotime('+30 days')); // Extend for 30 more days
$rotateDevice = true; // Rotate to new device if available
$result = $api->extendPort($portId, $newExpiryDate, $rotateDevice);
if ($result['success']) {
echo $result['message'] . "\n";
if ($result['device_changed']) {
echo "Device changed:\n";
echo "Old IMEI: " . $result['old_imei'] . "\n";
echo "New IMEI: " . $result['new_imei'] . "\n";
} else {
echo "Port extended on the same device\n";
}
} else {
echo "Error: " . $result['error'] . "\n";
}
Пример ответа:
{
"success": true,
"message": "Port moved from 867428050495154 to 353990074165890",
"device_changed": true,
"new_imei": "353990074165890",
"old_imei": "867428050495154"
}
Удалить порты
Удаляет конкретный порт или все просроченные порты.
Для удаления просроченных: проходит по всем портам и удаляет те, у которых PROXY_VALID_BEFORE меньше текущего времени. Использует /apix/purge_port для каждого порта.
Пример кода:
// Delete specific port
$api = new ProxysmartAPI();
$result = $api->deletePorts('portABC1234567890');
echo "Deleted ports: " . $result['deleted_count'] . "\n";
// Delete all expired ports
$result = $api->deletePorts('expired');
echo "Deleted expired ports: " . $result['deleted_count'] . "\n";
if ($result['deleted_count'] > 0) {
echo "Deleted port IDs:\n";
foreach ($result['deleted_ports'] as $portId) {
echo "- " . $portId . "\n";
}
}
Пример ответа:
{
"success": true,
"deleted_count": 3,
"deleted_ports": ["port123old", "port456old", "port789old"]
}
Получить активные порты
Возвращает список всех активных (не просроченных) портов с полными данными доступа.
Получает все порты через /apix/list_ports_json, фильтрует по дате окончания (больше текущей). Возвращает только порты с установленной датой окончания.
Пример кода:
// Get all active ports with full details
$api = new ProxysmartAPI();
$activePorts = $api->getActivePorts();
echo "Total active ports: " . count($activePorts) . "\n\n";
foreach ($activePorts as $port) {
// Calculate remaining time
$remainingTime = $port['expires_in_seconds'];
$days = floor($remainingTime / 86400);
$hours = floor(($remainingTime % 86400) / 3600);
$minutes = floor(($remainingTime % 3600) / 60);
echo "Port ID: " . $port['portID'] . "\n";
echo "Name: " . $port['portName'] . "\n";
echo "Device IMEI: " . $port['imei'] . "\n";
echo "HTTP Proxy: " . $port['http_creds'] . "\n";
echo "SOCKS5 Proxy: " . $port['socks5_creds'] . "\n";
echo "Expires: " . $port['PROXY_VALID_BEFORE'] . "\n";
echo "Remaining: {$days}d {$hours}h {$minutes}m\n";
echo "Reset IP: " . $port['RESET_SECURE_LINK']['URL'] . "\n";
echo "OS: " . ($port['OS'] ?? 'none') . "\n";
echo str_repeat('-', 50) . "\n";
}
Пример ответа:
[
{
"portID": "portABC1234567890",
"portName": "ClientPort_20231225",
"LOGIN": "user12345",
"PASSWORD": "pass67890abc",
"HTTP_PORT": "8543",
"SOCKS_PORT": "5543",
"http_creds": "http://user12345:pass67890abc@96.253.78.35:8543",
"socks5_creds": "socks5://user12345:pass67890abc@96.253.78.35:5543",
"PROXY_VALID_BEFORE": "2024-01-25T15:30",
"imei": "867428050495154",
"expires_in_seconds": 2592000,
"OS": "android:3",
"RESET_SECURE_LINK": {
"URL": "http://96.253.78.35:8080/apix/reset_ip_secure?hash=KNQWY5DF...",
"VALID_UNTIL": "2024-01-25@15:30:00 +03"
}
}
]
Перезагрузка устройства
Перезагружает устройство, на котором находится указанный порт.
ВАЖНО: сначала определяет IMEI устройства через порт (так как устройство может быть заменено). Затем выполняет перезагрузку через /apix/reboot_modem_by_imei.
Пример кода:
// Reboot device through port
$api = new ProxysmartAPI();
$portId = 'portABC1234567890';
// IMPORTANT: Always get current device through port!
// Device may be replaced by admin at any time
$result = $api->rebootDeviceByPort($portId);
if ($result['success']) {
echo "Device is rebooting...\n";
echo "Device IMEI: " . $result['imei'] . "\n";
if (isset($result['data']['ext_ip'])) {
echo "New IP: " . $result['data']['ext_ip'] . "\n";
echo "Message: " . $result['data']['message'] . "\n";
}
echo "Note: Reboot process takes 1-2 minutes\n";
} else {
echo "Error: " . $result['data']['message'] . "\n";
}
// WRONG WAY - DO NOT do this:
// $api->rebootDeviceByImei('867428050495154'); // Device could be changed!
Пример ответа:
{
"success": true,
"data": {
"result": "success",
"message": "external ip changed from 172.56.223.238 to 172.56.223.241",
"ext_ip": "172.56.223.241",
"debug": "..."
},
"imei": "867428050495154"
}
Автоматическая ротация IP
Включает автоматическую смену IP адреса через заданный интервал.
Получает устройство через порт, затем получает NICK устройства через /apix/show_single_status_json, сохраняет настройки модема с параметром AUTO_IP_ROTATION через /crud/store_modem. ВАЖНО: IMEI и name обязательны и не должны меняться!
Пример кода:
// Enable automatic IP rotation
$api = new ProxysmartAPI();
$portId = 'portABC1234567890';
$intervalMinutes = 60; // Rotate IP every hour
$result = $api->enableAutoRotation($portId, $intervalMinutes);
if ($result['success']) {
echo $result['message'] . "\n";
echo "Device IMEI: " . $result['imei'] . "\n";
echo "Device nickname: " . $result['nick'] . "\n";
echo "Note: IP will change automatically every " . $intervalMinutes . " minutes\n";
} else {
echo "Error: " . $result['error'] . "\n";
}
// IMPORTANT notes:
// 1. Do not rotate more than once per minute
// 2. IMEI and name fields are mandatory and must not be changed
// 3. The modem nickname (NICK) is stored in the "name" field
Пример ответа:
{
"success": true,
"message": "Auto rotation enabled every 60 minutes",
"imei": "867428050495154",
"nick": "modem_02"
}
Статистика сервера
Собирает и возвращает полную статистику по устройствам и портам.
Анализирует данные из /apix/show_status_json и /apix/list_ports_json. Подсчитывает количество устройств (всего/онлайн/оффлайн/доступно), портов (активные/просроченные), группирует по операторам и моделям.
Пример кода:
// Get server statistics
$api = new ProxysmartAPI();
$stats = $api->getServerStatistics();
echo "=== Device Statistics ===\n";
echo "Total devices: " . $stats['device_statistics']['total'] . "\n";
echo "Online: " . $stats['device_statistics']['online'] . "\n";
echo "Offline: " . $stats['device_statistics']['offline'] . "\n";
echo "Available: " . $stats['device_statistics']['available'] . "\n\n";
echo "=== Port Statistics ===\n";
echo "Active ports: " . $stats['port_statistics']['active'] . "\n";
echo "Expired ports: " . $stats['port_statistics']['expired'] . "\n";
echo "Total ports: " . $stats['port_statistics']['total'] . "\n\n";
echo "=== Network Operators ===\n";
foreach ($stats['network_operators'] as $operator => $count) {
echo $operator . ": " . $count . " devices\n";
}
echo "\n=== Device Models ===\n";
foreach ($stats['device_models'] as $model => $count) {
echo $model . ": " . $count . " devices\n";
}
Пример ответа:
{
"device_statistics": {
"total": 50,
"online": 45,
"offline": 5,
"available": 12
},
"port_statistics": {
"active": 120,
"expired": 8,
"total": 128
},
"network_operators": {
"Verizon": 20,
"AT&T": 15,
"T-Mobile": 15
},
"device_models": {
"MC8010CA": 25,
"E3372": 15,
"MR6400": 10
}
}
Перенос порта
Переносит порт на другое устройство с сохранением всех настроек.
Создает порт на новом устройстве с теми же параметрами через POST /crud/store_port, затем применяет изменения.
Пример кода:
// Transfer port to another device
$api = new ProxysmartAPI();
$portId = 'portABC1234567890';
// Get available free devices for transfer
$freeDevices = $api->getFreeDevices();
if (empty($freeDevices)) {
die("No free devices available for transfer\n");
}
// Select first free device
$newImei = $freeDevices[0]['modem_details']['IMEI'];
// Transfer port
$result = $api->transferPort($portId, $newImei);
if ($result['success']) {
echo $result['message'] . "\n";
echo "Old device IMEI: " . $result['old_imei'] . "\n";
echo "New device IMEI: " . $result['new_imei'] . "\n";
echo "Credentials (login/password) remain the same\n";
echo "Port numbers remain the same\n";
} else {
echo "Error: " . $result['error'] . "\n";
}
Пример ответа:
{
"success": true,
"message": "Port transferred from 867428050495154 to 353990074165890",
"old_imei": "867428050495154",
"new_imei": "353990074165890"
}
Полный класс API
<?php
/**
* Proxysmart API Client
* Complete implementation for all API endpoints
*
* @version 1.0.0
* @author JetLink
*/
class ProxysmartAPI {
/**
* @var array Configuration array
*/
private $config;
/**
* @var array Current server configuration
*/
private $serverConfig;
/**
* @var string|null Last error message
*/
private $lastError = null;
/**
* Constructor
*
* @param array|null $config Configuration array or null to load from file
* @throws Exception If configuration is invalid
*/
public function __construct($config = null) {
if ($config === null) {
if (file_exists('config.php')) {
$config = include 'config.php';
} else {
throw new Exception('Configuration file not found');
}
}
if (!isset($config['servers']) || !isset($config['active_server'])) {
throw new Exception('Invalid configuration structure');
}
$this->config = $config;
$this->serverConfig = $config['servers'][$config['active_server']] ?? null;
if (!$this->serverConfig) {
throw new Exception('Active server configuration not found');
}
}
/**
* Make HTTP request to API
*
* @param string $endpoint API endpoint
* @param string $method HTTP method (GET/POST)
* @param mixed $data Request data
* @return array Response data
* @throws Exception On request failure
*/
private function makeRequest($endpoint, $method = 'GET', $data = null) {
$ch = curl_init();
$url = $this->serverConfig['url'] . $endpoint;
// Set basic cURL options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, $this->serverConfig['username'] . ':' . $this->serverConfig['password']);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->config['defaults']['request_timeout'] ?? 30);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// Set method-specific options
if ($method === 'POST') {
curl_setopt($ch, CURLOPT_POST, true);
if ($data !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
}
// Execute request
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
// Handle cURL errors
if ($error) {
$this->lastError = $error;
throw new Exception("cURL Error: " . $error);
}
// Parse response
$decoded = json_decode($response, true);
return [
'success' => $httpCode === 200,
'code' => $httpCode,
'data' => $decoded !== null ? $decoded : $response,
'raw' => $response
];
}
/**
* 1. Get all devices
* Returns complete list of all modems on server
*
* @return array Array of devices
* @throws Exception On API error
*/
public function getAllDevices() {
$result = $this->makeRequest('/apix/show_status_json');
if (!$result['success']) {
throw new Exception('Failed to get devices');
}
return $result['data'] ?? [];
}
/**
* 2. Get free devices
* Returns devices without active ports based on server type logic
*
* @return array Array of free devices
* @throws Exception On API error
*/
public function getFreeDevices() {
$devices = $this->getAllDevices();
$ports = $this->getAllPorts();
$serverType = $this->serverConfig['type'];
$freeDevices = [];
$currentTime = time();
foreach ($devices as $device) {
$imei = $device['modem_details']['IMEI'] ?? '';
if (!$imei) continue;
$devicePorts = isset($ports[$imei]) ? $ports[$imei] : [];
if ($serverType === 'dedicated' || $serverType === 'mix') {
// Dedicated/Mix: free if no ports or all ports expired
$isFree = true;
foreach ($devicePorts as $port) {
if (empty($port['PROXY_VALID_BEFORE'])) {
$isFree = false;
break;
}
$expiryTime = strtotime($port['PROXY_VALID_BEFORE']);
if ($expiryTime > $currentTime) {
$isFree = false;
break;
}
}
} else { // shared
// Shared: free if active ports < max_ports_per_device
$activePortsCount = 0;
foreach ($devicePorts as $port) {
if (empty($port['PROXY_VALID_BEFORE'])) {
$activePortsCount++;
} else {
$expiryTime = strtotime($port['PROXY_VALID_BEFORE']);
if ($expiryTime > $currentTime) {
$activePortsCount++;
}
}
}
$maxPorts = $this->serverConfig['max_ports_per_device'] ?? 5;
$isFree = $activePortsCount < $maxPorts;
}
if ($isFree) {
$freeDevices[] = $device;
}
}
return $freeDevices;
}
/**
* 3. Get busy devices
* Returns devices with active ports
*
* @return array Array of busy devices
* @throws Exception On API error
*/
public function getBusyDevices() {
$devices = $this->getAllDevices();
$freeDevices = $this->getFreeDevices();
$freeImeis = array_column(array_column($freeDevices, 'modem_details'), 'IMEI');
$busyDevices = [];
foreach ($devices as $device) {
$imei = $device['modem_details']['IMEI'] ?? '';
if ($imei && !in_array($imei, $freeImeis)) {
$busyDevices[] = $device;
}
}
return $busyDevices;
}
/**
* 4. Create port
* Creates new port with auto-generated credentials
*
* @param string $imei Device IMEI
* @param string $portName Port name
* @param string|null $expiryDate Expiry date in Y-m-d\TH:i format
* @param string|null $osFingerprint OS fingerprint
* @return array Operation result
* @throws Exception On API error
*/
public function createPort($imei, $portName, $expiryDate = null, $osFingerprint = null) {
// Validate inputs
if (!$imei || !$portName) {
throw new Exception('IMEI and port name are required');
}
// Generate unique credentials
$portId = 'port' . $this->generateRandomString(10);
$login = $this->generateRandomString(8);
$password = $this->generateRandomString(10);
$httpPort = rand(
$this->config['defaults']['http_port_range'][0],
$this->config['defaults']['http_port_range'][1]
);
$socksPort = rand(
$this->config['defaults']['socks_port_range'][0],
$this->config['defaults']['socks_port_range'][1]
);
// Build port data
$portData = [
'IMEI' => $imei,
'portID' => $portId,
'portName' => $portName,
'proxy_login' => $login,
'proxy_password' => $password,
'http_port' => $httpPort,
'socks_port' => $socksPort
];
if ($expiryDate) {
$portData['PROXY_VALID_BEFORE'] = $expiryDate;
}
if ($osFingerprint) {
$portData['OS'] = $osFingerprint;
}
// Create port
$result = $this->makeRequest('/crud/store_port', 'POST',
'data=' . urlencode(json_encode($portData)));
if (!isset($result['data']['result']) || $result['data']['result'] !== 'success') {
return [
'success' => false,
'error' => $result['data']['error'] ?? 'Failed to create port'
];
}
// Apply settings
$this->makeRequest('/apix/apply_port?arg=' . $portId);
return [
'success' => true,
'portID' => $portId,
'credentials' => [
'login' => $login,
'password' => $password,
'http_port' => $httpPort,
'socks_port' => $socksPort,
'http_proxy' => sprintf('http://%s:%s@%s:%d',
$login, $password, $this->getServerHost(), $httpPort),
'socks_proxy' => sprintf('socks5://%s:%s@%s:%d',
$login, $password, $this->getServerHost(), $socksPort)
]
];
}
/**
* 5. Get port details
* Returns complete access data for port
*
* @param string $portId Port ID
* @return array Port details
* @throws Exception On API error
*/
public function getPortDetails($portId) {
$ports = $this->getAllPorts();
foreach ($ports as $imei => $devicePorts) {
foreach ($devicePorts as $port) {
if ($port['portID'] === $portId) {
return [
'success' => true,
'port' => $port,
'http_proxy' => $port['http_creds'] ?? null,
'socks_proxy' => $port['socks5_creds'] ?? null,
'reset_link' => $port['RESET_SECURE_LINK']['URL'] ?? null,
'reset_valid_until' => $port['RESET_SECURE_LINK']['VALID_UNTIL'] ?? null,
'vpn_link' => $this->serverConfig['url'] . "/get_vpn_profile/{$portId}.ovpn",
'imei' => $imei
];
}
}
}
return ['success' => false, 'error' => 'Port not found'];
}
/**
* 6. Change OS fingerprint
* Updates OS fingerprint without changing other parameters
*
* @param string $portId Port ID
* @param string $newOS New OS fingerprint
* @return array Operation result
* @throws Exception On API error
*/
public function changeOSFingerprint($portId, $newOS) {
// Get current port details
$portDetails = $this->getPortDetails($portId);
if (!$portDetails['success']) {
return $portDetails;
}
$port = $portDetails['port'];
$imei = $portDetails['imei'];
// Preserve all existing parameters
$portData = [
'IMEI' => $imei,
'portID' => $portId,
'portName' => $port['portName'],
'proxy_login' => $port['LOGIN'],
'proxy_password' => $port['PASSWORD'],
'http_port' => $port['HTTP_PORT'],
'socks_port' => $port['SOCKS_PORT']
];
// Add new OS if specified
if ($newOS) {
$portData['OS'] = $newOS;
}
// Preserve optional parameters
if (!empty($port['PROXY_VALID_BEFORE'])) {
$portData['PROXY_VALID_BEFORE'] = $port['PROXY_VALID_BEFORE'];
}
// Update port
$result = $this->makeRequest('/crud/store_port', 'POST',
'data=' . urlencode(json_encode($portData)));
if ($result['data']['result'] === 'success') {
$this->makeRequest('/apix/apply_port?arg=' . $portId);
return ['success' => true, 'message' => 'OS fingerprint updated'];
}
return ['success' => false, 'error' => 'Failed to update OS fingerprint'];
}
/**
* 7. Extend port
* Extends port validity with optional device rotation
*
* @param string $portId Port ID
* @param string $newExpiryDate New expiry date
* @param bool $rotateDevice Whether to rotate to new device
* @return array Operation result
* @throws Exception On API error
*/
public function extendPort($portId, $newExpiryDate, $rotateDevice = true) {
// Get current port details
$portDetails = $this->getPortDetails($portId);
if (!$portDetails['success']) {
return $portDetails;
}
$port = $portDetails['port'];
$currentImei = $portDetails['imei'];
$newImei = $currentImei;
// Find new device if rotation requested
if ($rotateDevice) {
$freeDevices = $this->getFreeDevices();
foreach ($freeDevices as $device) {
$deviceImei = $device['modem_details']['IMEI'];
if ($deviceImei !== $currentImei &&
$device['net_details']['IS_ONLINE'] === 'yes') {
$newImei = $deviceImei;
break;
}
}
}
// Recreate port with new parameters
$portData = [
'IMEI' => $newImei,
'portID' => $portId,
'portName' => $port['portName'],
'proxy_login' => $port['LOGIN'],
'proxy_password' => $port['PASSWORD'],
'http_port' => $port['HTTP_PORT'],
'socks_port' => $port['SOCKS_PORT'],
'PROXY_VALID_BEFORE' => $newExpiryDate
];
// Preserve OS if exists
if (isset($port['OS'])) {
$portData['OS'] = $port['OS'];
}
$result = $this->makeRequest('/crud/store_port', 'POST',
'data=' . urlencode(json_encode($portData)));
if ($result['data']['result'] === 'success') {
$this->makeRequest('/apix/apply_port?arg=' . $portId);
return [
'success' => true,
'message' => $newImei !== $currentImei ?
"Port moved from {$currentImei} to {$newImei}" :
"Port extended on the same device",
'device_changed' => $newImei !== $currentImei,
'new_imei' => $newImei,
'old_imei' => $currentImei
];
}
return ['success' => false, 'error' => 'Failed to extend port'];
}
/**
* 8. Delete ports
* Deletes specific port or all expired ports
*
* @param string|array $portIds Port ID(s) or 'expired'
* @return array Operation result
* @throws Exception On API error
*/
public function deletePorts($portIds = 'expired') {
$deletedPorts = [];
if ($portIds === 'expired') {
// Delete all expired ports
$ports = $this->getAllPorts();
$currentTime = time();
foreach ($ports as $imei => $devicePorts) {
foreach ($devicePorts as $port) {
if (!empty($port['PROXY_VALID_BEFORE'])) {
$expiryTime = strtotime($port['PROXY_VALID_BEFORE']);
if ($expiryTime < $currentTime) {
$result = $this->makeRequest('/apix/purge_port?arg=' . $port['portID']);
if ($result['data']['result'] === 'ok') {
$deletedPorts[] = $port['portID'];
}
}
}
}
}
} else {
// Delete specific ports
$portIds = is_array($portIds) ? $portIds : [$portIds];
foreach ($portIds as $portId) {
$result = $this->makeRequest('/apix/purge_port?arg=' . $portId);
if ($result['data']['result'] === 'ok') {
$deletedPorts[] = $portId;
}
}
}
return [
'success' => true,
'deleted_count' => count($deletedPorts),
'deleted_ports' => $deletedPorts
];
}
/**
* 9. Get active ports
* Returns all ports with valid expiry date
*
* @return array Array of active ports
* @throws Exception On API error
*/
public function getActivePorts() {
$ports = $this->getAllPorts();
$activePorts = [];
$currentTime = time();
foreach ($ports as $imei => $devicePorts) {
foreach ($devicePorts as $port) {
// Active = has expiry date and it's in future
if (!empty($port['PROXY_VALID_BEFORE'])) {
$expiryTime = strtotime($port['PROXY_VALID_BEFORE']);
if ($expiryTime > $currentTime) {
$port['imei'] = $imei;
$port['expires_in_seconds'] = $expiryTime - $currentTime;
$activePorts[] = $port;
}
}
}
}
return $activePorts;
}
/**
* 10. Reboot device by port
* Reboots device that hosts the specified port
*
* @param string $portId Port ID
* @return array Operation result
* @throws Exception On API error
*/
public function rebootDeviceByPort($portId) {
// Get device IMEI through port
$portDetails = $this->getPortDetails($portId);
if (!$portDetails['success']) {
return $portDetails;
}
$imei = $portDetails['imei'];
$result = $this->makeRequest('/apix/reboot_modem_by_imei?IMEI=' . $imei);
return [
'success' => isset($result['data']['result']) &&
$result['data']['result'] === 'success',
'data' => $result['data'],
'imei' => $imei
];
}
/**
* 11. Enable automatic IP rotation
* Enables automatic IP address change at specified interval
*
* @param string $portId Port ID
* @param int $intervalMinutes Rotation interval in minutes
* @return array Operation result
* @throws Exception On API error
*/
public function enableAutoRotation($portId, $intervalMinutes) {
// Step 1: Get IMEI through port
$portDetails = $this->getPortDetails($portId);
if (!$portDetails['success']) {
return $portDetails;
}
$imei = $portDetails['imei'];
// Step 2: Get modem details including NICK
$modemResult = $this->makeRequest('/apix/show_single_status_json?arg=' . $imei);
if (!$modemResult['success'] || empty($modemResult['data'])) {
return ['success' => false, 'error' => 'Failed to get modem details'];
}
// API returns object directly, not array
$modemData = $modemResult['data'];
if (!isset($modemData['modem_details']['NICK'])) {
return ['success' => false, 'error' => 'Modem nickname not found'];
}
$modemNick = $modemData['modem_details']['NICK'];
// Step 3: Save modem settings with AUTO_IP_ROTATION
// IMPORTANT: IMEI must be passed as string
// The API now automatically removes previous entries with same IMEI
$modemStoreData = [
'IMEI' => (string)$imei, // Ensure IMEI is string
'name' => $modemNick, // name field = NICK
'AUTO_IP_ROTATION' => intval($intervalMinutes)
];
$result = $this->makeRequest('/crud/store_modem', 'POST',
'data=' . urlencode(json_encode($modemStoreData)));
if ($result['data']['result'] !== 'success') {
return ['success' => false, 'error' => 'Failed to store modem settings'];
}
// Apply settings
$this->makeRequest('/modem/settings', 'POST', 'imei=' . $imei);
return [
'success' => true,
'message' => "Auto rotation enabled every {$intervalMinutes} minutes",
'imei' => $imei,
'nick' => $modemNick
];
}
/**
* 12. Get server statistics
* Returns complete statistics for devices and ports
*
* @return array Statistics data
* @throws Exception On API error
*/
public function getServerStatistics() {
$devices = $this->getAllDevices();
$ports = $this->getAllPorts();
$currentTime = time();
// Device statistics
$totalDevices = count($devices);
$onlineDevices = 0;
$offlineDevices = 0;
$availableDevices = count($this->getFreeDevices());
// Port statistics
$totalPorts = 0;
$activePorts = 0;
$expiredPorts = 0;
// Operators and models
$operators = [];
$models = [];
// Process devices
foreach ($devices as $device) {
// Online/Offline status
if ($device['net_details']['IS_ONLINE'] === 'yes') {
$onlineDevices++;
} else {
$offlineDevices++;
}
// Operators
$operator = $device['net_details']['CELLOP'] ?? 'Unknown';
if (!isset($operators[$operator])) {
$operators[$operator] = 0;
}
$operators[$operator]++;
// Models
$model = $device['modem_details']['MODEL'] ?? 'Unknown';
if (!isset($models[$model])) {
$models[$model] = 0;
}
$models[$model]++;
}
// Process ports
foreach ($ports as $devicePorts) {
foreach ($devicePorts as $port) {
$totalPorts++;
if (!empty($port['PROXY_VALID_BEFORE'])) {
$expiryTime = strtotime($port['PROXY_VALID_BEFORE']);
if ($expiryTime > $currentTime) {
$activePorts++;
} else {
$expiredPorts++;
}
} else {
$activePorts++; // Ports without expiry are considered active
}
}
}
return [
'device_statistics' => [
'total' => $totalDevices,
'online' => $onlineDevices,
'offline' => $offlineDevices,
'available' => $availableDevices
],
'port_statistics' => [
'active' => $activePorts,
'expired' => $expiredPorts,
'total' => $totalPorts
],
'network_operators' => $operators,
'device_models' => $models
];
}
/**
* 13. Transfer port to another device
* Moves port to different device keeping all settings
*
* @param string $portId Port ID
* @param string $newImei New device IMEI
* @return array Operation result
* @throws Exception On API error
*/
public function transferPort($portId, $newImei) {
// Get current port details
$portDetails = $this->getPortDetails($portId);
if (!$portDetails['success']) {
return $portDetails;
}
$port = $portDetails['port'];
$oldImei = $portDetails['imei'];
// Create port on new device
$portData = [
'IMEI' => $newImei,
'portID' => $portId,
'portName' => $port['portName'],
'proxy_login' => $port['LOGIN'],
'proxy_password' => $port['PASSWORD'],
'http_port' => $port['HTTP_PORT'],
'socks_port' => $port['SOCKS_PORT']
];
// Preserve all additional parameters
if (!empty($port['PROXY_VALID_BEFORE'])) {
$portData['PROXY_VALID_BEFORE'] = $port['PROXY_VALID_BEFORE'];
}
if (isset($port['OS'])) {
$portData['OS'] = $port['OS'];
}
$result = $this->makeRequest('/crud/store_port', 'POST',
'data=' . urlencode(json_encode($portData)));
if ($result['data']['result'] === 'success') {
$this->makeRequest('/apix/apply_port?arg=' . $portId);
return [
'success' => true,
'message' => "Port transferred from {$oldImei} to {$newImei}",
'old_imei' => $oldImei,
'new_imei' => $newImei
];
}
return ['success' => false, 'error' => 'Failed to transfer port'];
}
/**
* Helper: Get all ports
*
* @return array All ports grouped by IMEI
* @throws Exception On API error
*/
private function getAllPorts() {
$result = $this->makeRequest('/apix/list_ports_json');
return $result['data'] ?? [];
}
/**
* Helper: Get server host from URL
*
* @return string Server host with port
*/
private function getServerHost() {
$url = parse_url($this->serverConfig['url']);
return $url['host'] . (isset($url['port']) ? ':' . $url['port'] : '');
}
/**
* Helper: Generate random string
*
* @param int $length String length
* @return string Random string
*/
private function generateRandomString($length) {
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$result = '';
for ($i = 0; $i < $length; $i++) {
$result .= $chars[rand(0, strlen($chars) - 1)];
}
return $result;
}
/**
* Get last error message
*
* @return string|null Last error or null
*/
public function getLastError() {
return $this->lastError;
}
/**
* Get current server configuration
*
* @return array Server config
*/
public function getServerInfo() {
return $this->serverConfig;
}
/**
* Set active server
*
* @param string $serverKey Server key from config
* @return bool Success
*/
public function setActiveServer($serverKey) {
if (!isset($this->config['servers'][$serverKey])) {
return false;
}
$this->config['active_server'] = $serverKey;
$this->serverConfig = $this->config['servers'][$serverKey];
return true;
}
}
Пример интеграции
<?php
/**
* Proxysmart API Integration Example
* Complete working example showing all features
*/
// Include the API class
require_once 'api.php';
// Optional: Custom configuration
$customConfig = [
'active_server' => 'test_dedicated',
'servers' => [
'test_dedicated' => [
'name' => 'Test Server',
'type' => 'dedicated',
'url' => 'http://96.253.78.35:8080',
'username' => 'proxy',
'password' => 'proxy',
'location' => 'USA, Virginia',
'operators' => ['Test Operator'],
'max_ports_per_device' => 1
]
],
'defaults' => [
'port_expiry_days' => 30,
'http_port_range' => [8100, 8999],
'socks_port_range' => [5100, 5999],
'request_timeout' => 30
]
];
try {
// Initialize API client
// Use custom config or load from config.php
$api = new ProxysmartAPI($customConfig);
// or simply: $api = new ProxysmartAPI();
echo "=== Proxysmart API Integration Example ===\n\n";
// 1. Check server connection and statistics
echo "1. Checking server status...\n";
$stats = $api->getServerStatistics();
echo "Server connected successfully!\n";
echo "- Total devices: {$stats['device_statistics']['total']}\n";
echo "- Online devices: {$stats['device_statistics']['online']}\n";
echo "- Available devices: {$stats['device_statistics']['available']}\n";
echo "- Active ports: {$stats['port_statistics']['active']}\n\n";
// 2. Get free devices
echo "2. Getting free devices...\n";
$freeDevices = $api->getFreeDevices();
if (empty($freeDevices)) {
die("No free devices available. Please free up some devices first.\n");
}
echo "Found " . count($freeDevices) . " free devices:\n";
foreach ($freeDevices as $device) {
echo "- {$device['modem_details']['NICK']} ";
echo "(IMEI: {$device['modem_details']['IMEI']}, ";
echo "IP: {$device['net_details']['EXT_IP']})\n";
}
echo "\n";
// 3. Create a new port
echo "3. Creating new port...\n";
$selectedDevice = $freeDevices[0];
$imei = $selectedDevice['modem_details']['IMEI'];
$portName = "Demo_Port_" . date('Ymd_His');
$expiryDate = date('Y-m-d\TH:i', strtotime('+7 days')); // 7 days validity
$osFingerprint = 'android:3'; // Android fingerprint
$portResult = $api->createPort($imei, $portName, $expiryDate, $osFingerprint);
if (!$portResult['success']) {
die("Failed to create port: {$portResult['error']}\n");
}
$portId = $portResult['portID'];
echo "Port created successfully!\n";
echo "- Port ID: {$portId}\n";
echo "- HTTP Proxy: {$portResult['credentials']['http_proxy']}\n";
echo "- SOCKS5 Proxy: {$portResult['credentials']['socks_proxy']}\n";
echo "- Login: {$portResult['credentials']['login']}\n";
echo "- Password: {$portResult['credentials']['password']}\n\n";
// 4. Get port details
echo "4. Getting port access details...\n";
$portDetails = $api->getPortDetails($portId);
if ($portDetails['success']) {
echo "Port details retrieved:\n";
echo "- Reset IP URL: {$portDetails['reset_link']}\n";
echo "- Reset link valid until: {$portDetails['reset_valid_until']}\n";
echo "- OpenVPN config: {$portDetails['vpn_link']}\n\n";
// Download OpenVPN config (optional)
/*
$vpnConfig = file_get_contents($portDetails['vpn_link'], false,
stream_context_create([
'http' => [
'header' => 'Authorization: Basic ' .
base64_encode('proxy:proxy')
]
])
);
file_put_contents($portId . '.ovpn', $vpnConfig);
echo "OpenVPN config saved to {$portId}.ovpn\n\n";
*/
}
// 5. Change OS fingerprint
echo "5. Changing OS fingerprint to Windows 10...\n";
$osResult = $api->changeOSFingerprint($portId, 'windows:1');
if ($osResult['success']) {
echo "OS fingerprint changed successfully!\n\n";
}
// 6. Enable automatic IP rotation
echo "6. Enabling automatic IP rotation (every 30 minutes)...\n";
$rotationResult = $api->enableAutoRotation($portId, 30);
if ($rotationResult['success']) {
echo "Auto rotation enabled!\n";
echo "- Device: {$rotationResult['nick']} (IMEI: {$rotationResult['imei']})\n\n";
}
// 7. Test IP reset (optional - commented out to avoid actual reset)
/*
echo "7. Testing IP reset...\n";
$rebootResult = $api->rebootDeviceByPort($portId);
if ($rebootResult['success']) {
echo "Device rebooting...\n";
echo "- Old IP: {$rebootResult['data']['old_ip']}\n";
echo "- New IP: {$rebootResult['data']['ext_ip']}\n\n";
}
*/
// 8. List all active ports
echo "7. Getting all active ports...\n";
$activePorts = $api->getActivePorts();
echo "Found " . count($activePorts) . " active ports:\n";
foreach ($activePorts as $port) {
$remainingDays = floor($port['expires_in_seconds'] / 86400);
echo "- {$port['portName']} (Port: {$port['portID']}, ";
echo "Expires in: {$remainingDays} days)\n";
}
echo "\n";
// 9. Extend port validity
echo "8. Extending port validity for 30 more days...\n";
$newExpiry = date('Y-m-d\TH:i', strtotime('+30 days'));
$extendResult = $api->extendPort($portId, $newExpiry, false); // No device rotation
if ($extendResult['success']) {
echo "Port extended successfully!\n";
if ($extendResult['device_changed']) {
echo "Device was changed during extension:\n";
echo "- Old IMEI: {$extendResult['old_imei']}\n";
echo "- New IMEI: {$extendResult['new_imei']}\n";
}
echo "\n";
}
// 10. Transfer port to another device (if available)
if (count($freeDevices) > 1) {
echo "9. Transferring port to another device...\n";
$newDevice = $freeDevices[1];
$newImei = $newDevice['modem_details']['IMEI'];
$transferResult = $api->transferPort($portId, $newImei);
if ($transferResult['success']) {
echo "Port transferred successfully!\n";
echo "- From: {$transferResult['old_imei']}\n";
echo "- To: {$transferResult['new_imei']}\n\n";
}
}
// 11. Clean up - delete the test port
echo "10. Cleaning up - deleting test port...\n";
$deleteResult = $api->deletePorts($portId);
if ($deleteResult['success']) {
echo "Port deleted successfully!\n";
echo "- Deleted ports: " . implode(', ', $deleteResult['deleted_ports']) . "\n\n";
}
// 12. Delete all expired ports (optional)
echo "11. Checking for expired ports to clean up...\n";
$expiredResult = $api->deletePorts('expired');
echo "Deleted {$expiredResult['deleted_count']} expired ports\n\n";
echo "=== Integration example completed successfully! ===\n";
} catch (Exception $e) {
echo "\nERROR: " . $e->getMessage() . "\n";
echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
}
// Example: Working with proxy in your application
echo "\n=== Example: Using proxy in your application ===\n";
echo <<<'EXAMPLE'
// After creating a port, use the proxy credentials in your application:
$proxy = 'http://user12345:pass67890abc@96.253.78.35:8543';
// Example with cURL:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://ipinfo.io/json');
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
// Example with file_get_contents:
$context = stream_context_create([
'http' => [
'proxy' => $proxy,
'request_fulluri' => true
]
]);
$response = file_get_contents('http://ipinfo.io/json', false, $context);
// Example with Guzzle:
$client = new \GuzzleHttp\Client([
'proxy' => $proxy
]);
$response = $client->get('http://ipinfo.io/json');
EXAMPLE;
Важные замечания
- Проверка устройства: Всегда получайте IMEI устройства через порт перед операциями перезагрузки или ротации IP.
- Смена устройства: При переносе или продлении порта с ротацией порт создается на новом устройстве с теми же параметрами.
- Скорость API: API может работать медленно. Используйте таймауты и обработку ошибок.
- Ограничения: Не меняйте IP чаще раза в минуту, не перезагружайте устройство чаще раза в час.
- Автоматическая ротация: При сохранении настроек модема IMEI и name обязательны и не должны изменяться!
- Типы серверов: Логика определения свободных устройств зависит от типа сервера (Dedicated/Shared/Mix).