PHP code example of olorunda / laravel-zkteco-push

1. Go to this page and download the library: Download olorunda/laravel-zkteco-push library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

olorunda / laravel-zkteco-push example snippets


// In config/zkteco-push.php
'admin_middleware' => ['web', 'auth'], // Require user authentication

// Or with custom authorization / permission middleware:
'admin_middleware' => ['web', 'auth', 'can:access-zkteco-admin'],

use ZkTeco\Push\Facades\ZkTecoPush;

// 1. Delete user with a 2-minute delay (120 seconds) using array
ZkTecoPush::deleteUser('ZK-SN-001', ['pin' => '1003'], delaySeconds: 120);

// 2. Queue command using array format
ZkTecoPush::queueCommand('ZK-SN-001', [
    'action' => 'delete_user',
    'pin' => '1003'
], delaySeconds: 120);

// 3. Add or update user using array payload
ZkTecoPush::addUser('ZK-SN-001', [
    'pin' => '1004',
    'name' => 'John Doe',
    'card_number' => '987654321',
    'password' => '1234'
]);

use ZkTeco\Push\Facades\ZkTecoPush;

// Chain methods directly on a target machine
ZkTecoPush::device('ZK-SN-001')
    ->deleteUser('1003', delaySeconds: 120);

ZkTecoPush::device('ZK-SN-001')
    ->reboot(delaySeconds: 10);

ZkTecoPush::device('ZK-SN-001')
    ->syncTime();

ZkTecoPush::device('ZK-SN-001')
    ->unlockDoor(unlockSeconds: 5);

use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;
use ZkTeco\Push\Events\AttendancePushed;

Event::listen(AttendancePushed::class, function (AttendancePushed $event) {
    // Machine Serial Number (e.g. "ZK-SN-001")
    $deviceSn = $event->deviceSn;
    
    // Array of parsed attendance punch records
    foreach ($event->records as $log) {
        $userPin = $log['pin'];                      // e.g. "1003"
        $punchTime = $log['timestamp'];              // e.g. "2026-08-09 08:30:00"
        $statusCode = $log['status_code'];           // e.g. 0 (Check-In) or 1 (Check-Out)
        $statusLabel = $log['status_label'];         // e.g. "Check-In"
        $verifyTypeCode = $log['verify_type_code'];   // e.g. 1 (Fingerprint) or 15 (Face)
        $verifyTypeLabel = $log['verify_type_label']; // e.g. "Fingerprint"
        
        Log::info("Attendance Punch recorded for User {$userPin} on Device {$deviceSn} via {$verifyTypeLabel}");
        
        // Save to your Eloquent Attendance model:
        // AttendanceRecord::create([
        //     'employee_id' => $userPin,
        //     'device_sn' => $deviceSn,
        //     'punched_at' => $punchTime,
        //     'punch_type' => $statusLabel,
        //     'verification_method' => $verifyTypeLabel,
        // ]);
    }
});

namespace App\Listeners;

use ZkTeco\Push\Events\AttendancePushed;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Models\Attendance;

class ProcessZkTecoPunch implements ShouldQueue
{
    public function handle(AttendancePushed $event): void
    {
        foreach ($event->records as $log) {
            Attendance::updateOrCreate(
                [
                    'device_sn' => $event->deviceSn,
                    'user_pin' => $log['pin'],
                    'punched_at' => $log['timestamp'],
                ],
                [
                    'status' => $log['status_label'],
                    'method' => $log['verify_type_label'],
                ]
            );
        }
    }
}

use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;
use ZkTeco\Push\Events\DeviceHeartbeat;

Event::listen(DeviceHeartbeat::class, function (DeviceHeartbeat $event) {
    $deviceSn = $event->deviceSn; // Device Serial Number (e.g. "ZK-SN-001")
    $metadata = $event->metadata; // Hardware metadata array
    
    $ipAddress = $metadata['ip'] ?? '127.0.0.1';
    $pushVersion = $metadata['pushversion'] ?? '3.0.1';
    $firmware = $metadata['firmware'] ?? 'Ver 8.0.0';
    
    Log::info("Device {$deviceSn} heartbeat received from IP {$ipAddress}");
    
    // Update machine status in your database:
    // BiometricDevice::where('serial_number', $deviceSn)->update([
    //     'last_seen_at' => now(),
    //     'ip_address' => $ipAddress,
    //     'is_online' => true,
    // ]);
});

use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;
use ZkTeco\Push\Events\CommandExecuted;

Event::listen(CommandExecuted::class, function (CommandExecuted $event) {
    $deviceSn = $event->deviceSn; // Machine Serial Number
    $result = $event->result;     // Command Execution Result Payload
    
    $commandId = $result['command_id'];  // Unique Command ID string
    $returnCode = $result['return_code']; // 0 = Success, non-zero = error
    $status = ($returnCode === 0) ? 'COMPLETED' : 'FAILED';
    
    if ($returnCode === 0) {
        Log::info("Command {$commandId} successfully executed on device {$deviceSn}");
    } else {
        Log::error("Command {$commandId} failed on device {$deviceSn} with code {$returnCode}");
    }
    
    // Update command status in your system:
    // DeviceCommandLog::where('command_id', $commandId)->update([
    //     'status' => $status,
    //     'executed_at' => now(),
    // ]);
});

namespace App\Listeners;

use ZkTeco\Push\Events\AttendancePushed;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use App\Models\EmployeeAttendance;
use Throwable;

class SyncBiometricAttendanceListener implements ShouldQueue
{
    use InteractsWithQueue;

    public int $tries = 3;
    public int $timeout = 60;

    public function handle(AttendancePushed $event): void
    {
        $deviceSn = $event->deviceSn;
        $records = $event->records;

        Log::channel('daily')->info("Processing " . count($records) . " attendance punches from device [{$deviceSn}]");

        DB::beginTransaction();
        try {
            foreach ($records as $log) {
                EmployeeAttendance::updateOrCreate(
                    [
                        'device_sn' => $deviceSn,
                        'user_pin' => (string)$log['pin'],
                        'punched_at' => $log['timestamp'],
                    ],
                    [
                        'status' => $log['status_label'],
                        'verification_method' => $log['verify_type_label'],
                        'work_code' => $log['work_code'] ?? '0',
                        'raw_payload' => json_encode($log),
                    ]
                );
            }

            DB::commit();
            Log::info("Successfully synced " . count($records) . " attendance records for device [{$deviceSn}]");
        } catch (Throwable $e) {
            DB::rollBack();
            Log::error("Failed to sync attendance batch from [{$deviceSn}]: " . $e->getMessage());
            throw $e; // Trigger job retry
        }
    }
}

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Routing\Controller;
use ZkTeco\Push\Facades\ZkTecoPush;
use Illuminate\Support\Facades\Log;

class BiometricEmployeeManagementController extends Controller
{
    /**
     * Onboard Employee to Biometric Terminal
     * POST /api/employees/onboard
     */
    public function onboardEmployee(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'device_sn' => '                'card_number' => $validated['card_number'] ?? null,
                    'password' => $validated['passcode'] ?? null,
                    'privilege' => 0, // 0 = Standard User, 14 = Admin
                ]);

            return response()->json([
                'status' => 'success',
                'message' => "User provisioning command queued for terminal {$validated['device_sn']}",
                'command_id' => $cmdId,
            ]);
        } catch (\Throwable $e) {
            Log::error("Onboarding error: " . $e->getMessage());
            return response()->json(['status' => 'error', 'message' => $e->getMessage()], 500);
        }
    }

    /**
     * Offboard Employee with Delayed Deletion (e.g., 2 minutes delay)
     * DELETE /api/employees/offboard
     */
    public function offboardEmployee(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'device_sn' => 'cess',
            'message' => "Door unlock command issued for {$seconds} seconds",
            'command_id' => $cmdId,
        ]);
    }
}
bash
php artisan vendor:publish --tag=zkteco-config
php artisan vendor:publish --tag=zkteco-migrations

php artisan migrate
ini
ZKTECO_ADMIN_MIDDLEWARE="web,auth"