Webhook helpers¶
Pennylane\Sdk\Webhooks\Webhooks verifies webhook delivery signatures and parses payloads. Pennylane webhooks are in beta: they POST a JSON payload to your HTTPS endpoint, and the response to the subscription creation call carries a secret returned only once, used to sign deliveries with an HMAC.
Pennylane documents the HMAC secret but not the exact signature header name or encoding, so verification is deliberately tolerant: it accepts hex in both cases and base64, with or without a sha256= or hmac-sha256= prefix. Every comparison is constant time. Check your webhook deliveries to find the signature header, and keep the changelog endpoints as a fallback while the feature is in beta.
Webhooks¶
Both methods are static; the class cannot be instantiated.
verifySignature()¶
public static function verifySignature(
string $payload,
string $signature,
string $secret,
): bool
| Parameter | Description |
|---|---|
$payload |
The RAW request body, exactly as received. Re-serializing the JSON would change the bytes and the HMAC. |
$signature |
Value of the signature header of the delivery. |
$secret |
The subscription secret returned at creation time. #[\SensitiveParameter]. |
Returns false (rather than throwing) when $signature or $secret is empty, or when none of the accepted encodings match.
parseEvent()¶
public static function parseEvent(
string $payload,
?string $signature = null,
?string $secret = null,
): WebhookEvent
Parses a webhook delivery, optionally verifying its signature first. When $secret is given, $signature must also be given and must verify, or WebhookSignatureException is thrown. $secret is marked #[\SensitiveParameter].
Throws PennylaneException (not a more specific subclass) when the payload is not valid JSON, or is valid JSON but not a JSON object.
WebhookEvent¶
Pennylane\Sdk\Webhooks\WebhookEvent extends PennylaneObject. Unknown fields are preserved: inspect toArray() for event specific data. Known event types include customer_invoice.e_invoicing_status_updated and dms_file.created.
| Property | Type | Description |
|---|---|---|
event |
?string |
Event type identifier. |
data |
?array |
Event specific payload data. |
Example¶
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use Pennylane\Sdk\Exception\PennylaneException;
use Pennylane\Sdk\Exception\WebhookSignatureException;
use Pennylane\Sdk\Webhooks\Webhooks;
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_PENNYLANE_SIGNATURE'] ?? '';
$secret = getenv('PENNYLANE_WEBHOOK_SECRET');
try {
$event = Webhooks::parseEvent($payload, $signature, $secret);
} catch (WebhookSignatureException $e) {
http_response_code(400);
exit('Invalid signature');
} catch (PennylaneException $e) {
http_response_code(400);
exit('Malformed payload');
}
if ($event->event === 'customer_invoice.e_invoicing_status_updated') {
// handle $event->data
}
http_response_code(200);