AXIAM PHP SDK

AxiamWebhooks
in package

FinalYes

Verifies the `X-Axiam-Signature` HMAC-SHA256 header AXIAM attaches to every webhook delivery (CONTRACT.md §13, T-145). Mirrors the server's signer (`crates/axiam-api-rest/src/webhook.rs`'s `compute_signature_v2`): the MAC covers the ASCII string `<t>.<raw_body>`, keyed with the webhook secret's raw UTF-8 bytes.

Table of Contents

Constants

DEFAULT_TOLERANCE_SECONDS  : mixed = 300
The default freshness window (CONTRACT.md §13.2): a signature whose `t=` is more than this far in the past OR the future (relative to the `$now` clock — see {@see self::verify()}) is rejected.

Methods

verify()  : WebhookEvent
Verifies a webhook delivery's `X-Axiam-Signature` header against `$body` and returns the parsed {@see WebhookEvent} on success.

Constants

DEFAULT_TOLERANCE_SECONDS

The default freshness window (CONTRACT.md §13.2): a signature whose `t=` is more than this far in the past OR the future (relative to the `$now` clock — see {@see self::verify()}) is rejected.

public mixed DEFAULT_TOLERANCE_SECONDS = 300

Methods

verify()

Verifies a webhook delivery's `X-Axiam-Signature` header against `$body` and returns the parsed {@see WebhookEvent} on success.

public static verify(Sensitive $secret, string $signatureHeader, string $body[, int $toleranceSeconds = self::DEFAULT_TOLERANCE_SECONDS ][, callable(): int|null $now = null ]) : WebhookEvent
Parameters
$secret : Sensitive

The webhook's plaintext signing secret (CONTRACT.md §7). Its raw UTF-8 bytes are the HMAC key.

$signatureHeader : string

The raw, unparsed X-Axiam-Signature header value — t=<unix_seconds>,v1=<hex>, optionally with multiple v1 entries during secret rotation.

$body : string

The exact raw bytes received off the wire, before any JSON decoding. Re-serializing a parsed body (different key order/whitespace) changes these bytes and breaks the MAC — callers MUST pass the untouched request body, e.g. file_get_contents('php://input') read BEFORE any framework has parsed it as JSON.

$toleranceSeconds : int = self::DEFAULT_TOLERANCE_SECONDS

The freshness window in seconds; a non-positive value falls back to self::DEFAULT_TOLERANCE_SECONDS (300). Rejects a t= more than this far in the past OR the future — a two-sided check, so a future-dated timestamp is rejected just like a stale one (clock-skew abuse).

$now : callable(): int|null = null

Test/injection seam for "now" (unix seconds); defaults to time(). Pass a fake clock to deterministically exercise the freshness check.

Tags
throws
WebhookVerificationException

The header is malformed (no v1, more than one t, non-numeric t, or empty), no supplied v1 matches the recomputed MAC, or t falls outside the freshness tolerance. The exception message is always a fixed, generic reason string — never the expected signature or the secret (CONTRACT.md §13.3 rule 6).

Return values
WebhookEvent
On this page

Search results