PHPackages                             preverus/preverus-laravel - 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. preverus/preverus-laravel

ActiveLibrary

preverus/preverus-laravel
=========================

Laravel integration for Preverus hosted-script form protection and backend fraud decisions.

v0.1.3(1mo ago)03MITPHPPHP ^8.1

Since Jul 13Pushed 1mo agoCompare

[ Source](https://github.com/Preverus/preverus-laravel)[ Packagist](https://packagist.org/packages/preverus/preverus-laravel)[ Docs](https://preverus.com)[ RSS](/packages/preverus-preverus-laravel/feed)WikiDiscussions main Synced 2w ago

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

Preverus Laravel
================

[](#preverus-laravel)

Laravel integration for Preverus hosted-script form protection and backend fraud decisions.

Website:
Documentation:

This package is designed for Laravel, PHP, and server-rendered applications that do not use the JavaScript npm SDK. It pairs the hosted Preverus browser script with trusted Laravel backend enforcement.

Install
-------

[](#install)

```
composer require preverus/preverus-laravel
php artisan vendor:publish --tag=preverus-config
```

Add keys to `.env`:

```
PREVERUS_BROWSER_KEY=pk_live_xxx
PREVERUS_SERVER_KEY=sk_live_xxx
```

Use two keys in production:

- Browser key: publishable, used by the hosted script.
- Server key: private, used only by Laravel for decisions and lookups.

Never put your server key in Blade, JavaScript, or public config.

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

[](#quick-start)

Add the hosted script to your main layout:

```
@preverusScript(['auto' => true, 'trackForms' => true])
```

Protect a server-rendered form:

```

    @csrf

    Create account

```

Before submit, the hosted script attaches hidden fields:

```
preverus_fingerprint
preverus_visitor_id
preverus_risk_session_token
preverus_browser_session_event_id

```

Evaluate risk in your controller:

```
use Illuminate\Http\Request;
use Preverus\Laravel\Facades\Preverus;

public function register(Request $request)
{
    $decision = Preverus::evaluate($request, [
        'event_type' => 'signup',
        'user_id' => $request->input('user_id'),
        'metadata' => [
            'email' => $request->input('email'),
        ],
    ]);

    if ($decision->isBlock()) {
        abort(403, 'Unable to create account.');
    }

    if ($decision->isReview()) {
        return redirect()->route('verify');
    }

    // Continue registration.
}
```

No try/catch is required for normal use. If Preverus is unavailable, the package returns a fallback `DecisionResult` based on your configured failure mode.

Failure Modes
-------------

[](#failure-modes)

Failure mode is optional. If you do not configure it, the package defaults to `open` so your Laravel app keeps working if Preverus is temporarily unreachable.

Optional `.env` value:

```
PREVERUS_FAILURE_MODE=open
```

Supported modes:

```
open   -> allow if Preverus is unavailable
review -> send to step-up/manual review if Preverus is unavailable
closed -> block if Preverus is unavailable

```

Recommended defaults:

- Use `open` for signup, login, and checkout if uptime/revenue continuity is the priority.
- Use `review` for withdrawals, payouts, password resets, and payment changes.
- Use `closed` only when your business explicitly wants to stop the action during vendor/API failure.

You can override per call:

```
$decision = Preverus::evaluate($request, [
    'event_type' => 'withdraw',
    'user_id' => $user->id,
    'failure_mode' => 'review',
]);
```

Fallback decisions are still valid objects:

```
$decision->isFallback();
$decision->failureReason();
$decision->recommendedAction();
```

Retries And Timeouts
--------------------

[](#retries-and-timeouts)

Defaults are short so your Laravel request does not hang:

```
PREVERUS_TIMEOUT_MS=1500
PREVERUS_CONNECT_TIMEOUT_MS=500
PREVERUS_RETRIES=2
PREVERUS_RETRY_DELAY_MS=150
PREVERUS_MAX_RETRY_DELAY_MS=1000
```

The underlying PHP client retries transient network failures and retryable HTTP statuses:

```
408, 409, 425, 429, 500, 502, 503, 504

```

It does not retry validation or auth failures like `400`, `401`, `403`, or `422`.

The Laravel wrapper automatically sends `X-Idempotency-Key` for decision and event POSTs.

Circuit Breaker
---------------

[](#circuit-breaker)

The package includes a simple cache-backed circuit breaker. If repeated Preverus calls fail, Laravel temporarily stops making outbound calls and immediately returns fallback decisions.

```
PREVERUS_CIRCUIT_BREAKER=true
PREVERUS_CIRCUIT_FAILURE_THRESHOLD=5
PREVERUS_CIRCUIT_COOLDOWN_SECONDS=30
```

This protects merchant apps from slow request chains during an outage.

What `evaluate()` Sends
-----------------------

[](#what-evaluate-sends)

`Preverus::evaluate($request, [...])` automatically extracts:

```
preverus_fingerprint
preverus_visitor_id
preverus_risk_session_token
preverus_browser_session_event_id
request IP
user agent
accept language
current URL
referrer

```

It sends `preverus_visitor_id` as `X-Visitor-ID` when available.

It sends `preverus_risk_session_token` as `risk_session_token` when available. This is preferred because it links the trusted backend action to the stored browser session collected moments earlier.

Sensitive Actions
-----------------

[](#sensitive-actions)

Use synchronous decisions for actions where your app needs an immediate allow/review/block answer:

```
$decision = Preverus::evaluate($request, [
    'event_type' => 'withdraw',
    'user_id' => $user->id,
    'metadata' => [
        'payment_address' => $request->input('payment_address'),
    ],
    'failure_mode' => 'review',
]);

if ($decision->isBlock()) {
    abort(403);
}

if ($decision->isReview()) {
    return redirect()->route('withdraw.review');
}
```

Good event names include:

```
signup
login
checkout
password_reset
payout
withdraw
payment_change
account_update

```

Middleware
----------

[](#middleware)

For simple routes, you can use middleware:

```
Route::post('/withdraw', WithdrawController::class)
    ->middleware('preverus:withdraw,withdraw.review');
```

The first argument is the `event_type`. The second optional argument is a route name for review outcomes.

Controller-level usage is still recommended for complex flows because every application handles step-up and manual review differently.

Queue Non-Blocking Events
-------------------------

[](#queue-non-blocking-events)

Use queued events for telemetry that does not need to block the user:

```
Preverus::dispatchEvent($request, [
    'event_type' => 'profile_update',
    'user_id' => $user->id,
    'metadata' => [
        'email' => $user->email,
    ],
]);
```

Queue config:

```
PREVERUS_QUEUE_EVENTS=true
PREVERUS_QUEUE_CONNECTION=redis
PREVERUS_QUEUE=default
```

Queued event jobs retry with backoff:

```
10s, 30s, 120s, 300s

```

Lookups
-------

[](#lookups)

Visitor lookup:

```
$visitor = Preverus::lookupVisitor(visitorId: 'v_abc123');
$visitor = Preverus::lookupVisitor(fingerprint: 'fp_hash');
```

Metadata lookup:

```
$metadata = Preverus::lookupMetadata('email', 'person@example.com');
$userRiskProfile = Preverus::lookupUserRiskProfile('acct_42');
```

Use lookups for investigations and added context. Do not use lookups as the only enforcement decision for sensitive actions; call `evaluate()` for final allow/review/block guidance.

Webhook Verification
--------------------

[](#webhook-verification)

```
use Illuminate\Http\Request;
use Preverus\Laravel\Facades\Preverus;

Route::post('/preverus/webhook', function (Request $request) {
    if (!Preverus::verifyWebhook($request, config('services.preverus.webhook_secret'))) {
        abort(400, 'Invalid webhook signature');
    }

    $payload = $request->json()->all();

    // Store $payload['id'] or X-Fraud-Webhook-Id for idempotency.

    return response()->noContent();
});
```

Webhook delivery is at-least-once. Always dedupe by `X-Fraud-Webhook-Id` or payload `id`.

For a complete verify-parse-dispatch flow:

```
Route::post('/preverus/webhook', function (Request $request) {
    Preverus::handleWebhook(
        $request,
        config('services.preverus.webhook_secret'),
        [
            'decision.high_risk' => function ($event) {
                // Open a case, notify ops, or hold the account action.
            },
            '*' => function ($event) {
                // Optional catch-all handler.
            },
        ],
        function ($event) {
            return DB::table('processed_webhooks')->where('id', $event->id())->exists();
        },
    );

    return response()->noContent();
});
```

The package does not own your idempotency table because every Laravel app stores operational events differently.

Strict Exceptions
-----------------

[](#strict-exceptions)

If you want exceptions instead of fallback decisions:

```
$decision = Preverus::evaluateOrFail($request, [
    'event_type' => 'signup',
    'user_id' => $user->id,
]);
```

Most production apps should use `evaluate()` so a temporary external failure does not crash the customer flow.

Full Config
-----------

[](#full-config)

```
return [
    'server_key' => env('PREVERUS_SERVER_KEY'),
    'browser_key' => env('PREVERUS_BROWSER_KEY'),
    'endpoint' => env('PREVERUS_ENDPOINT', 'https://api.preverus.com'),
    'script_url' => env('PREVERUS_SCRIPT_URL', 'https://api.preverus.com/v1/preverus.js'),
    // Optional. Defaults to open.
    'failure_mode' => env('PREVERUS_FAILURE_MODE', 'open'),
    'http' => [
        'timeout_ms' => env('PREVERUS_TIMEOUT_MS', 1500),
        'connect_timeout_ms' => env('PREVERUS_CONNECT_TIMEOUT_MS', 500),
        'retries' => env('PREVERUS_RETRIES', 2),
    ],
    'circuit_breaker' => [
        'enabled' => true,
        'failure_threshold' => 5,
        'cooldown_seconds' => 30,
    ],
    'queue' => [
        'events' => true,
        'connection' => env('PREVERUS_QUEUE_CONNECTION'),
        'queue' => env('PREVERUS_QUEUE', 'default'),
    ],
];
```

Production Checklist
--------------------

[](#production-checklist)

- Add `@preverusScript(['auto' => true])` to layouts with protected forms.
- Add `data-preverus-action` to signup, login, checkout, withdraw, payout, password reset, and payment-change forms.
- Call `Preverus::evaluate()` before approving sensitive actions.
- Send your real account ID as `user_id`.
- Include metadata such as email, phone, username, and payment address where available.
- Use `review` outcomes for step-up auth or manual review.
- Configure failure mode per risk level.
- Keep `PREVERUS_SERVER_KEY` private.
- Verify and dedupe webhooks before processing them.

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance92

Actively maintained with recent releases

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 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 ~3 days

Total

4

Last Release

39d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/5856a97797bf2bae9a6b63393e1a73ec8816b614b15198e8a12eac2a6df6f014?d=identicon)[preverus](/maintainers/preverus)

---

Top Contributors

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

### Embed Badge

![Health badge](/badges/preverus-preverus-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/preverus-preverus-laravel/health.svg)](https://phpackages.com/packages/preverus-preverus-laravel)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3365.5M359](/packages/psalm-plugin-laravel)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k17.6M170](/packages/laravel-pulse)[api-platform/laravel

API Platform support for Laravel

58190.1k22](/packages/api-platform-laravel)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

80732.6M276](/packages/laravel-mcp)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

1.0k2.5M153](/packages/roots-acorn)

PHPackages © 2026

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