Aller au contenu

Webhook helpers

See the webhooks guide for receiver examples.

Webhook signature verification and payload parsing.

Pennylane webhooks (beta) POST a JSON payload to your HTTPS endpoint when an event occurs. When you create a subscription (client.webhook_subscriptions.create), the response contains a secret returned only once: used to sign deliveries with an HMAC.

.. warning:: As of mid-2026 Pennylane documents the HMAC secret but NOT the exact signature header name or encoding. This module therefore verifies signatures defensively: it accepts hex or base64 encodings, with or without a sha256= prefix. Check your webhook deliveries to find the signature header (commonly X-Pennylane-Signature), and keep the changelog endpoints (client.changelogs) as a fallback while the feature is in beta, as Pennylane itself recommends.

Known event types: customer_invoice.e_invoicing_status_updated, dms_file.created.

WebhookSignatureError

Bases: PennylaneError

The webhook payload signature could not be verified.

WebhookEvent

Bases: PennylaneModel

A webhook delivery payload.

Unknown fields are preserved (extra="allow"): inspect raw or the model's extra attributes for event-specific data.

event class-attribute instance-attribute

event: str | None = None

Event type, e.g. customer_invoice.e_invoicing_status_updated.

data class-attribute instance-attribute

data: dict[str, Any] | None = None

Event payload, when the delivery wraps it in a data object.

verify_signature

verify_signature(
    payload: bytes | str, signature: str, secret: str
) -> bool

Check a webhook delivery signature (constant-time comparison).

Parameters:

Name Type Description Default
payload bytes | str

The RAW request body, exactly as received (bytes preferred re-serializing the JSON would change the bytes and the HMAC).

required
signature str

Value of the signature header of the delivery.

required
secret str

The subscription secret returned at creation time.

required

Returns:

Type Description
bool

True when the signature matches the HMAC-SHA256 of the payload,

bool

trying hex and base64 encodings, with or without a sha256= prefix.

parse_event

parse_event(
    payload: bytes | str,
    *,
    signature: str | None = None,
    secret: str | None = None,
) -> WebhookEvent

Parse a webhook delivery, optionally verifying its signature first.

Parameters:

Name Type Description Default
payload bytes | str

The raw request body.

required
signature str | None

Signature header value; verified when secret is given.

None
secret str | None

Subscription secret. When provided together with signature, the payload is verified before parsing and a :class:WebhookSignatureError is raised on mismatch.

None

Raises:

Type Description
WebhookSignatureError

When verification was requested and failed.

PennylaneError

When the payload is not valid JSON.