Aller au contenu

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);