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
- PHP 8.1 or newer.
- A secret key, and a webhook signing secret if you receive webhooks.
Install
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
$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
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
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
| Member | Returns | Notes |
|---|---|---|
new Client($secretKey) | Client | A second argument takes endpoint and an HTTP client. |
$client->events->get($requestId) | Event | Throws ApiException with getStatus() for a non-2xx response. |
$client->events->list([...]) | EventPage | Keys: from, to, page, limit, visitor, level. |
Webhook::verify(secret:, payload:, timestamp:, signature:) | bool | Five minutes of tolerance. |