verifykit-io/2fa-php-sdk

Official PHP SDK for VerifyKit 2FA - Two-factor authentication via Email OTP

Maintainers

Package info

github.com/verifykit-io/2fa-php-sdk

Homepage

Documentation

pkg:composer/verifykit-io/2fa-php-sdk

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-03-02 16:37 UTC

This package is not auto-updated.

Last update: 2026-03-04 23:31:26 UTC


README

Packagist Version License: MIT PHP Version

Official PHP SDK for VerifyKit 2FA - Two-factor authentication via Email OTP.

Features

  • Simple & Intuitive - Send and verify OTP codes in two API calls
  • Fast & Reliable - Built-in retry logic and error handling
  • Modern PHP - PHP 8 features with PHP 7.4+ compatibility
  • Automatic Retries - Smart retry logic with exponential backoff
  • Rate Limit Handling - Automatic rate limit detection and retry
  • Custom Exceptions - Detailed exception classes for better error handling
  • Secure - SHA-256 hashed codes, auto-expiry, max 5 attempts

Requirements

  • PHP 7.4 or higher (PHP 8.0+ recommended)
  • ext-json
  • ext-filter

Installation

Install via Composer:

composer require verifykit-io/2fa-php-sdk

Quick Start

<?php

require 'vendor/autoload.php';

use VerifyKit2FA\VerifyKit2FA;

// Initialize with your API key
$client = new VerifyKit2FA(
    apiKey: $_ENV['VERIFYKIT_API_KEY'] // Get your API key from https://verifykit.io/dashboard/api-keys
);

// Send an OTP code
$result = $client->sendOtp('user@example.com');
$requestId = $result->requestId;

// Verify the code entered by the user
$verification = $client->verifyOtp($requestId, '123456');
echo $verification->valid ? 'Verified!' : 'Invalid code';

Table of Contents

Authentication

Get your API key from the VerifyKit Dashboard. 2FA requires a Growth, Pro, or Unlimited plan.

<?php

use VerifyKit2FA\VerifyKit2FA;

$client = new VerifyKit2FA(
    apiKey: $_ENV['VERIFYKIT_API_KEY']
);

Environment Variables:

# .env file
VERIFYKIT_API_KEY=vk_live_your_api_key_here

Usage Examples

Send OTP Code

<?php

use VerifyKit2FA\VerifyKit2FA;

$client = new VerifyKit2FA(apiKey: $_ENV['VERIFYKIT_API_KEY']);

$result = $client->sendOtp('user@example.com');

echo "Request ID: {$result->requestId}\n";   // Save this to verify later
echo "Expires in: {$result->expiresIn}s\n";  // Seconds until code expires (default: 600)
echo "Message: {$result->message}\n";

Verify OTP Code

<?php

// After the user enters their code
$verification = $client->verifyOtp($requestId, '847293');

if ($verification->valid) {
    echo "User verified!\n";
} else {
    echo "Invalid code: {$verification->message}\n";
}

Custom App Name

Brand the verification email with your app name:

<?php

$result = $client->sendOtp(
    'user@example.com',
    appName: 'MyApp' // Displayed in the verification email (max 50 chars)
);

API Delivery Mode

Get the OTP code in the API response instead of sending via email:

<?php

$result = $client->sendOtp(
    'user@example.com',
    delivery: 'api' // Returns the code in the response
);

echo $result->code; // '847293' - deliver this yourself via SMS, push, etc.

Configuration

<?php

use VerifyKit2FA\VerifyKit2FA;

$client = new VerifyKit2FA(
    // Required: Your API key (use environment variable)
    apiKey: $_ENV['VERIFYKIT_API_KEY'],

    // Optional: Base URL (default: 'https://api.verifykit.io')
    baseUrl: 'https://api.verifykit.io',

    // Optional: Request timeout in seconds (default: 30)
    timeout: 30,

    // Optional: Maximum number of retries (default: 3)
    maxRetries: 3,

    // Optional: Enable debug logging (default: false)
    debug: true,

    // Optional: Custom headers
    headers: [
        'X-Custom-Header' => 'value'
    ]
);

API Reference

sendOtp(string $email, ?string $appName = null, string $delivery = 'email'): SendOtpResult

Send a 2FA OTP verification code to an email address.

Parameters:

  • $email (string): The email address to send the code to
  • $appName (string|null): Your app name for the verification email (max 50 chars)
  • $delivery (string): Delivery mode - 'email' (default) or 'api'

Returns: SendOtpResult

Example:

$result = $client->sendOtp('user@example.com', appName: 'MyApp');

verifyOtp(string $requestId, string $code): VerifyOtpResult

Verify a 2FA OTP code.

Parameters:

  • $requestId (string): The requestId from sendOtp
  • $code (string): The 6-digit code entered by the user

Returns: VerifyOtpResult

Example:

$result = $client->verifyOtp('2fa_abc123...', '847293');
echo $result->valid ? 'Valid' : 'Invalid';

Error Handling

The SDK provides detailed exception classes for different scenarios:

<?php

use VerifyKit2FA\VerifyKit2FA;
use VerifyKit2FA\Exception\ValidationException;
use VerifyKit2FA\Exception\AuthenticationException;
use VerifyKit2FA\Exception\ForbiddenException;
use VerifyKit2FA\Exception\RateLimitException;
use VerifyKit2FA\Exception\NetworkException;
use VerifyKit2FA\Exception\ServerException;
use VerifyKit2FA\Exception\VerifyKit2FAException;

$client = new VerifyKit2FA(apiKey: $_ENV['VERIFYKIT_API_KEY']);

try {
    $result = $client->sendOtp('user@example.com');
} catch (ValidationException $e) {
    echo "Invalid input: {$e->getMessage()}\n";
} catch (AuthenticationException $e) {
    echo "Invalid API key: {$e->getMessage()}\n";
} catch (ForbiddenException $e) {
    echo "2FA not available on your plan: {$e->getMessage()}\n";
} catch (RateLimitException $e) {
    echo "Rate limit exceeded, retry after: {$e->retryAfter}s\n";
} catch (NetworkException $e) {
    echo "Network error: {$e->getMessage()}\n";
} catch (ServerException $e) {
    echo "Server error: {$e->getMessage()}\n";
} catch (VerifyKit2FAException $e) {
    echo "VerifyKit error: {$e->getMessage()}\n";
} catch (\Exception $e) {
    echo "Unknown error: {$e->getMessage()}\n";
}

Exception Properties

All VerifyKit 2FA exceptions include:

  • getMessage(): Human-readable error message
  • errorCode: Machine-readable error code
  • statusCode: HTTP status code
  • requestId: Request ID for debugging

Advanced Features

Automatic Retries

The SDK automatically retries failed requests with exponential backoff:

<?php

$client = new VerifyKit2FA(
    apiKey: 'vk_live_...',
    maxRetries: 5 // Retry up to 5 times (default: 3)
);

Retries are attempted for:

  • Network errors
  • Server errors (5xx)
  • Rate limit errors (with appropriate delay)

Rate Limit Handling

The SDK automatically handles rate limits by:

  1. Detecting rate limit errors (429)
  2. Waiting with exponential backoff
  3. Retrying the request automatically
<?php

// The SDK handles this automatically
try {
    $result = $client->sendOtp('user@example.com');
} catch (RateLimitException $e) {
    // Only throws if max retries exceeded
    echo "Still rate limited after retries\n";
}

Debug Logging

Enable debug logging to see detailed request/response information:

<?php

$client = new VerifyKit2FA(
    apiKey: 'vk_live_...',
    debug: true
);

// Logs will show:
// - Request details
// - Retry attempts
// - Error information

Custom Timeouts

Configure request timeouts:

<?php

$client = new VerifyKit2FA(
    apiKey: 'vk_live_...',
    timeout: 60 // 60 seconds
);

OTP Security

VerifyKit 2FA codes are:

  • SHA-256 hashed - Codes are never stored in plain text
  • Single-use - Each code can only be verified once
  • Auto-expiring - Codes expire after 10 minutes
  • Rate limited - Maximum 5 verification attempts per code

Testing

The SDK includes test coverage:

Running Tests

# Run all tests
composer test

# Run only unit tests
./vendor/bin/pest tests/Unit

# Run static analysis
composer analyse

# Format code
composer format

# Check formatting
composer format:check

Examples

Check out the examples directory for more usage examples:

  • basic-usage.php - Send and verify an OTP code
  • error-handling.php - Comprehensive error handling

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

License

MIT (c) Nuno Miguel Duarte Unip. Lda

Made with care by the VerifyKit team