Aller au contenu

Webhooks

Bêta

Les webhooks Pennylane sont en bêta. Pennylane recommande elle-même de conserver les endpoints changelog en solution de repli pendant que la fonctionnalité se stabilise. Types d'événements connus à ce jour : customer_invoice.e_invoicing_status_updated et dms_file.created.

S'abonner

subscription = client.webhook_subscriptions.create(
    callback_url="https://example.com/webhooks/pennylane",  # must be HTTPS
    events=["customer_invoice.e_invoicing_status_updated"],
)
print(subscription.secret)

Stockez le secret immédiatement

Le secret utilisé pour vérifier les livraisons n'est renvoyé qu'une seule fois, à la création. Stockez-le immédiatement dans votre gestionnaire de secrets ; vous ne pourrez plus le récupérer ensuite.

Gérez les abonnements avec list(), get(id), update(id, ...) et delete(id).

Recevoir et vérifier les livraisons

Pennylane signe les livraisons avec un HMAC du corps brut à l'aide de votre secret. Vérifiez avant de faire confiance :

from fastapi import FastAPI, Header, HTTPException, Request
from pennylane_sdk.webhooks import parse_event, WebhookSignatureError

app = FastAPI()
SECRET = "..."  # from your secret manager

@app.post("/webhooks/pennylane")
async def pennylane_webhook(request: Request, x_pennylane_signature: str = Header(None)):
    raw = await request.body()   # le corps BRUT, ne pas le re-sérialiser
    try:
        event = parse_event(raw, signature=x_pennylane_signature, secret=SECRET)
    except WebhookSignatureError:
        raise HTTPException(status_code=400, detail="bad signature")
    if event.event == "customer_invoice.e_invoicing_status_updated":
        ...
    return {"ok": True}

En-tête de signature

À la mi-2026, Pennylane ne documente pas encore précisément le nom ni l'encodage de l'en-tête de signature. verify_signature est volontairement tolérant : il accepte les encodages HMAC-SHA256 en hexadécimal comme en base64, avec ou sans préfixe sha256=, comparés en temps constant. Inspectez vos premières livraisons réelles pour confirmer l'en-tête (généralement X-Pennylane-Signature) et figez votre intégration en conséquence.

Vous pouvez aussi vérifier manuellement :

from pennylane_sdk.webhooks import verify_signature

is_valid = verify_signature(raw_body, signature_header, SECRET)

Repli : changelogs

Pour une synchronisation à livraison garantie, interrogez les endpoints changelog. Ils renvoient des événements de changement par ressource, paginés par curseur, ce qui rend triviale une boucle de synchronisation incrémentale :

for event in client.changelogs.customer_invoices():
    ...  # chaque événement référence la facture modifiée

Des changelogs existent pour les factures clients, les factures fournisseurs, les clients, les fournisseurs, les produits, les lignes d'écriture, les transactions et les devis.