PHPackages                             shaykhnazar/hikvision-isapi - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. shaykhnazar/hikvision-isapi

ActiveLibrary[API Development](/categories/api)

shaykhnazar/hikvision-isapi
===========================

Laravel package for Hikvision ISAPI Face Recognition Terminals integration

v1.5.4(8mo ago)19203↑12.5%9[1 issues](https://github.com/Shaykhnazar/hikvision-isapi/issues)MITPHPPHP ^8.2

Since Oct 10Pushed 1mo agoCompare

[ Source](https://github.com/Shaykhnazar/hikvision-isapi)[ Packagist](https://packagist.org/packages/shaykhnazar/hikvision-isapi)[ RSS](/packages/shaykhnazar-hikvision-isapi/feed)WikiDiscussions master Synced today

READMEChangelogDependencies (5)Versions (29)Used By (0)

Hikvision ISAPI Laravel Package
===============================

[](#hikvision-isapi-laravel-package)

[![Latest Version](https://camo.githubusercontent.com/d2a1078b5f208b369d3fe798d6ee6bb9784906bbc8dcc074a8c5c26968858f4b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d76312e352e342d627269676874677265656e2e737667)](https://github.com/shaykhnazar/hikvision-isapi/releases)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](https://opensource.org/licenses/MIT)[![PHP Version](https://camo.githubusercontent.com/12ba79b4c8771d8067d75af9042c66480c860df180785c6462538e847ea1a5d2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253545382e322d626c75652e737667)](https://www.php.net/)[![Laravel Version](https://camo.githubusercontent.com/977ed8891f0c3f376e098db6a13fd1aa413d5d0c4e380d9a550a475e52696470/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d3131253230253743253230313225323025374325323031332d7265642e737667)](https://laravel.com/)

A clean, modern Laravel package for integrating with **Hikvision ISAPI Face Recognition Terminals** and access control devices. Supports multi-device management, universal device providers (config, database, API), multi-tenant architectures, and real-time event webhooks.

Features
--------

[](#features)

- **Real-Time Event Webhooks**: Configure devices to push events to your API endpoints (v1.4.0+)
- **Multi-Device Support**: Manage unlimited Hikvision terminals simultaneously (v1.2.0+)
- **Universal Device Providers**: Load devices from config, database, API, or custom sources (v1.3.0+)
- **Multi-Tenant Ready**: Tenant-scoped device loading with runtime registration (v1.3.0+)
- **Device Management**: Get device info, status, and capabilities
- **Person Management**: Add, update, search, and delete persons
- **Card Management**: Handle access cards with full CRUD operations
- **Face Recognition**: Upload and manage face images with advanced search (v1.1.0+)
- **Fingerprint Support**: Register and manage fingerprints
- **Access Control**: Control doors remotely
- **Event Handling**: Search and subscribe to access events
- **Event Notifications**: HTTP webhooks for real-time event delivery (v1.4.0+)
- **Clean Architecture**: SOLID principles, dependency injection, contracts
- **Type Safety**: PHP 8.2+ features (enums, readonly properties)
- **Performance**: Built-in caching with configurable TTL (v1.3.0+)
- **XML/JSON Support**: Automatic format detection and conversion (v1.4.0+)
- **Laravel 11/12/13**: Supports Laravel 11.x, 12.x, and 13.x with service provider and facade

Table of Contents
-----------------

[](#table-of-contents)

- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Quick Start](#quick-start)
- [Event Webhooks &amp; Notifications](#event-webhooks--notifications-v140)
    - [Configure Webhook Endpoint](#configure-webhook-endpoint)
    - [Simple Webhook Setup](#simple-webhook-setup)
    - [Advanced Webhook Configuration](#advanced-webhook-configuration)
    - [Testing Webhooks](#testing-webhooks)
    - [Receiving Webhook Events](#receiving-webhook-events)
- [Multi-Device Support](#multi-device-support)
    - [Configuration from Config Files](#configuration-from-config-files-default)
    - [Loading Devices from Database](#loading-devices-from-database)
    - [Using Eloquent Models with CallbackProvider](#using-eloquent-models-with-callbackprovider)
    - [Multi-Tenant Support](#multi-tenant-support-example)
    - [Runtime Device Registration](#runtime-device-registration)
    - [Device Manager Methods](#device-manager-methods)
- [Services Overview](#services-overview)
- [DTOs (Data Transfer Objects)](#dtos-data-transfer-objects)
- [Enums](#enums)
- [Error Handling](#error-handling)
- [Advanced Usage](#advanced-usage)
- [Testing](#testing)
- [Troubleshooting](#troubleshooting)
- [Security](#security)
- [Contributing](#contributing)
- [Changelog](#changelog)

Requirements
------------

[](#requirements)

- PHP ^8.2
- Laravel / illuminate/support ^11.0 || ^12.0 || ^13.0
- PHP ^8.3 is required when installing with Laravel 13
- Guzzle HTTP ^7.8
- ext-curl
- ext-json
- ext-simplexml
- ext-libxml

Installation
------------

[](#installation)

Install the package via Composer:

```
composer require shaykhnazar/hikvision-isapi
```

Publish the configuration file:

```
php artisan vendor:publish --tag=hikvision-config
```

Configuration
-------------

[](#configuration)

Add these environment variables to your `.env` file:

```
HIKVISION_IP=192.168.1.100
HIKVISION_PORT=80
HIKVISION_USERNAME=admin
HIKVISION_PASSWORD=your_password
HIKVISION_PROTOCOL=http
HIKVISION_TIMEOUT=30
HIKVISION_VERIFY_SSL=false
HIKVISION_FORMAT=json
```

### Configuration File

[](#configuration-file)

The published `config/hikvision.php` supports multiple devices:

```
return [
    'default' => env('HIKVISION_DEFAULT_DEVICE', 'primary'),

    'devices' => [
        'primary' => [
            'ip' => env('HIKVISION_IP', '192.168.1.100'),
            'port' => env('HIKVISION_PORT', 80),
            'username' => env('HIKVISION_USERNAME', 'admin'),
            'password' => env('HIKVISION_PASSWORD'),
            'protocol' => env('HIKVISION_PROTOCOL', 'http'),
            'timeout' => env('HIKVISION_TIMEOUT', 30),
            'verify_ssl' => env('HIKVISION_VERIFY_SSL', false),
        ],
    ],

    'format' => env('HIKVISION_FORMAT', 'json'),

    'logging' => [
        'enabled' => env('HIKVISION_LOGGING', true),
        'channel' => env('HIKVISION_LOG_CHANNEL', 'stack'),
    ],
];
```

Quick Start
-----------

[](#quick-start)

### Check Device Status

[](#check-device-status)

```
use Shaykhnazar\HikvisionIsapi\Services\DeviceService;

$deviceService = app(DeviceService::class);

if ($deviceService->isOnline()) {
    $info = $deviceService->getInfo();
    echo "Device Model: " . $info['DeviceInfo']['model'];
}
```

### Add a Person

[](#add-a-person)

```
use Shaykhnazar\HikvisionIsapi\Services\PersonService;
use Shaykhnazar\HikvisionIsapi\DTOs\Person;
use Shaykhnazar\HikvisionIsapi\Enums\UserType;

$personService = app(PersonService::class);

$person = new Person(
    employeeNo: 'EMP001',
    name: 'John Doe',
    userType: UserType::NORMAL,
    validEnabled: true,
    beginTime: now()->toISOString(),
    endTime: now()->addYear()->toISOString(),
    doorRight: '1',
    rightPlan: [
        ['doorNo' => 1, 'planTemplateNo' => '1']
    ]
);

$response = $personService->add($person);
```

### Upload Face Image

[](#upload-face-image)

```
use Shaykhnazar\HikvisionIsapi\Services\FaceService;

$faceService = app(FaceService::class);

// Read image file
$imageData = file_get_contents('path/to/photo.jpg');
$imageBase64 = base64_encode($imageData);

// Upload face (person must exist first)
$response = $faceService->uploadFace('EMP001', $imageBase64, 1);
```

### Search and Manage Face Data

[](#search-and-manage-face-data)

```
use Shaykhnazar\HikvisionIsapi\Services\FaceService;

$faceService = app(FaceService::class);

// Search face data with pagination
$results = $faceService->searchFace(
    page: 0,
    maxResults: 30,
    faceLibType: 'blackFD',
    fdid: 1,
    fpid: '31903791410044'
);

// Upload face data record with image file
$imageContent = file_get_contents('face.jpg');
$response = $faceService->uploadFaceDataRecord(
    fdid: 1,
    fpid: '31903791410044',
    imageContent: $imageContent,
    faceLibType: 'blackFD'
);

// Delete face search data
$faceService->deleteFaceSearch(fdid: 1, faceLibType: 'blackFD');
```

### Search Persons

[](#search-persons)

```
$personService = app(PersonService::class);

// Get total count
$total = $personService->count();

// Search with pagination (30 persons per page)
$persons = $personService->search(page: 0, maxResults: 30);

foreach ($persons as $person) {
    echo "{$person->employeeNo}: {$person->name}\n";
}
```

### Add Card

[](#add-card)

```
use Shaykhnazar\HikvisionIsapi\Services\CardService;
use Shaykhnazar\HikvisionIsapi\DTOs\Card;

$cardService = app(CardService::class);

$card = new Card(
    employeeNo: 'EMP001',
    cardNo: '1234567890',
    cardType: 'normal'
);

$response = $cardService->add($card);
```

### Control Doors

[](#control-doors)

```
use Shaykhnazar\HikvisionIsapi\Services\AccessControlService;

$accessControl = app(AccessControlService::class);

// Open door
$accessControl->openDoor(1);

// Get door status
$status = $accessControl->getDoorStatus(1);

// Close door
$accessControl->closeDoor(1);
```

### Search Events

[](#search-events)

```
use Shaykhnazar\HikvisionIsapi\Services\EventService;

$eventService = app(EventService::class);

$events = $eventService->search([
    'major' => 5,  // Access control
    'minor' => 75, // Face recognition
    'startTime' => now()->subDay()->toISOString(),
    'endTime' => now()->toISOString(),
], page: 0, maxResults: 50);
```

Event Webhooks &amp; Notifications (v1.4.0+)
--------------------------------------------

[](#event-webhooks--notifications-v140)

Configure Hikvision devices to automatically push events (access granted, face recognized, etc.) to your application's webhook endpoint in real-time. This eliminates the need for polling and provides instant event notifications.

### Configure Webhook Endpoint

[](#configure-webhook-endpoint)

The `EventNotificationService` allows you to configure HTTP event notifications on Hikvision devices:

```
use Shaykhnazar\HikvisionIsapi\Services\EventNotificationService;

$eventNotificationService = app(EventNotificationService::class);
```

### Simple Webhook Setup

[](#simple-webhook-setup)

The easiest way to set up a webhook is using the `configureWebhook()` method:

```
// Configure device to send all events to your webhook endpoint
$webhookUrl = 'https://your-api.com/api/webhooks/hikvision/events';

$response = $eventNotificationService->configureWebhook(
    webhookUrl: $webhookUrl,
    hostId: 1 // Host ID (1-8), default is 1
);

// Enable the webhook
$eventNotificationService->enableHttpHost(1);
```

### Advanced Webhook Configuration

[](#advanced-webhook-configuration)

For more control over webhook configuration, use `configureHttpHost()`:

```
$response = $eventNotificationService->configureHttpHost(
    url: 'https://your-api.com/api/webhooks/hikvision/events',
    id: 1,                      // Host ID (1-8)
    protocol: 'HTTPS',          // HTTP or HTTPS
    port: 443,                  // Port number
    httpAuthType: 'basic',      // none, basic, or digest
    username: 'webhook_user',   // Optional: for authentication
    password: 'webhook_pass',   // Optional: for authentication
    eventTypes: [               // Optional: specific event types (empty = all events)
        'AccessControllerEvent',
        'VideoMotion',
        'linedetection'
    ]
);
```

### Managing Webhook Hosts

[](#managing-webhook-hosts)

```
// Get webhook configuration
$config = $eventNotificationService->getHttpHost(1);

// Get all webhook configurations (supports up to 8 hosts)
$allConfigs = $eventNotificationService->getAllHttpHosts();

// Enable webhook
$eventNotificationService->enableHttpHost(1);

// Disable webhook
$eventNotificationService->disableHttpHost(1);

// Remove webhook configuration
$eventNotificationService->removeHttpHost(1);

// Get notification capabilities
$capabilities = $eventNotificationService->getCapabilities();
```

### Testing Webhooks

[](#testing-webhooks)

Test if your webhook endpoint is reachable from the device:

```
// Send a test event to configured webhook
$response = $eventNotificationService->testHttpNotification(1);
```

### Receiving Webhook Events

[](#receiving-webhook-events)

Create a controller to receive webhook events from Hikvision devices:

```
namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class HikvisionWebhookController extends Controller
{
    /**
     * Receive events from Hikvision devices
     */
    public function handleEvent(Request $request)
    {
        // Hikvision sends events as XML
        $xmlData = $request->getContent();

        // Parse XML to array
        $xml = simplexml_load_string($xmlData);
        $event = json_decode(json_encode($xml), true);

        // Log the event
        Log::info('Hikvision Event Received', $event);

        // Process event based on type
        $eventType = $event['eventType'] ?? null;

        match($eventType) {
            'AccessControllerEvent' => $this->handleAccessControl($event),
            'faceDetection' => $this->handleFaceDetection($event),
            'VideoMotion' => $this->handleMotionDetection($event),
            default => Log::warning('Unknown event type', ['type' => $eventType])
        };

        // Return 200 OK to acknowledge receipt
        return response('OK', 200);
    }

    protected function handleAccessControl(array $event)
    {
        // Example: Handle access control event
        $employeeNo = $event['employeeNoString'] ?? null;
        $cardNo = $event['cardNo'] ?? null;
        $doorNo = $event['doorNo'] ?? null;

        Log::info('Access Control Event', [
            'employee' => $employeeNo,
            'card' => $cardNo,
            'door' => $doorNo,
            'time' => $event['dateTime'] ?? now()
        ]);

        // Your business logic here
        // - Record attendance
        // - Send notifications
        // - Update access logs
    }

    protected function handleFaceDetection(array $event)
    {
        // Handle face detection event
        Log::info('Face Detection Event', $event);
    }

    protected function handleMotionDetection(array $event)
    {
        // Handle motion detection event
        Log::info('Motion Detection Event', $event);
    }
}
```

**Route setup:**

```
// routes/api.php
Route::post('webhooks/hikvision/events', [HikvisionWebhookController::class, 'handleEvent'])
    ->name('hikvision.webhook');
```

### Multi-Device Webhook Setup

[](#multi-device-webhook-setup)

Configure webhooks for multiple devices:

```
use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;
use Shaykhnazar\HikvisionIsapi\Services\EventNotificationService;

$devices = ['entrance', 'exit', 'canteen'];
$webhookUrl = 'https://your-api.com/api/webhooks/hikvision/events';

foreach ($devices as $deviceName) {
    $client = Hikvision::device($deviceName);
    $eventService = new EventNotificationService($client);

    // Configure webhook with device name in URL for identification
    $deviceWebhookUrl = $webhookUrl . '?device=' . $deviceName;

    $eventService->configureWebhook($deviceWebhookUrl);
    $eventService->enableHttpHost(1);

    Log::info("Webhook configured for device: {$deviceName}");
}
```

### Webhook Security

[](#webhook-security)

Protect your webhook endpoint:

```
// Add authentication to webhook configuration
$eventNotificationService->configureHttpHost(
    url: 'https://your-api.com/api/webhooks/hikvision/events',
    id: 1,
    protocol: 'HTTPS',
    port: 443,
    httpAuthType: 'basic',
    username: env('HIKVISION_WEBHOOK_USER'),
    password: env('HIKVISION_WEBHOOK_PASSWORD')
);

// In your controller, validate the credentials
public function handleEvent(Request $request)
{
    // Laravel automatically handles basic auth with middleware
    // Or manually validate:
    if ($request->getUser() !== env('HIKVISION_WEBHOOK_USER') ||
        $request->getPassword() !== env('HIKVISION_WEBHOOK_PASSWORD')) {
        return response('Unauthorized', 401);
    }

    // Process event...
}
```

### Webhook Event Examples

[](#webhook-event-examples)

**Access Control Event (Face Recognition):**

```

    AccessControllerEvent
    active
    Access Control Event
    2025-10-30T14:30:00Z

        AccessControllerEvent
        EMP001
        John Doe
        1234567890
        1
        success

```

**Motion Detection Event:**

```

    VideoMotion
    active
    2025-10-30T14:35:00Z

```

Using the Facade
----------------

[](#using-the-facade)

```
use Shaykhnazar\HikvisionIsapi\Facades\HikvisionIsapi;

// Get device info
$info = HikvisionIsapi::get('/ISAPI/System/deviceInfo');

// Custom endpoint
$response = HikvisionIsapi::post('/ISAPI/CustomEndpoint', [
    'key' => 'value'
]);
```

Services Overview
-----------------

[](#services-overview)

### DeviceService

[](#deviceservice)

```
$deviceService = app(DeviceService::class);

$deviceService->getInfo();           // Get device information
$deviceService->getCapabilities();   // Get device capabilities
$deviceService->getStatus();         // Get device status
$deviceService->isOnline();          // Check if device is online
```

### PersonService

[](#personservice)

```
$personService = app(PersonService::class);

$personService->add(Person $person);              // Add person
$personService->update(Person $person);           // Update person
$personService->apply(Person $person);            // Apply person changes
$personService->search(int $page, int $maxResults); // Search persons
$personService->delete(array $employeeNos);       // Delete persons
$personService->count();                          // Count persons
$personService->getCapabilities();                // Get capabilities
```

### CardService

[](#cardservice)

```
$cardService = app(CardService::class);

$cardService->add(Card $card);                    // Add card
$cardService->update(Card $card);                 // Update card
$cardService->search(...);                        // Search cards
$cardService->delete(array $employeeNos);         // Delete cards
$cardService->deleteAll();                        // Delete all cards
$cardService->count(?string $employeeNo);         // Count cards
$cardService->batchAdd(array $cards);             // Batch add cards
```

### FaceService

[](#faceservice)

```
$faceService = app(FaceService::class);

$faceService->uploadFace(string $employeeNo, string $imageBase64, int $fdid);
$faceService->deleteFace(int $fdid, int $fpid);
$faceService->searchFace(int $page, int $maxResults, string $faceLibType, ?int $fdid, ?string $fpid);
$faceService->deleteFaceSearch(int $fdid, string $faceLibType);
$faceService->uploadFaceDataRecord(int $fdid, string $fpid, string $imageContent, string $faceLibType);
$faceService->getLibraries();
$faceService->createLibrary(array $data);
$faceService->getCapabilities();
```

### FingerprintService

[](#fingerprintservice)

```
$fingerprintService = app(FingerprintService::class);

$fingerprintService->add(string $employeeNo, int $fingerprintId, string $data);
$fingerprintService->search(...);
$fingerprintService->capture(int $timeout);
$fingerprintService->delete(array $employeeNos);
$fingerprintService->getCapabilities();
```

### AccessControlService

[](#accesscontrolservice)

```
$accessControl = app(AccessControlService::class);

$accessControl->openDoor(int $doorNo);
$accessControl->closeDoor(int $doorNo);
$accessControl->getDoorStatus(int $doorNo);
```

### EventService

[](#eventservice)

```
$eventService = app(EventService::class);

$eventService->search(array $conditions, int $page, int $maxResults);
$eventService->count(array $conditions);
$eventService->subscribe(array $eventTypes, int $heartbeat);
```

### EventNotificationService

[](#eventnotificationservice)

```
$eventNotificationService = app(EventNotificationService::class);

// Simple webhook setup
$eventNotificationService->configureWebhook(string $webhookUrl, int $hostId);

// Advanced configuration
$eventNotificationService->configureHttpHost(string $url, int $id, string $protocol, int $port, string $httpAuthType, ?string $username, ?string $password, array $eventTypes);

// Manage webhooks
$eventNotificationService->getHttpHost(int $id);
$eventNotificationService->getAllHttpHosts();
$eventNotificationService->enableHttpHost(int $id);
$eventNotificationService->disableHttpHost(int $id);
$eventNotificationService->removeHttpHost(int $id);

// Testing
$eventNotificationService->testHttpNotification(int $id);

// Capabilities
$eventNotificationService->getCapabilities();
```

DTOs (Data Transfer Objects)
----------------------------

[](#dtos-data-transfer-objects)

### Person DTO

[](#person-dto)

```
use Shaykhnazar\HikvisionIsapi\DTOs\Person;
use Shaykhnazar\HikvisionIsapi\Enums\UserType;

$person = new Person(
    employeeNo: 'EMP001',
    name: 'John Doe',
    userType: UserType::NORMAL,
    validEnabled: true,
    beginTime: '2025-01-01T00:00:00',
    endTime: '2025-12-31T23:59:59',
    doorRight: '1',
    rightPlan: [
        ['doorNo' => 1, 'planTemplateNo' => '1']
    ],
    email: 'john@example.com',
    phoneNumber: '+1234567890',
    organizationId: 1,
    belongGroup: null
);

// Convert to array for API
$array = $person->toArray();

// Create from API response
$person = Person::fromArray($response);
```

### Card DTO

[](#card-dto)

```
use Shaykhnazar\HikvisionIsapi\DTOs\Card;

$card = new Card(
    employeeNo: 'EMP001',
    cardNo: '1234567890',
    cardType: 'normal',
    enabled: true
);
```

### Face DTO

[](#face-dto)

```
use Shaykhnazar\HikvisionIsapi\DTOs\Face;

$face = new Face(
    employeeNo: 'EMP001',
    faceData: base64_encode($imageData),
    faceLibId: 1,
    faceLibType: 'blackFD'
);
```

Enums
-----

[](#enums)

### UserType

[](#usertype)

```
use Shaykhnazar\HikvisionIsapi\Enums\UserType;

UserType::NORMAL    // Normal user
UserType::VISITOR   // Visitor
UserType::BLOCKLIST // Blocklist user

// Get label
$label = UserType::NORMAL->label(); // "Normal User"
```

### EventType

[](#eventtype)

```
use Shaykhnazar\HikvisionIsapi\Enums\EventType;

EventType::ACCESS_GRANTED  // 0x01
EventType::ACCESS_DENIED   // 0x02
EventType::FACE_RECOGNIZED // 0x4b
EventType::CARD_SWIPED     // 0x05

// Get description
$desc = EventType::ACCESS_GRANTED->description(); // "Access Granted"
```

Error Handling
--------------

[](#error-handling)

All exceptions extend `HikvisionException`:

```
use Shaykhnazar\HikvisionIsapi\Exceptions\HikvisionException;
use Shaykhnazar\HikvisionIsapi\Exceptions\AuthenticationException;
use Shaykhnazar\HikvisionIsapi\Exceptions\DeviceNotFoundException;

try {
    $response = $personService->add($person);
} catch (AuthenticationException $e) {
    // Handle authentication errors
    Log::error('Authentication failed', ['error' => $e->getMessage()]);
} catch (DeviceNotFoundException $e) {
    // Handle device not found
    Log::error('Device not found', ['error' => $e->getMessage()]);
} catch (HikvisionException $e) {
    // Handle other Hikvision errors
    Log::error('Hikvision error', ['error' => $e->getMessage()]);
}
```

Multi-Device Support
--------------------

[](#multi-device-support)

The package supports managing multiple Hikvision devices simultaneously. This is useful when you have multiple terminals at different locations (entrance, exit, canteen, etc.).

**Device Sources Supported:**

- ✅ Config files (default)
- ✅ Database tables
- ✅ Custom callbacks (API, Redis, cache, etc.)
- ✅ Runtime registration

### Configuration from Config Files (Default)

[](#configuration-from-config-files-default)

Configure multiple devices in `config/hikvision.php`:

```
return [
    'default' => env('HIKVISION_DEFAULT_DEVICE', 'primary'),

    'devices' => [
        'primary' => [
            'ip' => env('HIKVISION_IP', '192.168.1.100'),
            'port' => env('HIKVISION_PORT', 80),
            'username' => env('HIKVISION_USERNAME', 'admin'),
            'password' => env('HIKVISION_PASSWORD'),
            'protocol' => env('HIKVISION_PROTOCOL', 'http'),
            'timeout' => env('HIKVISION_TIMEOUT', 30),
            'verify_ssl' => env('HIKVISION_VERIFY_SSL', false),
        ],

        'entrance' => [
            'ip' => env('HIKVISION_ENTRANCE_IP', '192.168.1.101'),
            'port' => env('HIKVISION_ENTRANCE_PORT', 80),
            'username' => env('HIKVISION_ENTRANCE_USERNAME', 'admin'),
            'password' => env('HIKVISION_ENTRANCE_PASSWORD'),
            'protocol' => env('HIKVISION_ENTRANCE_PROTOCOL', 'http'),
            'timeout' => env('HIKVISION_ENTRANCE_TIMEOUT', 30),
            'verify_ssl' => env('HIKVISION_ENTRANCE_VERIFY_SSL', false),
        ],

        'exit' => [
            'ip' => env('HIKVISION_EXIT_IP', '192.168.1.102'),
            'port' => env('HIKVISION_EXIT_PORT', 80),
            'username' => env('HIKVISION_EXIT_USERNAME', 'admin'),
            'password' => env('HIKVISION_EXIT_PASSWORD'),
            'protocol' => env('HIKVISION_EXIT_PROTOCOL', 'http'),
            'timeout' => env('HIKVISION_EXIT_TIMEOUT', 30),
            'verify_ssl' => env('HIKVISION_EXIT_VERIFY_SSL', false),
        ],

        'canteen' => [
            'ip' => env('HIKVISION_CANTEEN_IP', '192.168.1.103'),
            'port' => env('HIKVISION_CANTEEN_PORT', 80),
            'username' => env('HIKVISION_CANTEEN_USERNAME', 'admin'),
            'password' => env('HIKVISION_CANTEEN_PASSWORD'),
            'protocol' => env('HIKVISION_CANTEEN_PROTOCOL', 'http'),
            'timeout' => env('HIKVISION_CANTEEN_TIMEOUT', 30),
            'verify_ssl' => env('HIKVISION_CANTEEN_VERIFY_SSL', false),
        ],
    ],
];
```

### Environment Variables

[](#environment-variables)

Add device-specific environment variables to `.env`:

```
# Primary Device (Default)
HIKVISION_DEFAULT_DEVICE=primary
HIKVISION_IP=192.168.1.100
HIKVISION_PORT=80
HIKVISION_USERNAME=admin
HIKVISION_PASSWORD=your_password

# Entrance Device
HIKVISION_ENTRANCE_IP=192.168.1.101
HIKVISION_ENTRANCE_PORT=80
HIKVISION_ENTRANCE_USERNAME=admin
HIKVISION_ENTRANCE_PASSWORD=entrance_password

# Exit Device
HIKVISION_EXIT_IP=192.168.1.102
HIKVISION_EXIT_PORT=80
HIKVISION_EXIT_USERNAME=admin
HIKVISION_EXIT_PASSWORD=exit_password

# Canteen Device
HIKVISION_CANTEEN_IP=192.168.1.103
HIKVISION_CANTEEN_PORT=80
HIKVISION_CANTEEN_USERNAME=admin
HIKVISION_CANTEEN_PASSWORD=canteen_password
```

### Using Multiple Devices with Facade

[](#using-multiple-devices-with-facade)

```
use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;

// Use default device
$defaultClient = Hikvision::default();
$info = $defaultClient->get('/ISAPI/System/deviceInfo');

// Use specific devices
$entranceClient = Hikvision::device('entrance');
$exitClient = Hikvision::device('exit');
$canteenClient = Hikvision::device('canteen');

// Get device information from each terminal
$entranceInfo = $entranceClient->get('/ISAPI/System/deviceInfo');
$exitInfo = $exitClient->get('/ISAPI/System/deviceInfo');
$canteenInfo = $canteenClient->get('/ISAPI/System/deviceInfo');

// List all available devices
$devices = Hikvision::availableDevices();
// Returns: ['primary', 'entrance', 'exit', 'canteen']

// Check if device exists
if (Hikvision::hasDevice('entrance')) {
    // Work with entrance device
}
```

### Using Multiple Devices with Services

[](#using-multiple-devices-with-services)

```
use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;
use Shaykhnazar\HikvisionIsapi\Services\PersonService;
use Shaykhnazar\HikvisionIsapi\DTOs\Person;
use Shaykhnazar\HikvisionIsapi\Enums\UserType;

// Create person DTO
$person = new Person(
    employeeNo: 'EMP001',
    name: 'John Doe',
    userType: UserType::NORMAL,
    validEnabled: true,
    beginTime: now()->toISOString(),
    endTime: now()->addYear()->toISOString()
);

// Get device-specific clients
$entranceClient = Hikvision::device('entrance');
$exitClient = Hikvision::device('exit');
$canteenClient = Hikvision::device('canteen');

// Create person service for each device
$entrancePersonService = new PersonService($entranceClient);
$exitPersonService = new PersonService($exitClient);
$canteenPersonService = new PersonService($canteenClient);

// Add person to all devices
$entrancePersonService->add($person);
$exitPersonService->add($person);
$canteenPersonService->add($person);
```

### Syncing Employee to Multiple Devices

[](#syncing-employee-to-multiple-devices)

```
use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;
use Shaykhnazar\HikvisionIsapi\Services\PersonService;
use Shaykhnazar\HikvisionIsapi\Services\FaceService;
use Shaykhnazar\HikvisionIsapi\DTOs\Person;

class EmployeeSyncService
{
    public function syncToAllDevices(Person $person, string $faceImagePath): array
    {
        $results = [];
        $devices = Hikvision::availableDevices();

        foreach ($devices as $deviceName) {
            try {
                // Get device client
                $client = Hikvision::device($deviceName);

                // Create services for this device
                $personService = new PersonService($client);
                $faceService = new FaceService($client);

                // Add person
                $personService->add($person);

                // Upload face
                $imageData = file_get_contents($faceImagePath);
                $imageBase64 = base64_encode($imageData);
                $faceService->uploadFace($person->employeeNo, $imageBase64, 1);

                $results[$deviceName] = [
                    'success' => true,
                    'message' => 'Synced successfully',
                ];
            } catch (\Exception $e) {
                $results[$deviceName] = [
                    'success' => false,
                    'error' => $e->getMessage(),
                ];
            }
        }

        return $results;
    }
}
```

### Device Manager Methods

[](#device-manager-methods)

The `DeviceManager` provides the following methods:

```
use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;

// Get client for specific device (or default if null)
$client = Hikvision::device('entrance');
$client = Hikvision::device(); // Uses default device

// Get default device client
$defaultClient = Hikvision::default();

// Get all available device names
$devices = Hikvision::availableDevices();
// Returns: ['primary', 'entrance', 'exit', 'canteen']

// Check if device exists in configuration
$exists = Hikvision::hasDevice('entrance'); // true or false

// Reload devices from provider (useful for database-driven configs)
Hikvision::reload(); // Clears cache and reloads from source

// Clear cached clients (useful for testing)
Hikvision::clearClients();

// Register device at runtime (v1.3.0+)
Hikvision::registerDevice('temp_device', [
    'ip' => '192.168.1.150',
    'port' => 80,
    'username' => 'admin',
    'password' => 'password',
    'protocol' => 'http',
    'timeout' => 30,
    'verify_ssl' => false,
]);

// Switch device provider at runtime (v1.3.0+)
use Shaykhnazar\HikvisionIsapi\Client\Providers\DatabaseDeviceProvider;
$dbProvider = new DatabaseDeviceProvider(table: 'terminals');
Hikvision::setProvider($dbProvider);
```

### Backward Compatibility

[](#backward-compatibility)

The package maintains **100% backward compatibility**. If you're using the default device setup, your existing code will work without any changes:

```
use Shaykhnazar\HikvisionIsapi\Services\PersonService;

// This still works - uses default device
$personService = app(PersonService::class);
$person = $personService->add($newPerson);
```

### Loading Devices from Database

[](#loading-devices-from-database)

For applications that store terminal configurations in database (multi-tenant, dynamic terminals, etc.), use the `DatabaseDeviceProvider`:

#### Step 1: Create Terminals Table

[](#step-1-create-terminals-table)

```
// Migration: create_terminals_table.php
Schema::create('terminals', function (Blueprint $table) {
    $table->id();
    $table->string('name')->unique(); // Device identifier
    $table->string('ip');
    $table->integer('port')->default(80);
    $table->string('username');
    $table->string('password');
    $table->string('protocol')->default('http');
    $table->integer('timeout')->default(30);
    $table->boolean('verify_ssl')->default(false);
    $table->boolean('is_active')->default(true);
    $table->timestamps();
});
```

#### Step 2: Register Database Provider

[](#step-2-register-database-provider)

In your `AppServiceProvider` or custom service provider:

```
use Shaykhnazar\HikvisionIsapi\Client\Providers\DatabaseDeviceProvider;

public function register(): void
{
    // Bind custom device provider
    $this->app->singleton('hikvision.device.provider', function ($app) {
        return new DatabaseDeviceProvider(
            table: 'terminals',
            nameColumn: 'name',
            configColumns: [
                'ip' => 'ip',
                'port' => 'port',
                'username' => 'username',
                'password' => 'password',
                'protocol' => 'protocol',
                'timeout' => 'timeout',
                'verify_ssl' => 'verify_ssl',
            ],
            defaultDevice: 'primary',
            whereConditions: ['is_active' => true], // Only load active terminals
            cache: true, // Enable caching
            cacheTtl: 3600 // Cache for 1 hour
        );
    });
}
```

#### Step 3: Use Terminals from Database

[](#step-3-use-terminals-from-database)

```
use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;
use Shaykhnazar\HikvisionIsapi\Services\PersonService;

// Get all available terminals from database
$terminals = Hikvision::availableDevices();
// Returns: ['entrance', 'exit', 'canteen', 'office'] - loaded from DB

// Use specific terminal
$entranceClient = Hikvision::device('entrance');
$personService = new PersonService($entranceClient);

// Add person to entrance terminal
$personService->add($person);
```

#### Step 4: Reload Devices When Database Changes

[](#step-4-reload-devices-when-database-changes)

```
use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;

// After adding/updating terminals in database
Hikvision::reload(); // Clears cache and reloads from DB
```

### Using Eloquent Models with CallbackProvider

[](#using-eloquent-models-with-callbackprovider)

For more complex scenarios with Eloquent relationships:

```
use Shaykhnazar\HikvisionIsapi\Client\Providers\CallbackDeviceProvider;
use App\Models\Terminal;

// In your service provider
$this->app->singleton('hikvision.device.provider', function ($app) {
    return CallbackDeviceProvider::fromEloquent(
        query: Terminal::where('status', 'active')
                      ->where('company_id', auth()->user()->company_id),
        nameColumn: 'slug',
        configMap: [
            'ip' => 'ip_address',
            'port' => 'port',
            'username' => 'username',
            'password' => 'password',
            'protocol' => 'protocol',
            'timeout' => 'connection_timeout',
            'verify_ssl' => 'ssl_enabled',
        ]
    );
});
```

### Multi-Tenant Support Example

[](#multi-tenant-support-example)

For multi-tenant applications where each tenant has their own terminals:

```
use Shaykhnazar\HikvisionIsapi\Client\Providers\CallbackDeviceProvider;
use App\Models\Terminal;

// In AppServiceProvider
$this->app->singleton('hikvision.device.provider', function ($app) {
    return new CallbackDeviceProvider(
        deviceNamesCallback: function () {
            // Only load terminals for current tenant
            $tenantId = auth()->user()->tenant_id;
            return Terminal::where('tenant_id', $tenantId)
                          ->where('is_active', true)
                          ->pluck('name')
                          ->toArray();
        },
        deviceConfigCallback: function (string $deviceName) {
            $tenantId = auth()->user()->tenant_id;
            $terminal = Terminal::where('tenant_id', $tenantId)
                               ->where('name', $deviceName)
                               ->first();

            if (!$terminal) {
                return null;
            }

            return [
                'ip' => $terminal->ip,
                'port' => $terminal->port,
                'username' => $terminal->username,
                'password' => decrypt($terminal->password), // Decrypt if encrypted
                'protocol' => $terminal->protocol,
                'timeout' => $terminal->timeout,
                'verify_ssl' => $terminal->verify_ssl,
            ];
        },
        defaultDevice: 'primary'
    );
});
```

### Runtime Device Registration

[](#runtime-device-registration)

Register devices dynamically at runtime:

```
use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;

// Register a temporary device
Hikvision::registerDevice('temp_device', [
    'ip' => '192.168.1.150',
    'port' => 80,
    'username' => 'admin',
    'password' => 'password',
    'protocol' => 'http',
    'timeout' => 30,
    'verify_ssl' => false,
]);

// Use the temporary device
$client = Hikvision::device('temp_device');
```

### Switching Providers at Runtime

[](#switching-providers-at-runtime)

Change device provider dynamically:

```
use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;
use Shaykhnazar\HikvisionIsapi\Client\Providers\DatabaseDeviceProvider;
use Shaykhnazar\HikvisionIsapi\Client\Providers\ConfigDeviceProvider;

// Switch to database provider
$dbProvider = new DatabaseDeviceProvider(table: 'terminals');
Hikvision::setProvider($dbProvider);

// Now all devices are loaded from database
$devices = Hikvision::availableDevices();

// Switch back to config provider
$configProvider = new ConfigDeviceProvider(config('hikvision'));
Hikvision::setProvider($configProvider);
```

Advanced Usage
--------------

[](#advanced-usage)

### Batch Operations

[](#batch-operations)

```
$cardService = app(CardService::class);

$cards = [
    new Card('EMP001', '1234567890'),
    new Card('EMP002', '0987654321'),
    new Card('EMP003', '1122334455'),
];

$results = $cardService->batchAdd($cards);

/*
Returns:
[
    'total' => 3,
    'success' => 3,
    'failed' => 0,
    'errors' => []
]
*/
```

### Pagination

[](#pagination)

```
$personService = app(PersonService::class);
$total = $personService->count();
$perPage = 30;
$pages = ceil($total / $perPage);

for ($page = 0; $page < $pages; $page++) {
    $persons = $personService->search($page, $perPage);
    // Process persons...
}
```

### Custom HTTP Requests

[](#custom-http-requests)

```
use Shaykhnazar\HikvisionIsapi\Facades\HikvisionIsapi;

// GET request
$response = HikvisionIsapi::get('/ISAPI/CustomEndpoint', [
    'param1' => 'value1',
]);

// POST request
$response = HikvisionIsapi::post('/ISAPI/CustomEndpoint', [
    'key' => 'value',
]);

// PUT request
$response = HikvisionIsapi::put('/ISAPI/CustomEndpoint', [
    'key' => 'value',
]);

// DELETE request
$response = HikvisionIsapi::delete('/ISAPI/CustomEndpoint');
```

Testing
-------

[](#testing)

```
# Run tests
./vendor/bin/phpunit

# Run specific test file
./vendor/bin/phpunit tests/Feature/PersonServiceTest.php

# Run with coverage
./vendor/bin/phpunit --coverage-html coverage
```

Troubleshooting
---------------

[](#troubleshooting)

### Authentication Failed (401)

[](#authentication-failed-401)

Check your credentials in `.env`:

```
# Test with curl
curl -v --digest -u admin:password http://192.168.1.100/ISAPI/System/deviceInfo
```

### Connection Timeout

[](#connection-timeout)

- Verify device IP and network connectivity
- Increase timeout in config: `HIKVISION_TIMEOUT=60`
- Check firewall rules

### Face Upload Fails

[](#face-upload-fails)

- Ensure image is JPEG format
- Check image size (max 200KB)
- Verify person exists on device first
- Image quality should be good with clear face

### Device Not Found

[](#device-not-found)

- Check IP address in `.env`
- Verify device is powered on
- Ensure device is on same network

Security
--------

[](#security)

See [SECURITY.md](SECURITY.md) for supported versions, vulnerability reporting instructions, and disclosure policy. Do not open public GitHub issues for suspected vulnerabilities; report them privately through the channels described there.

- Store Hikvision device and webhook credentials in environment variables or a secret manager; never commit them
- Prefer HTTPS/TLS for device and webhook communication where supported
- Enable SSL certificate verification with valid certificates in production
- Restrict device access with firewalls, VPNs, or private networks
- Implement rate limiting on your API endpoints
- Validate webhook payloads and all user-controlled input
- Treat XML input as untrusted and parse it defensively
- Avoid logging credentials, tokens, face images, biometric data, or raw personally identifiable data
- Rotate device and webhook credentials after suspected compromise

Contributing
------------

[](#contributing)

Contributions are welcome! Please follow these guidelines:

1. Fork the repository
2. Create a feature branch
3. Write tests for new features
4. Follow PSR-12 coding standards
5. Submit a pull request

Changelog
---------

[](#changelog)

For full release history, see [CHANGELOG.md](CHANGELOG.md) and the GitHub releases/tags.

### v1.5.4 (2025-11-05)

[](#v154-2025-11-05)

- Current stable release on Packagist.
- Fixed FaceService image filenames so supported face upload/update flows use unique `{fpid}.jpg` filenames.

### v1.4.0 (2025-10-30)

[](#v140-2025-10-30)

- **EventNotificationService**: New service for configuring HTTP event notifications (webhooks)
- **Real-Time Webhooks**: Configure devices to push events to your API endpoints automatically
- **XML Support**: Added `putXml()` method to HikvisionClient for XML-only endpoints
- **HTTP Client Enhancements**:
    - Added `arrayToXml()` method for converting arrays to XML format
    - Added `xmlToArray()` method for parsing XML responses
    - Automatic XML/JSON format detection based on Content-Type
- **Event Notification Methods**:
    - `configureWebhook()` - Simple one-line webhook setup
    - `configureHttpHost()` - Advanced webhook configuration with authentication
    - `enableHttpHost()` / `disableHttpHost()` - Enable/disable webhooks
    - `testHttpNotification()` - Test webhook connectivity
    - `getCapabilities()` - Get notification capabilities
- **Dependencies**: Added `ext-simplexml` and `ext-libxml` for XML processing
- **Multi-Device Webhooks**: Configure webhooks for multiple devices simultaneously
- **Webhook Security**: Support for HTTP Basic and Digest authentication
- 100% backward compatible with v1.3.0

### v1.3.0 (2025-10-13)

[](#v130-2025-10-13)

- **Universal Device Providers**: Framework for loading devices from any source
- **DatabaseDeviceProvider**: Load terminals from database tables with built-in caching
- **CallbackDeviceProvider**: Maximum flexibility with custom callbacks (API, Redis, etc.)
- **Multi-Tenant Support**: Tenant-scoped device loading and isolation
- **Runtime Device Registration**: Register devices dynamically at runtime
- **Provider Switching**: Change device providers on-the-fly
- **Hot Reload**: Update database-driven configurations without restart
- **Configurable Caching**: Built-in cache support with TTL control
- 100% backward compatible with v1.2.0

### v1.2.0 (2025-10-13)

[](#v120-2025-10-13)

- **Multi-Device Support**: Manage unlimited Hikvision devices simultaneously
- **DeviceManager**: Central manager with lazy initialization and caching
- **New Hikvision Facade**: Multi-device access with `Hikvision::device()`
- **Device Discovery**: List and validate configured devices
- **Device-Specific Clients**: Automatic client caching per device
- 100% backward compatible with single-device setups

### v1.1.0 (2025-10-13)

[](#v110-2025-10-13)

- **Face Search Functionality**: Search face data with pagination support
- **Face Data Record Upload**: Multipart/form-data support for face images
- **Fixed PersonService Delete Endpoint**: Updated to match ISAPI specification
- **Configuration Validation**: Required username/password validation
- **Extended HTTP Client**: Added multipart form-data upload support
- Enhanced error handling and validation

### v1.0.0 (2025-10-09)

[](#v100-2025-10-09)

- Initial release
- Full ISAPI support
- Person, Card, Face, Fingerprint management
- Access control and event handling
- Laravel 11/12/13 support
- PHP 8.2+ with modern features

License
-------

[](#license)

This package is open-sourced software licensed under the [MIT license](LICENSE).

Credits
-------

[](#credits)

- **Author**: Shaykhnazar
- **Email**:

Support
-------

[](#support)

For issues, questions, or contributions:

- GitHub Issues:
- Email:

Disclaimer
----------

[](#disclaimer)

This package is designed for **legitimate access control systems** and **defensive security** purposes only. Do not use for malicious purposes.

---

**Made with ❤️ for the Laravel community**

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance78

Regular maintenance activity

Popularity26

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

28

Last Release

241d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3a29bb830d42d2603e05dff1a60283ba6960092fb14116668e6d7721c4f5b2f0?d=identicon)[Shaykhnazar](/maintainers/Shaykhnazar)

---

Top Contributors

[![Shaykhnazar](https://avatars.githubusercontent.com/u/49790448?v=4)](https://github.com/Shaykhnazar "Shaykhnazar (31 commits)")

---

Tags

laravelaccess-controlface-recognitionhikvisionISAPI

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/shaykhnazar-hikvision-isapi/health.svg)

```
[![Health](https://phpackages.com/badges/shaykhnazar-hikvision-isapi/health.svg)](https://phpackages.com/packages/shaykhnazar-hikvision-isapi)
```

###  Alternatives

[craftcms/cms

Craft CMS

3.6k3.6M3.1k](/packages/craftcms-cms)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5021.9k](/packages/simplestats-io-laravel-client)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

273.0k](/packages/eslazarev-wildberries-sdk)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
