verifinow / laravel
Official VerifyNow Laravel package for Age Verification and Identity Verification
Requires
- php: ^8.3
- guzzlehttp/guzzle: ^7.0
- laravel/framework: ^11.0
Requires (Dev)
- laravel/pint: ^1.0
- orchestra/testbench: ^9.0
- pestphp/pest: ^2.0
- phpstan/phpstan: ^1.0
This package is not auto-updated.
Last update: 2026-04-04 15:44:02 UTC
README
Official Laravel package for VerifyNow Age Verification and Identity Verification services.
Features
- ๐ Identity Verification (IDV) - Document-based verification
- ๐ Facial Recognition - Liveness detection and face matching
- ๐ Webhook Support - Automatic verification status updates
- ๐ก๏ธ Signature Verification - Secure webhook validation
- ๐ Database Models - Track all verifications and attempts
- ๐ฏ Route Middleware - Protect routes with verification requirements
- ๐ก Event System - React to verification completion/failure
- ๐งช Fully Tested - Comprehensive test suite included
Requirements
- PHP 8.3+
- Laravel 11.0+
- Guzzle HTTP 7.0+
Installation
composer require verifinow/laravel
Configuration
Publish the configuration file:
php artisan vendor:publish --provider="VerifyNow\Laravel\VerifyNowServiceProvider" --tag=verifinow-config
Add to your .env:
VERIFINOW_API_KEY=sk_live_xxxxxxxxxxxxx VERIFINOW_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxx VERIFINOW_BASE_URL=https://7on7-backend.verifinow.io VERIFINOW_TIMEOUT=30 VERIFINOW_REGISTER_ROUTES=true VERIFINOW_QUEUE_VERIFICATIONS=false
Database Setup
Publish and run migrations:
php artisan vendor:publish --provider="VerifyNow\Laravel\VerifyNowServiceProvider" --tag=verifinow-migrations
php artisan migrate
Usage
Basic Usage with Facades
use VerifyNow\Laravel\Facades\VerifyNow; // Request ID Verification $response = VerifyNow::requestIDV([ 'user_id' => auth()->id(), 'country' => 'US', 'document_type' => 'passport', ]); // Check verification status $status = VerifyNow::checkVerificationStatus($response['verification_id']); // Request facial authentication $auth = VerifyNow::requestAuthentication([ 'user_id' => auth()->id(), 'verification_id' => $response['verification_id'], ]);
Using Services
use VerifyNow\Laravel\Services\IDVService; use VerifyNow\Laravel\Services\AuthenticationService; // IDV Service $idvService = app(IDVService::class); $result = $idvService->request(['user_id' => 1, 'country' => 'US']); $isApproved = $idvService->isSuccessful($verification_id); // Authentication Service $authService = app(AuthenticationService::class); $result = $authService->request(['user_id' => 1, 'verification_id' => $vid]); $confidenceScore = $authService->getConfidenceScore($verification_id);
Add Verification to User Model
use VerifyNow\Laravel\Traits\Verifiable; use VerifyNow\Laravel\Traits\HasVerifications; class User extends Model { use Verifiable, HasVerifications; } // Check if user is verified $user->isVerified(); // bool // Get latest verification $verification = $user->latestVerification(); // Check if requires re-verification $user->requiresReverification(365); // bool // Get approval rate $user->verificationApprovalRate(); // float (0-100) // Authentication checks $user->hasCompletedAuthentication(); // bool $user->lastAuthenticationHasLiveness(); // bool $user->lastAuthenticationFaceMatched(); // bool
Protect Routes
// Require verification for routes Route::middleware('verifinow.verified')->group(function () { Route::get('/verified-content', function () { // Only verified users access }); }); // Require specific verification type Route::middleware('verifinow.verified:idv')->group(function () { // Only IDV verified users }); Route::middleware('verifinow.verified:authentication')->group(function () { // Only authenticated users });
Listen to Events
use VerifyNow\Laravel\Events\VerificationCompleted; use VerifyNow\Laravel\Events\VerificationFailed; use Illuminate\Support\Facades\Event; Event::listen(VerificationCompleted::class, function ($event) { $verification = $event->verification; if ($verification->isApproved()) { // Notify user verification succeeded $user = $verification->user; $user->notify(new VerificationApprovedNotification()); } }); Event::listen(VerificationFailed::class, function ($event) { // Handle verification failure Log::error('Verification failed', ['verification' => $event->verification]); });
Handle Webhooks
The package automatically handles VerifyNow webhooks at /api/webhooks/verifinow:
// Configure webhook in VerifyNow dashboard: // Webhook URL: https://yourapp.com/api/webhooks/verifinow // Events: verification.completed, verification.failed, etc.
Testing
Run the test suite:
./vendor/bin/pest
Run specific test file:
./vendor/bin/pest tests/Feature/WebhookTest.php
Generate coverage report:
./vendor/bin/pest --coverage
Database Schema
verifications Table
Stores verification requests and results:
id- Primary keyuser_id- Associated userverification_id- VerifyNow verification IDtype- Verification type (idv, authentication, age_verification)country- Country codestatus- Status (pending, processing, completed, failed)result- Result (approved, rejected, pending)confidence_score- Confidence score (0-100)document_type- Document type usedmetadata- Additional datacompleted_at- Completion timestamp
verification_attempts Table
Tracks individual verification attempts:
id- Primary keyverification_id- Foreign key to verificationsattempt_number- Attempt sequence numberstatus- Attempt statusresponse_code- API response codeerror_message- Error details if failedresponse_data- Full API responseip_address- Request IPuser_agent- Request user agent
user_authentications Table
Stores facial authentication results:
id- Primary keyverification_id- Foreign key to verificationsuser_id- Associated userauthentication_id- VerifyNow authentication IDstatus- Status (pending, processing, completed, failed)result- Result (approved, rejected, pending)confidence_score- Overall confidenceliveness_score- Liveness detection scoreface_match_score- Face matching scoredevice_info- Device informationlocation_data- Location dataauthenticated_at- Authentication timestamp
Configuration Options
All configuration options can be set via environment variables:
# API Configuration VERIFINOW_API_KEY= # Your VerifyNow API key (required) VERIFINOW_BASE_URL= # VerifyNow API base URL VERIFINOW_WEBHOOK_SECRET= # Webhook signature secret (required) VERIFINOW_TIMEOUT= # Request timeout in seconds (default: 30) # Feature Flags VERIFINOW_REGISTER_ROUTES= # Auto-register webhook routes (default: true) VERIFINOW_QUEUE_VERIFICATIONS= # Queue verification jobs (default: false) VERIFINOW_CACHE_VERIFICATIONS= # Cache verification results (default: true) VERIFINOW_CACHE_TTL= # Cache TTL in seconds (default: 3600) # Retry Configuration VERIFINOW_RETRY_FAILED= # Retry failed verifications (default: true) VERIFINOW_MAX_RETRIES= # Maximum retry attempts (default: 3) # Logging VERIFINOW_LOG_CHANNEL= # Log channel (default: single)
Helper Functions
Convenient helper functions are available:
// Get the main service verify_now(); // Get the manager verifinow_manager(); // Request IDV verification request_idv(['user_id' => 1, 'country' => 'US']); // Request authentication request_authentication(['user_id' => 1, 'verification_id' => 'ver_xxx']); // Check verification status check_verification_status('ver_xxx');
Error Handling
The package throws specific exceptions for different scenarios:
use VerifyNow\Laravel\Exceptions\{ VerifyNowException, UnauthorizedException, InvalidRequestException, DocumentValidationException, LivenessFailedException, FaceMismatchException, }; try { VerifyNow::requestIDV($data); } catch (UnauthorizedException $e) { // Invalid API key } catch (InvalidRequestException $e) { // Invalid request data } catch (DocumentValidationException $e) { // Document quality/format issue } catch (LivenessFailedException $e) { // Liveness detection failed } catch (FaceMismatchException $e) { // Face doesn't match document } catch (VerifyNowException $e) { // Generic VerifyNow API error }
Documentation
See the docs/ folder for complete documentation:
Support
For issues, questions, or contributions, please visit:
- GitHub: https://github.com/verifinow/laravel
- VerifyNow: https://verifinow.io
License
The MIT License (MIT). Please see License File for more information.
Contributing
Please see CONTRIBUTING.md for details.
Changelog
Please see CHANGELOG.md for details on what has changed recently.