{"id":503,"date":"2021-03-05T14:27:00","date_gmt":"2021-03-05T13:27:00","guid":{"rendered":"https:\/\/brentasoft.com\/blog\/webhook-cos-e-integrazioni-guida\/"},"modified":"2021-03-05T14:27:00","modified_gmt":"2021-03-05T13:27:00","slug":"webhook-cos-e-integrazioni-guida","status":"publish","type":"post","link":"https:\/\/brentasoft.com\/blog\/webhook-cos-e-integrazioni-guida\/","title":{"rendered":"Webhook: cos&#8217;\u00e8 e come usarli nelle integrazioni 2021"},"content":{"rendered":"<p><strong>Webhook cos&#8217;\u00e8?<\/strong> Se hai mai sentito parlare di &#8220;webhook&#8221; in una riunione tecnica, in una documentazione di Stripe o nelle impostazioni di Shopify e ti sei chiesto cosa significhi davvero, sei nel posto giusto. In questa guida 2021 vediamo, in modo chiaro e operativo, cos&#8217;\u00e8 un webhook, come funziona, in che cosa differisce dalle classiche API REST in polling, e come si usa nelle integrazioni reali tra ERP, CRM, e-commerce e gateway di pagamento.<\/p>\n<p>L&#8217;obiettivo \u00e8 duplice: dare agli IT manager e ai project manager le categorie giuste per parlare con i fornitori, e fornire ai developer junior una mappa concettuale solida prima di scrivere il primo ricevitore. Per chi vuole partire dalle basi delle API, consigliamo prima la lettura del nostro pillar dedicato alla <a href=\"https:\/\/brentasoft.com\/blog\/cos-e-una-api-rest-guida-non-sviluppatori\/\">guida alle API REST per non sviluppatori<\/a>: questo articolo ne \u00e8 il complemento naturale.<\/p>\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1880\" height=\"1058\" src=\"https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/webhook-flusso-dati.jpg\" alt=\"Flusso dati e connessioni di rete tra sistemi via webhook\" class=\"wp-image-505\" srcset=\"https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/webhook-flusso-dati.jpg 1880w, https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/webhook-flusso-dati-300x169.jpg 300w, https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/webhook-flusso-dati-1024x576.jpg 1024w, https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/webhook-flusso-dati-768x432.jpg 768w, https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/webhook-flusso-dati-1536x864.jpg 1536w\" sizes=\"(max-width: 1880px) 100vw, 1880px\" \/><figcaption>I webhook abilitano un flusso di dati event-driven tra sistemi distribuiti.<\/figcaption><\/figure>\n<h2>1. Webhook: cos&#8217;\u00e8 davvero (analogia &#8220;campanello vs chiamata&#8221;)<\/h2>\n<p>Il termine &#8220;webhook&#8221; nasce nel 2007 grazie a Jeff Lindsay, che lo introdusse per descrivere un meccanismo molto semplice: una callback HTTP. In pratica, un webhook \u00e8 un endpoint URL che tu pubblichi sul tuo server e che un sistema esterno (Stripe, Shopify, Slack, GitHub, HubSpot\u2026) chiama automaticamente quando accade un evento di interesse.<\/p>\n<p>L&#8217;analogia pi\u00f9 efficace \u00e8 quella del campanello di casa. Immagina di aspettare un pacco. Hai due opzioni:<\/p>\n<ul>\n<li><strong>Polling (chiamata)<\/strong>: ogni 5 minuti scendi in strada e chiedi al corriere se \u00e8 arrivato. Spreca tempo ed energia, soprattutto se il pacco arriver\u00e0 solo nel pomeriggio.<\/li>\n<li><strong>Webhook (campanello)<\/strong>: lasci il citofono pronto. Quando il corriere arriva, suona. Tu rispondi solo quando serve.<\/li>\n<\/ul>\n<p>Il webhook \u00e8 esattamente questo: un meccanismo &#8220;push&#8221; event-driven. Il sistema sorgente dice &#8220;appena succede X, ti avviso io chiamando il tuo URL&#8221;. Tu non devi pi\u00f9 chiedere continuamente &#8220;\u00e8 successo qualcosa?&#8221;, ma reagire quando il messaggio arriva.<\/p>\n<p>Questo cambia profondamente l&#8217;architettura delle integrazioni. Invece di costruire processi schedulati che ogni ora interrogano l&#8217;API di Shopify per scaricare nuovi ordini, registri un webhook su <code>orders\/create<\/code> e ricevi l&#8217;ordine nel momento esatto in cui il cliente conclude il checkout. Il delta in termini di tempo, banda e affidabilit\u00e0 \u00e8 enorme.<\/p>\n<h2>2. Webhook vs API REST polling: differenza fondamentale<\/h2>\n<p>Capire <strong>webhook vs API<\/strong> \u00e8 il primo passo per progettare integrazioni sane. In realt\u00e0 i due concetti non sono in contrapposizione: un webhook \u00e8 una chiamata HTTP, e quasi sempre i sistemi che inviano webhook offrono anche API REST tradizionali. La differenza non \u00e8 &#8220;tecnologica&#8221;, ma di direzione e di ingaggio.<\/p>\n<table>\n<thead>\n<tr>\n<th>Aspetto<\/th>\n<th>API REST (polling)<\/th>\n<th>Webhook (push)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Chi inizia la chiamata<\/td>\n<td>Il client (tu)<\/td>\n<td>Il sistema sorgente (es. Stripe)<\/td>\n<\/tr>\n<tr>\n<td>Quando avviene<\/td>\n<td>Periodicamente (es. ogni 5 min)<\/td>\n<td>Al momento dell&#8217;evento<\/td>\n<\/tr>\n<tr>\n<td>Ritardo medio<\/td>\n<td>Da pochi secondi a decine di minuti<\/td>\n<td>Quasi tempo reale (millisecondi)<\/td>\n<\/tr>\n<tr>\n<td>Carico<\/td>\n<td>Alto: tante chiamate spesso a vuoto<\/td>\n<td>Basso: solo eventi reali<\/td>\n<\/tr>\n<tr>\n<td>Configurazione<\/td>\n<td>Solo client<\/td>\n<td>Server pubblico + URL accessibile<\/td>\n<\/tr>\n<tr>\n<td>Affidabilit\u00e0<\/td>\n<td>Tu controlli i retry<\/td>\n<td>Il provider gestisce i retry<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Detto questo, anche nel 2021 il polling resta utile in due scenari: quando il sistema sorgente non offre webhook (succede ancora con molti gestionali italiani), e quando devi fare reconciliation periodica per recuperare eventi persi (esempio: ogni notte scarichi tutti gli ordini delle ultime 48 ore per essere sicuro di non aver perso nulla).<\/p>\n<p>La regola d&#8217;oro \u00e8: <strong>webhook per la reattivit\u00e0, polling per la consistenza<\/strong>. Un&#8217;integrazione robusta tipicamente li combina entrambi.<\/p>\n<h2>3. Come funziona tecnicamente un webhook<\/h2>\n<p>Tecnicamente, un webhook \u00e8 una banale richiesta HTTP, di solito <code>POST<\/code>, verso un URL che tu hai dichiarato al provider. Il flusso \u00e8 questo:<\/p>\n<ol>\n<li>Tu pubblichi un endpoint, ad esempio <code>https:\/\/app.tuodominio.it\/webhooks\/stripe<\/code>.<\/li>\n<li>Vai nel pannello del provider (Stripe, Shopify, GitHub\u2026) e registri quell&#8217;URL, scegliendo a quali eventi iscriverti (es. <code>checkout.session.completed<\/code>).<\/li>\n<li>Quando l&#8217;evento si verifica, il provider esegue una richiesta <code>POST<\/code> verso il tuo URL, includendo nel body un payload JSON con i dati dell&#8217;evento.<\/li>\n<li>Il tuo server elabora il payload e risponde con un codice <code>2xx<\/code> (tipicamente <code>200 OK<\/code> o <code>204 No Content<\/code>) per confermare la ricezione.<\/li>\n<li>Se rispondi con un errore <code>5xx<\/code> o vai in timeout, il provider riprover\u00e0 secondo la propria policy di retry.<\/li>\n<\/ol>\n<p>Un payload tipico, semplificato, ha questa forma:<\/p>\n<pre><code>POST \/webhooks\/stripe HTTP\/1.1\nHost: app.tuodominio.it\nContent-Type: application\/json\nStripe-Signature: t=1614950820,v1=5257a869e7...\n\n{\n  \"id\": \"evt_1ICwS62eZvKYlo2C...\",\n  \"type\": \"checkout.session.completed\",\n  \"created\": 1614950820,\n  \"data\": {\n    \"object\": {\n      \"id\": \"cs_test_a1B2c3...\",\n      \"amount_total\": 4990,\n      \"currency\": \"eur\",\n      \"customer_email\": \"mario.rossi@example.it\"\n    }\n  }\n}<\/code><\/pre>\n<p>Da questo si capisce un punto cruciale: <strong>chi riceve il webhook deve avere un endpoint HTTPS pubblico e raggiungibile<\/strong>. Non puoi ricevere webhook su un server che sta dietro firewall o solo in rete locale, a meno di non usare tunnel come ngrok in fase di sviluppo.<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1880\" height=\"1253\" src=\"https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/team-sviluppo-webhook.jpg\" alt=\"Team di sviluppatori che implementa webhook su laptop\" class=\"wp-image-506\" srcset=\"https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/team-sviluppo-webhook.jpg 1880w, https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/team-sviluppo-webhook-300x200.jpg 300w, https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/team-sviluppo-webhook-1024x682.jpg 1024w, https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/team-sviluppo-webhook-768x512.jpg 768w, https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/team-sviluppo-webhook-1536x1024.jpg 1536w\" sizes=\"(max-width: 1880px) 100vw, 1880px\" \/><figcaption>Implementare webhook richiede coordinamento tra team back-end e operations.<\/figcaption><\/figure>\n<h2>4. Casi d&#8217;uso 2021: Stripe, Shopify, Slack, GitHub<\/h2>\n<p>I webhook nel 2021 sono diventati lo standard per integrare quasi qualsiasi servizio cloud. Vediamo i casi pi\u00f9 comuni che troviamo nei progetti di <a href=\"https:\/\/brentasoft.com\/soluzioni\/integrazione-api.php\">integrazione API<\/a> per PMI italiane.<\/p>\n<h3>Stripe: pagamenti e abbonamenti<\/h3>\n<p>Stripe \u00e8 il caso scuola. Quando un cliente completa un pagamento, Stripe invia un webhook <code>checkout.session.completed<\/code> al tuo server. Solo a quel punto puoi creare l&#8217;ordine nel tuo gestionale, generare la fattura, abilitare l&#8217;accesso al servizio. Affidarsi solo al redirect del browser \u00e8 rischioso (l&#8217;utente pu\u00f2 chiudere la pagina): il webhook \u00e8 la fonte di verit\u00e0.<\/p>\n<h3>Shopify: ordini e magazzino<\/h3>\n<p>Shopify offre webhook su <code>orders\/create<\/code>, <code>orders\/paid<\/code>, <code>products\/update<\/code>, <code>inventory_levels\/update<\/code>. Tipico utilizzo: quando arriva un ordine su Shopify, un webhook scarica i dati nel <a href=\"https:\/\/brentasoft.com\/soluzioni\/odoo-ecommerce.php\">modulo e-commerce Odoo<\/a> e crea automaticamente la commessa di spedizione. Quando il magazzino aggiorna le giacenze, un webhook in direzione opposta sincronizza le quantit\u00e0 sul sito.<\/p>\n<h3>Slack: notifiche operative<\/h3>\n<p>Gli &#8220;Incoming Webhook&#8221; di Slack permettono al tuo software di pubblicare messaggi in un canale. Esempio: ogni volta che il monitoring rileva un errore in produzione, un webhook posta automaticamente in <code>#alerts-erp<\/code>. Zero email, reazione immediata del team.<\/p>\n<h3>GitHub: CI\/CD e automazioni<\/h3>\n<p>Quando uno sviluppatore fa <code>git push<\/code>, GitHub invia un webhook al server di build (Jenkins, GitLab CI, CircleCI) che avvia automaticamente test e deploy. \u00c8 il cuore di qualsiasi pipeline DevOps moderna.<\/p>\n<h3>HubSpot, Mailchimp, Typeform<\/h3>\n<p>Ogni volta che un lead compila un form, un webhook pu\u00f2 inviare i dati direttamente al CRM aziendale, marcando il contatto come &#8220;interessato&#8221; e attivando la sequenza commerciale. Questa \u00e8 la base dell&#8217;<a href=\"https:\/\/brentasoft.com\/soluzioni\/automazione.php\">automazione dei processi<\/a> commerciali.<\/p>\n<h2>5. Sicurezza dei webhook: HMAC signature e timestamp<\/h2>\n<p>Pubblicare un endpoint sul web significa esporlo al mondo. Chiunque pu\u00f2 inviarti una <code>POST<\/code> finta che sembra venire da Stripe. Senza protezioni, un attaccante potrebbe forgiare un payload &#8220;pagamento confermato&#8221; e farti spedire un prodotto mai pagato. Per questo i webhook seri usano la <strong>firma HMAC<\/strong>.<\/p>\n<p>Il meccanismo \u00e8 elegante:<\/p>\n<ol>\n<li>Provider e ricevente condividono un <em>secret<\/em> generato in fase di setup (mai trasmesso nel payload).<\/li>\n<li>Il provider calcola un hash HMAC-SHA256 del body (spesso concatenato a un timestamp) usando il secret come chiave.<\/li>\n<li>Lo trasmette in un header (es. <code>Stripe-Signature<\/code>, <code>X-Hub-Signature-256<\/code> per GitHub).<\/li>\n<li>Il ricevente ricalcola lo stesso HMAC con il proprio secret e lo confronta con l&#8217;header. Se coincidono, il payload \u00e8 autentico.<\/li>\n<\/ol>\n<p>Inoltre molte implementazioni includono un <strong>timestamp<\/strong> nel calcolo: il ricevente accetta solo richieste con timestamp recenti (es. ultimi 5 minuti) per prevenire i <em>replay attack<\/em>, ovvero tentativi di rispedire una richiesta legittima catturata in passato.<\/p>\n<p>Buone pratiche aggiuntive nel 2021:<\/p>\n<ul>\n<li>Endpoint sempre su <strong>HTTPS<\/strong> con certificato valido (Let&#8217;s Encrypt \u00e8 gratuito, non ci sono scuse).<\/li>\n<li>Secret diversi per ogni provider, custoditi in variabili d&#8217;ambiente, mai committati in git.<\/li>\n<li>Confronto delle firme con funzioni <em>constant-time<\/em> (es. <code>hash_equals<\/code> in PHP) per evitare timing attack.<\/li>\n<li>Logging di tutti i webhook ricevuti, validati e rifiutati, per audit e debugging.<\/li>\n<li>Rate limiting sull&#8217;endpoint per mitigare flood.<\/li>\n<\/ul>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1880\" height=\"1255\" src=\"https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/sicurezza-hmac-webhook.jpg\" alt=\"Sicurezza informatica e firma HMAC per autenticazione webhook\" class=\"wp-image-507\" srcset=\"https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/sicurezza-hmac-webhook.jpg 1880w, https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/sicurezza-hmac-webhook-300x200.jpg 300w, https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/sicurezza-hmac-webhook-1024x684.jpg 1024w, https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/sicurezza-hmac-webhook-768x513.jpg 768w, https:\/\/brentasoft.com\/blog\/wp-content\/uploads\/2021\/03\/sicurezza-hmac-webhook-1536x1025.jpg 1536w\" sizes=\"(max-width: 1880px) 100vw, 1880px\" \/><figcaption>La firma HMAC garantisce l autenticita del payload webhook.<\/figcaption><\/figure>\n<h2>6. Come implementare il ricevitore di un webhook<\/h2>\n<p>Vediamo a livello concettuale come si scrive un ricevitore di webhook nei tre stack pi\u00f9 diffusi nel 2021. Non sono esempi pronti per la produzione, ma servono a fissare la struttura mentale.<\/p>\n<h3>PHP \/ Laravel<\/h3>\n<pre><code>\/\/ routes\/api.php\nRoute::post('\/webhooks\/stripe', [StripeWebhookController::class, 'handle']);\n\n\/\/ app\/Http\/Controllers\/StripeWebhookController.php\npublic function handle(Request $request) {\n    $payload = $request->getContent();\n    $signature = $request->header('Stripe-Signature');\n    $secret = env('STRIPE_WEBHOOK_SECRET');\n\n    if (!$this->verifySignature($payload, $signature, $secret)) {\n        return response('Invalid signature', 401);\n    }\n\n    $event = json_decode($payload, true);\n    \/\/ dispatch su queue per non bloccare il provider\n    ProcessStripeEvent::dispatch($event);\n\n    return response('', 200);\n}<\/code><\/pre>\n<h3>Node.js \/ Express<\/h3>\n<pre><code>app.post('\/webhooks\/stripe',\n  express.raw({ type: 'application\/json' }),\n  (req, res) => {\n    const sig = req.headers['stripe-signature'];\n    let event;\n    try {\n      event = stripe.webhooks.constructEvent(\n        req.body, sig, process.env.STRIPE_WEBHOOK_SECRET\n      );\n    } catch (err) {\n      return res.status(400).send(`Webhook Error: ${err.message}`);\n    }\n    queue.add('stripe-event', event);\n    res.json({ received: true });\n  }\n);<\/code><\/pre>\n<h3>Python \/ FastAPI<\/h3>\n<pre><code>@app.post(\"\/webhooks\/stripe\")\nasync def stripe_webhook(request: Request):\n    payload = await request.body()\n    sig = request.headers.get(\"stripe-signature\")\n    try:\n        event = stripe.Webhook.construct_event(\n            payload, sig, settings.STRIPE_WEBHOOK_SECRET\n        )\n    except stripe.error.SignatureVerificationError:\n        raise HTTPException(401, \"Invalid signature\")\n\n    background_tasks.add_task(process_event, event)\n    return {\"received\": True}<\/code><\/pre>\n<p>Il pattern \u00e8 sempre lo stesso: <strong>verifica la firma, accoda l&#8217;elaborazione, rispondi 200 il prima possibile<\/strong>. Mai fare lavoro pesante (query lente, chiamate ad altre API, invio email) nel ciclo di richiesta del webhook. La maggior parte dei provider ha timeout di 5-30 secondi: se ci metti di pi\u00f9, ti rispediranno la stessa richiesta.<\/p>\n<h2>7. Gestione retry: cosa fare se il ricevitore \u00e8 gi\u00f9<\/h2>\n<p>Cosa succede se il tuo server \u00e8 offline al momento del webhook? Tutti i provider seri implementano una policy di retry. Ecco le strategie tipiche nel 2021:<\/p>\n<ul>\n<li><strong>Stripe<\/strong>: retry per 3 giorni con backoff esponenziale. Smette dopo molti tentativi falliti e marca l&#8217;evento come &#8220;failed&#8221; nel pannello.<\/li>\n<li><strong>Shopify<\/strong>: retry per 48 ore, fino a 19 tentativi. Disattiva l&#8217;endpoint dopo 19 fallimenti consecutivi.<\/li>\n<li><strong>GitHub<\/strong>: retry minimi (8 tentativi nelle prime 8 ore). Conta sulla pagina &#8220;Recent Deliveries&#8221; per il rinvio manuale.<\/li>\n<li><strong>HubSpot<\/strong>: retry fino a 24 ore con backoff.<\/li>\n<\/ul>\n<p>Per il ricevente questo significa che <strong>non puoi presumere che ogni evento arrivi una sola volta<\/strong>. Devi progettare l&#8217;integrazione assumendo che lo stesso webhook possa arrivare due, tre, dieci volte. Da qui la necessit\u00e0 dell&#8217;idempotenza.<\/p>\n<p>Inoltre conviene sempre integrare un meccanismo di <em>fallback<\/em> via polling: una volta al giorno scarichi gli ordini delle ultime 48 ore via API REST e verifichi che siano tutti gi\u00e0 nel tuo sistema. Se ne manca qualcuno (perch\u00e9 il webhook \u00e8 andato perso definitivamente), lo recuperi a posteriori. Questo schema \u00e8 particolarmente importante per le integrazioni con <a href=\"https:\/\/brentasoft.com\/soluzioni\/web-app-pwa.php\">web app e PWA<\/a> business critical.<\/p>\n<h2>8. Idempotenza: perch\u00e9 conta nei webhook<\/h2>\n<p>Un&#8217;operazione \u00e8 <strong>idempotente<\/strong> quando eseguirla N volte produce lo stesso risultato di eseguirla una volta sola. Nei webhook l&#8217;idempotenza non \u00e8 un nice-to-have, \u00e8 il bug fix pi\u00f9 importante che puoi prevenire.<\/p>\n<p>Esempio concreto: arriva il webhook <code>order.paid<\/code> di Stripe. Il tuo handler crea l&#8217;ordine nel gestionale, manda la fattura via email, addebita il magazzino. Tutto bello. Ma il provider, per un timeout di rete, rispedisce lo stesso evento. Il tuo server riceve di nuovo <code>order.paid<\/code> e, se non sei idempotente, crea un secondo ordine, manda una seconda fattura, scarica un secondo pezzo dal magazzino. Disastro.<\/p>\n<p>Le strategie 2021 per garantire idempotenza:<\/p>\n<ul>\n<li><strong>Event ID univoco<\/strong>: ogni provider include un ID dell&#8217;evento (es. <code>evt_1ICwS6...<\/code> in Stripe). Salvi questi ID in una tabella e ignori gli eventi gi\u00e0 processati.<\/li>\n<li><strong>Lock applicativo<\/strong>: prima di elaborare l&#8217;evento, prendi un lock su <code>event_id<\/code> (in Redis o in DB) e lo rilasci a fine processing.<\/li>\n<li><strong>Operazioni naturalmente idempotenti<\/strong>: se devi solo &#8220;settare lo stato dell&#8217;ordine a PAGATO&#8221;, farlo due volte non cambia nulla. Il problema esiste invece su INSERT, send email, accrediti.<\/li>\n<li><strong>Transazioni atomiche<\/strong>: wrappa &#8220;marca evento come processato&#8221; e &#8220;applica il side effect&#8221; in un&#8217;unica transazione DB.<\/li>\n<\/ul>\n<h2>9. Webhook nelle integrazioni e-commerce, gestionale, CRM<\/h2>\n<p>Nei progetti reali raramente costruiamo un&#8217;integrazione webhook isolata: quasi sempre fa parte di un flusso multi-sistema. Vediamo tre scenari ricorrenti per le PMI italiane nel 2021.<\/p>\n<h3>E-commerce \u2192 ERP<\/h3>\n<p>Cliente compra su Shopify\/WooCommerce \u2192 webhook al middleware \u2192 middleware crea l&#8217;ordine in Odoo\/SAP\/gestionale custom \u2192 ERP genera DDT, fattura elettronica via SDI, prepara la spedizione. Sul ritorno: ERP emette webhook (o evento interno) verso il sito per aggiornare lo stato a &#8220;spedito&#8221; e inviare il tracking al cliente.<\/p>\n<h3>Form lead \u2192 CRM \u2192 Marketing automation<\/h3>\n<p>Utente compila form su sito (Typeform, Gravity Forms, custom) \u2192 webhook a HubSpot\/Mailchimp \u2192 CRM crea\/aggiorna il contatto \u2192 trigger sequenza email + notifica Slack al commerciale. Il tutto in 1-2 secondi, senza intervento umano.<\/p>\n<h3>Pagamento ricorrente \u2192 Servizio<\/h3>\n<p>SaaS in abbonamento: Stripe Subscriptions invia webhook <code>invoice.paid<\/code> ogni mese \u2192 backend prolunga la validit\u00e0 dell&#8217;account. Quando arriva <code>invoice.payment_failed<\/code>, parte una sequenza di dunning (email di sollecito) e dopo N tentativi falliti il servizio viene sospeso.<\/p>\n<p>In tutti questi casi il middleware (proprietario o in cloud, vedi sezione successiva) fa da &#8220;centralino&#8221; e disaccoppia i sistemi: se Shopify cambia il formato dei suoi webhook, modifichi solo il middleware, non l&#8217;ERP.<\/p>\n<h2>10. Strumenti per testare webhook nel 2021<\/h2>\n<p>Sviluppare e debuggare integrazioni webhook \u00e8 notoriamente fastidioso, perch\u00e9 il tuo localhost non \u00e8 raggiungibile dal mondo esterno. Per fortuna nel 2021 abbiamo strumenti maturi:<\/p>\n<ul>\n<li><strong>Webhook.site<\/strong>: il modo pi\u00f9 rapido per ispezionare cosa invia un provider. Ti d\u00e0 un URL temporaneo e mostra in tempo reale ogni richiesta che lo colpisce, con headers, body, query string. Perfetto per &#8220;vedere com&#8217;\u00e8 fatto&#8221; un webhook prima di scrivere il codice.<\/li>\n<li><strong>ngrok<\/strong>: crea un tunnel HTTPS pubblico verso il tuo localhost (es. <code>https:\/\/abc123.ngrok.io<\/code> \u2192 <code>localhost:8000<\/code>). Configuri Stripe\/Shopify per chiamare l&#8217;URL ngrok e debugghi in locale come se fossi in produzione.<\/li>\n<li><strong>Stripe CLI<\/strong>: il comando <code>stripe listen --forward-to localhost:8000\/webhooks\/stripe<\/code> simula i webhook in locale senza nemmeno bisogno di ngrok. Esiste anche <code>stripe trigger checkout.session.completed<\/code> per generare eventi a comando.<\/li>\n<li><strong>Postman<\/strong>: per inviare a mano richieste POST al tuo endpoint con payload personalizzati, utile per testare i casi limite e gli errori.<\/li>\n<li><strong>Zapier \/ Integromat<\/strong>: piattaforme low-code che permettono di costruire integrazioni webhook senza scrivere codice. Hanno limiti (cost per task, latenza), ma sono un ottimo prototipo. Nota: nel 2021 si chiama ancora <em>Integromat<\/em>, il rebrand in Make arriver\u00e0 nel 2022.<\/li>\n<li><strong>n8n<\/strong>: alternativa open source self-hosted a Zapier, ottima quando i dati non possono uscire dall&#8217;azienda.<\/li>\n<\/ul>\n<h2>11. Errori comuni nelle implementazioni webhook<\/h2>\n<p>Negli anni abbiamo visto i seguenti errori ricorrenti, dai progetti pi\u00f9 semplici a quelli enterprise:<\/p>\n<ol>\n<li><strong>Non verificare la firma HMAC<\/strong>: l&#8217;endpoint accetta qualsiasi payload, esponendosi a frode.<\/li>\n<li><strong>Elaborare in modo sincrono operazioni lente<\/strong>: chiamate ad altre API, invio email, generazione PDF. Risultato: timeout, retry infiniti, payload duplicati.<\/li>\n<li><strong>Non gestire l&#8217;idempotenza<\/strong>: ordini doppi, fatture doppie, email doppie quando un retry arriva.<\/li>\n<li><strong>Rispondere con codici di errore per logiche applicative<\/strong>: se l&#8217;ordine &#8220;esiste gi\u00e0&#8221;, non rispondere 500. Rispondi 200 (l&#8217;evento l&#8217;hai ricevuto correttamente, semplicemente non c&#8217;era nulla da fare).<\/li>\n<li><strong>Mancanza di logging<\/strong>: quando qualcosa non funziona, senza log dettagliati il debug \u00e8 un incubo.<\/li>\n<li><strong>Endpoint dietro autenticazione standard (Basic Auth, sessione)<\/strong>: il provider non ha modo di autenticarsi nel modo che ti aspetti. Usa solo HMAC o IP allowlist.<\/li>\n<li><strong>Hardcoding del secret nel codice<\/strong>: deve stare in <code>.env<\/code>, mai in git.<\/li>\n<li><strong>Nessun monitoring<\/strong>: se i webhook smettono di arrivare per un&#8217;ora, te ne accorgi solo quando il cliente chiama arrabbiato. Implementa health check + alert.<\/li>\n<li><strong>Mancanza di reconciliation<\/strong>: dopo un downtime di 2 ore, alcuni eventi sono andati persi per sempre. Senza un job notturno di riconciliazione via API, hai dati mancanti.<\/li>\n<\/ol>\n<h2>12. Domande frequenti sui webhook<\/h2>\n<h3>Webhook e API REST sono la stessa cosa?<\/h3>\n<p>No, ma sono complementari. Un webhook \u00e8 una chiamata HTTP <em>in entrata<\/em> verso il tuo server, fatta dal provider quando accade un evento. Un&#8217;API REST \u00e8 una chiamata HTTP <em>in uscita<\/em> dal tuo server, fatta da te quando vuoi leggere o scrivere dati. Stripe, Shopify, GitHub espongono entrambe.<\/p>\n<h3>Posso ricevere webhook senza un server pubblico?<\/h3>\n<p>In sviluppo s\u00ec, usando ngrok o servizi simili che tunnellano il traffico dal cloud al tuo localhost. In produzione hai bisogno di un server con IP pubblico e dominio HTTPS valido. Soluzioni serverless come AWS Lambda + API Gateway o Cloudflare Workers funzionano benissimo come ricevitori, anche per piccoli volumi a costo quasi zero.<\/p>\n<h3>Quanti webhook posso ricevere al secondo?<\/h3>\n<p>Dipende dall&#8217;infrastruttura. Un&#8217;app PHP\/Laravel su un VPS modesto regge tranquillamente 50-100 webhook al secondo se l&#8217;handler accoda subito su Redis\/RabbitMQ e risponde 200. Se invece processa tutto sincrono, il limite scende drasticamente. La regola: <em>thin handler, fat worker<\/em>.<\/p>\n<h3>Cosa fare se perdo un webhook?<\/h3>\n<p>I provider conservano gli eventi per giorni o settimane. Stripe e Shopify hanno una pagina &#8220;Webhook deliveries&#8221; da cui puoi rinviare manualmente un evento. Per i casi sistematici, implementa un job di reconciliation che ogni notte scarichi via API gli eventi delle ultime 48 ore e verifichi la sincronia con il tuo database.<\/p>\n<h3>Posso usare Zapier al posto di scrivere codice?<\/h3>\n<p>S\u00ec, per integrazioni semplici a basso volume Zapier (e n8n self-hosted) \u00e8 perfetto. I limiti emergono quando: (a) il volume mensile supera i piani gratuiti, (b) servono trasformazioni dati complesse, (c) la latenza diventa critica, (d) non puoi inviare i dati a un servizio terzo per ragioni GDPR. In quei casi serve codice custom.<\/p>\n<h3>I webhook funzionano con Telegram, WhatsApp, email?<\/h3>\n<p>Telegram Bot API supporta webhook nativamente (puoi ricevere ogni messaggio inviato al bot via POST). WhatsApp Business API anche, ma richiede approvazione Meta. Le email no: sono push, ma usano SMTP\/IMAP, non webhook HTTP. Servizi come SendGrid e Mailgun emettono per\u00f2 webhook su eventi correlati (delivered, bounced, opened).<\/p>\n<h3>Per approfondire<\/h3>\n<p>Riferimento concettuale su <a href=\"https:\/\/it.wikipedia.org\/wiki\/Webhook\" target=\"_blank\" rel=\"nofollow noopener\">Wikipedia (Webhook)<\/a> e documentazione operativa lato provider: <a href=\"https:\/\/stripe.com\/docs\/webhooks\" target=\"_blank\" rel=\"nofollow noopener\">Stripe Webhooks<\/a>.<\/p>\n<div style=\"background:#f5f7fa;border-left:4px solid #0066cc;padding:20px;margin:30px 0;border-radius:4px;\">\n<h3 style=\"margin-top:0;\">Devi integrare sistemi via webhook?<\/h3>\n<p>Brentasoft sviluppa integrazioni custom con webhook tra ERP, CRM, e-commerce, gateway pagamento e servizi terzi per PMI italiane: ricevitori sicuri, retry, idempotenza e monitoring.<\/p>\n<p style=\"margin-bottom:0;\"><a href=\"https:\/\/brentasoft.com\/erp-brenta.php\" style=\"display:inline-block;background:#0066cc;color:#fff;padding:12px 24px;border-radius:4px;text-decoration:none;font-weight:600;\">Scopri ERP Brenta &rarr;<\/a><\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Webhook cos&#8217;\u00e8? Guida 2021: differenze con API REST, esempi Stripe Shopify GitHub, sicurezza HMAC, idempotenza e strumenti per testare integrazioni.<\/p>\n","protected":false},"author":2,"featured_media":504,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"","_seopress_titles_title":"Webhook: cos'\u00e8 e come usarli nelle integrazioni 2021","_seopress_titles_desc":"Webhook cos'\u00e8? Guida 2021 con esempi Stripe, Shopify, GitHub. Differenze API REST polling, sicurezza HMAC, idempotenza e strumenti per testare.","_seopress_robots_index":"","footnotes":""},"categories":[9],"tags":[61,224,223,57,225,94,66,226],"class_list":["post-503","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-guide-e-tutorial","tag-api","tag-hmac","tag-integrazione","tag-shopify","tag-stripe","tag-sviluppo-software","tag-webhook","tag-zapier"],"_links":{"self":[{"href":"https:\/\/brentasoft.com\/blog\/wp-json\/wp\/v2\/posts\/503","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/brentasoft.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/brentasoft.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/brentasoft.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/brentasoft.com\/blog\/wp-json\/wp\/v2\/comments?post=503"}],"version-history":[{"count":0,"href":"https:\/\/brentasoft.com\/blog\/wp-json\/wp\/v2\/posts\/503\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/brentasoft.com\/blog\/wp-json\/wp\/v2\/media\/504"}],"wp:attachment":[{"href":"https:\/\/brentasoft.com\/blog\/wp-json\/wp\/v2\/media?parent=503"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/brentasoft.com\/blog\/wp-json\/wp\/v2\/categories?post=503"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/brentasoft.com\/blog\/wp-json\/wp\/v2\/tags?post=503"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}