Passa al contenuto principale

Webhook

I webhook permettono alla vostra applicazione di ricevere callback HTTP in tempo reale quando si verificano eventi nella vostra organizzazione Gäld. Quando un evento viene attivato, Gäld invia una richiesta POST a ogni URL webhook registrato.

Configurare un webhook

Create un webhook tramite l'API:

curl -X POST https://app.gaeld.ch/api/v1/webhooks \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/gaeld",
"events": ["invoice.created", "invoice.finalized", "customer.created"],
"is_active": true
}'

La risposta include un secretconservatelo in modo sicuro, vi servirà per verificare le firme.

Eventi

EventoSi attiva quando
invoice.createdViene creata una nuova fattura
invoice.updatedUna fattura viene modificata
invoice.deletedUna fattura viene eliminata
invoice.finalizedUna fattura viene finalizzata (bloccata per la modifica)
invoice.payment_recordedViene registrato un pagamento per una fattura
customer.createdViene creato un nuovo cliente
customer.updatedUn cliente viene modificato
customer.deletedUn cliente viene eliminato
expense.createdViene creata una nuova spesa
expense.updatedUna spesa viene modificata
expense.deletedUna spesa viene eliminata
expense.approvedUna spesa viene approvata nel workflow

Utilizzate GET /api/v1/meta/webhook-events per recuperare questo elenco programmaticamente.

Formato del payload

Ogni consegna webhook invia una richiesta JSON POST:

{
"event": "invoice.finalized",
"timestamp": "2025-06-01T12:00:00Z",
"data": {
"id": "uuid",
"number": "INV-2025-042",
"status": "finalized",
"customer": { "id": "uuid", "name": "ACME GmbH" },
"total": "1081.00",
"currency": "CHF"
}
}

Il campo data contiene la rappresentazione completa della risorsa (stesso formato della risposta dell'endpoint API corrispondente).

Header della richiesta

Ogni richiesta webhook include questi header:

HeaderDescrizione
Content-Typeapplication/json
X-Webhook-SignatureDigest HMAC-SHA256 esadecimale del corpo della richiesta
X-Webhook-EventNome dell'evento (ad es. invoice.created)
X-Webhook-IdID di consegna univoco
User-AgentGaeld-Webhook/1.0

Verifica della firma

Ogni richiesta webhook è firmata con HMAC-SHA256 utilizzando il secret del webhook. Verificate sempre la firma prima di elaborare il payload.

PHP

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';

$computed = hash_hmac('sha256', $payload, $webhookSecret);

if (! hash_equals($computed, $signature)) {
http_response_code(400);
exit('Invalid signature');
}

$event = json_decode($payload, true);
// Elaborare $event

Node.js

const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
const computed = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(computed),
Buffer.from(signature)
);
}

// Nel vostro handler Express:
app.post('/webhooks/gaeld', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-webhook-signature'];
if (!verifySignature(req.body, signature, process.env.WEBHOOK_SECRET)) {
return res.status(400).send('Invalid signature');
}
const event = JSON.parse(req.body);
// Elaborare l'evento
res.sendStatus(200);
});

Python

import hmac
import hashlib

def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
computed = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
return hmac.compare_digest(computed, signature)

Consegna e tentativi

ProprietàValore
Timeout HTTP10 secondi
Max tentativi3
Backoff dei tentativi30 secondi, 5 minuti, 1 ora
Risposta attesaQualsiasi codice di stato 2xx

Se il vostro endpoint restituisce uno stato non 2xx o va in timeout, Gäld riprova con backoff esponenziale. Dopo 3 tentativi falliti, la consegna viene contrassegnata come fallita. Potete verificare lo stato di consegna tramite l'API webhook.

Gestire i webhook

AzioneMetodoEndpoint
Elencare tuttiGET/api/v1/webhooks
Visualizzare dettagliGET/api/v1/webhooks/{id}
CrearePOST/api/v1/webhooks
Aggiornare eventi/URLPUT/api/v1/webhooks/{id}
EliminareDELETE/api/v1/webhooks/{id}
Rigenerare il secretPOST/api/v1/webhooks/{id}/regenerate-secret
Rotazione del secret

Dopo aver chiamato regenerate-secret, aggiornate immediatamente la vostra applicazione con il nuovo secret. Il vecchio secret viene invalidato e tutte le consegne successive utilizzeranno quello nuovo.

Best practice

  • Verificate sempre le firme — non fidatevi mai del contenuto del payload senza controllare la firma HMAC
  • Rispondete rapidamente — restituite immediatamente 200 ed elaborate l'evento in modo asincrono (ad es. tramite una coda di lavoro)
  • Gestite i duplicati — utilizzate l'header X-Webhook-Id per la deduplicazione se il vostro endpoint viene chiamato più di una volta
  • Utilizzate HTTPS — gli URL webhook devono utilizzare HTTPS in produzione
  • Monitorate gli errori — verificate periodicamente lo stato di consegna dei webhook e correggete gli endpoint non funzionanti