SDKs

PHP

Read identification events with a secret key and verify signed webhooks from PHP 8.1 and newer, with Laravel and Symfony examples.

The fingerly/fingerly-php package reads stored events by request ID and verifies webhook signatures. It uses any PSR-18 HTTP client and falls back to Guzzle.

Requirements

Install

Terminal
composer require fingerly/fingerly-php

Read an event

Create one client with your secret key and reuse it. The key decides the regional API and the environment the client reads.

PHP
<?php

$fingerly = new \Fingerly\Client(getenv('FINGERLY_SECRET_KEY'));
$event = $fingerly->events->get('01a0a84b-e6a2-7c09-9f51-0b3d7a26c8e4');

An event has the fields listed in Get an event. suspect_score is null when the request was not scored.

Verify a checkout

Read the event your client identified, check it belongs to this action and is recent, then decide on its level. See server-side verification.

PHP
<?php

use Fingerly\ApiException;

function decide(string $orderId, string $requestId): string
{
    global $fingerly;

    try {
        $event = $fingerly->events->get($requestId);
    } catch (ApiException $e) {
        if ($e->getStatus() === 404) {
            return 'refuse';
        }
        throw $e;
    }

    if ($event->tag !== "checkout:{$orderId}") {
        return 'refuse';
    }
    if ($event->occurredAt < new DateTimeImmutable('-2 minutes')) {
        return 'refuse';
    }

    return match ($event->suspectLevel) {
        'high' => 'review',
        'medium' => 'challenge',
        default => 'allow',
    };
}

Verify a webhook

Check the signature over the raw request body before parsing it. The helper rejects timestamps more than five minutes from now.

PHP
<?php

use Fingerly\Webhook;
use Illuminate\Http\Request;

Route::post('/webhooks/fingerly', function (Request $request) {
    $valid = Webhook::verify(
        secret: config('services.fingerly.webhook_secret'),
        payload: $request->getContent(),
        timestamp: $request->header('x-fingerly-timestamp'),
        signature: $request->header('x-fingerly-signature'),
    );
    abort_unless($valid, 400);

    ProcessFingerlyEvent::dispatch($request->json()->all());
    return response()->noContent();
});

API

MemberReturnsNotes
new Client($secretKey)ClientA second argument takes endpoint and an HTTP client.
$client->events->get($requestId)EventThrows ApiException with getStatus() for a non-2xx response.
$client->events->list([...])EventPageKeys: from, to, page, limit, visitor, level.
Webhook::verify(secret:, payload:, timestamp:, signature:)boolFive minutes of tolerance.