Webhook di Applicazione
I webhook di applicazione sono chiamate HTTP che Riseact invia al tuo endpoint quando avvengono certi eventi in tutte le organizzazioni che hanno installato la tua applicazione.
A differenza dei webhook di organizzazione, li registri una sola volta sulla partner app. Ogni chiamata indica il dominio dell'organizzazione che ha generato l'evento.
Impostare un webhook
- Nel portale partner apri Apps e seleziona la tua applicazione.
- Apri la scheda Webhooks e clicca Add Webhook.
- Scegli gli eventi e inserisci l'URL HTTPS che riceverà le chiamate
POST. - Salva.
Dalla stessa scheda modifichi o elimini i webhook registrati.
Eventi disponibili
| Evento | Descrizione |
|---|---|
supporter.created | Un nuovo sostenitore è stato creato |
supporter.updated | Un sostenitore è stato aggiornato |
supporter.deleted | Un sostenitore è stato eliminato |
checkout.created | Un nuovo checkout è stato aperto |
checkout.updated | Un checkout è stato aggiornato |
checkout.paid | Un checkout è stato completato con pagamento |
checkout.closed | Un checkout è stato chiuso |
donation.created | Una nuova donazione è stata creata |
donation.updated | Una donazione è stata aggiornata |
donation.deleted | Una donazione è stata eliminata |
donation.revoked | Una donazione è stata revocata: a mano, per il rimborso del suo ultimo pagamento o per il pagamento fallito di una donazione singola |
payment.created | Un nuovo pagamento è stato registrato |
payment.updated | Un pagamento è stato aggiornato |
campaign.created | Una nuova campagna è stata creata |
campaign.updated | Una campagna è stata aggiornata |
campaign.deleted | Una campagna è stata eliminata |
Consegna delle chiamate
Riseact invia una POST con Content-Type: application/json all'URL registrato. Il payload è lo stesso dei webhook di organizzazione:
organization: il dominio dell'organizzazione che ha generato l'evento, da usare per instradarlo;event: il topic dell'evento, per esempiodonation.created;object: l'oggetto interessato;idempotency_key: identificativo della chiamata. Può arrivare più volte la stessa chiave: usala per deduplicare.
Esempio (donation.created):
{
"organization": "org-che-ha-installato-app",
"object": {
"id": 229,
"code": "#1000",
"state": "pending",
"amount": 10,
"frequency": 0,
"campaign": 29,
"supporter": 75835,
"payment_method": "MANUAL"
},
"event": "donation.created",
"idempotency_key": "b1e0c9a2-4f3d-4e2a-9c1b-6a7f8d0e2c34"
}Gli esempi per gli altri oggetti sono nella pagina dei webhook di organizzazione.
- Il timeout è di 10 secondi: rispondi subito con
2xxed elabora in modo asincrono il lavoro pesante. - Se la risposta non è
2xx, o non arriva entro il timeout, Riseact ritenta la consegna dopo 1 minuto, 10 minuti, 1 ora, 6 ore e 24 ore, con lo stesso payload e la stessaidempotency_key. Un tentativo ripetuto può quindi arrivare dopo eventi più recenti dello stesso oggetto: confrontaupdate_datecon quello che hai salvato e scarta i payload superati. - Le chiamate sono firmate con il client secret dell'app: verifica sempre la firma prima di elaborare il payload (vedi Verifica della firma).
Verifica della firma
Le chiamate dei webhook registrati da un'app sono firmate con il client secret dell'app, così puoi verificare che arrivino da Riseact. Lo stesso vale per la chiamata di disinstallazione. La richiesta contiene due header:
X-Riseact-Timestamp: istante di invio, in secondi Unix.X-Riseact-Signature:v1=seguito dall'HMAC-SHA256, in esadecimale, della stringa<timestamp>.<corpo>.<corpo>sono i byte grezzi ricevuti, prima di qualunque parsing JSON.
Il prefisso v1= indica lo schema della firma. In futuro l'header potrà contenere più firme separate da virgola (per esempio durante la rotazione del secret): considera valida la richiesta se almeno una firma v1 corrisponde.
Per verificarla:
- Ricalcola l'HMAC con il client secret sui byte ricevuti e confrontalo con la firma usando un confronto a tempo costante.
- Rifiuta la richiesta se il timestamp si discosta di più di 5 minuti dall'ora corrente, e deduplica su
idempotency_key: insieme impediscono di riusare una chiamata intercettata.
Se usi l'SDK Node.js la verifica è già fatta per te. Altrimenti, in Node.js:
const crypto = require("crypto");
function verifyRiseactSignature(rawBody, headers, clientSecret) {
const timestamp = headers["x-riseact-timestamp"];
if (!timestamp || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = crypto
.createHmac("sha256", clientSecret)
.update(`${timestamp}.`)
.update(rawBody)
.digest();
return (headers["x-riseact-signature"] || "")
.split(",")
.map((part) => part.trim().split("="))
.some(([version, hex]) => {
if (version !== "v1" || !/^[0-9a-f]{64}$/.test(hex)) return false;
return crypto.timingSafeEqual(Buffer.from(hex, "hex"), expected);
});
}rawBody devono essere i byte ricevuti, non il JSON riserializzato: con Express usa l'opzione verify di express.json() per conservarli, oppure express.raw({ type: "application/json" }) sulla rotta del webhook.
I webhook registrati dal portale partner sono firmati. Quelli che un'app registra su una singola organizzazione tramite API, con il proprio token, sono firmati anch'essi. Un webhook creato prima dell'introduzione della firma resta non firmato finché l'app non lo aggiorna o lo registra di nuovo.
Disinstallazione dell'app
Quando un'organizzazione disinstalla la tua app, o viene eliminata, Riseact revoca i token dell'app e invia una POST firmata a un percorso fisso:
<app_url>/webhooks/app-uninstalled<app_url> è l'URL dell'app impostato nel portale partner. Non serve registrare nulla: la chiamata non compare tra i webhook dell'app e non si può disattivare. Usala per cancellare i dati e le credenziali che conservi per quell'organizzazione.
{
"organization": "org-che-ha-disinstallato",
"event": "app.uninstalled",
"object": {
"id": 42,
"client_id": "<client id della tua app>",
"organization": "org-che-ha-disinstallato",
"reason": "app_uninstalled",
"uninstalled_at": "2026-10-14T12:00:00.000000+00:00"
},
"idempotency_key": "6f1d2c3b-8a9e-4f70-b1c2-d3e4f5a6b7c8"
}reasonvaleapp_uninstalledse l'organizzazione ha disinstallato l'app,organization_deletedse l'organizzazione è stata eliminata.- Verifica sempre la firma prima di cancellare qualcosa.
- Rispondi
2xxsolo quando la cancellazione è riuscita, così in caso di errore Riseact ritenta come per gli altri webhook. - La chiamata può arrivare più volte, e la tua app potrebbe aver già cancellato i dati: gestiscila in modo idempotente.
- Quando la chiamata arriva i token sono già revocati, quindi non puoi più interrogare le API per quell'organizzazione.
- Le app private di un'organizzazione eliminata vengono eliminate con lei, e per loro la chiamata non viene inviata.
Con l'SDK Node.js il percorso è gestito dall'SDK: implementa auth.onUninstall per cancellare i dati, le credenziali vengono rimosse in automatico.
Registro degli eventi
La scheda Events dell'app elenca ogni tentativo di consegna, con organizzazione, evento, payload, stato HTTP (o errore di connessione) e corpo della risposta.
Una consegna fallita si può rilanciare a mano dal dettaglio dell'evento.
Differenza rispetto ai webhook di organizzazione
| Webhook di applicazione | Webhook di organizzazione | |
|---|---|---|
| Ambito | Tutte le org che installano l'app | Una sola organizzazione |
| Dove si registrano | Portale partner, scheda Webhooks | Admin dell'organizzazione, app privata |
| Chi li usa | Partner app di terze parti | Automazioni e integrazioni interne |
| Payload | Uguale (include organization) | Uguale (include organization) |
Fonte: https://dev.riseact.org/docs/partner-apps/application-webhooks. Copia automatica da dev.riseact.org: non modificare qui, le modifiche vanno fatte sulla documentazione Docusaurus.