---
title: "Webhooky sa opakujú. Vaša integrácia s tým musí rátať."
description: "Platobné a platformové webhooky sa v okne na opakovanie doručujú aspoň raz, nie presne raz. Čo dvojité doručenie pokazí a ako ho idempotentné handlery absorbujú."
author: "Luboš Zápotočný"
published: "2026-06-17"
language: "sk"
canonical: "https://zapolu.com/sk/blog/webhooky-sa-opakuju/"
---

# Webhooky sa opakujú. Vaša integrácia s tým musí rátať.

Prečítajte si dokumentáciu webhookov ktoréhokoľvek seriózneho
poskytovateľa (Stripe, Shopify, Adyen, GoPay) a nájdete v tej či
onej podobe to isté varovanie: doručenia môžu nastať viac než raz.
V rámci okna na opakovanie je kontrakt *at-least-once*, nie
*exactly-once*; ak váš endpoint zostane celé okno nedostupný,
udalosť nepríde ani raz, a preto je pod všetkým ostatným záchytnou
poistkou rekonciliačná úloha, ktorá si stav doťahuje z API
poskytovateľa. Exactly-once doručenie cez nespoľahlivú sieť sa
zaručiť nedá, takže poskytovatelia robia rozumnú vec: keď si nie sú
istí, či ste udalosť dostali, pošlú ju znova.

Väčšina integrácií je napísaná, akoby tá klauzula neexistovala.
Fungujú v deme, fungujú prvý mesiac, a potom niekde medzi
poskytovateľom a odpoveďou 200 nastane timeout a tá istá udalosť
`order.paid` príde dvakrát.

## Čo dvojité doručenie naozaj pokazí

- Zákazník dostane dve potvrdenia objednávky.
- Zásoby sa odpočítajú dvakrát a vzniká fantómové „vypredané“.
- Faktúra sa vystaví dvakrát a nezrovnalosť sa objaví pri účtovnej
  uzávierke.
- Vernostný kredit sa pripíše dvakrát a čísla prestanú sedieť.

Nič z toho pritom nie je chyba poskytovateľa; ten urobil presne to,
čo má v dokumentácii. Chyba je v handleri, ktorý sa spoliehal na
sľub, ktorý nikto nedal.

## Riešením je idempotencia

Idempotentný handler vyprodukuje rovnaký koncový stav bez ohľadu na
to, či udalosť spracuje raz alebo päťkrát. Táto jediná vlastnosť
absorbuje opakovania, manuálne replaye a celú triedu race
conditions. Dosiahnuť ju je predovšetkým otázka disciplíny:

1. **Každej udalosti kľúč.** Poskytovatelia posielajú ID udalosti; ak
   ho ten váš neposiela, odvoďte si ho zo stabilných polí. Spracované ID si
   zaznamenajte a duplikáty preskočte. Vynucujte to unique
   constraintom v databáze: kontrola „už som to videl?“ v aplikačnom
   kóde má race window, constraint nemá.
2. **Uprednostnite absolútny stav pred relatívnymi zmenami.** „Nastav
   status na zaplatené“ je prirodzene idempotentné. „Odpočítaj zo
   zásob 2“ nie je. Keď poskytovateľ posiela delty, prekladajte ich
   na upserty proti vlastnému záznamu udalosti, nie na slepú
   aritmetiku.
3. **Rátajte aj s prehodeným poradím.** Opakovania prichádzajú aj
   mimo poradia; `order.updated` môže doraziť pred `order.created`.
   Verzie alebo časové pečiatky na cieľovom zázname („aplikuj, iba ak
   je novšie“) zvládnu to, čo predpoklady o poradí nezvládnu.

## Zvyšok checklistu

Idempotencia je jadro; tri návyky okolo nej oddeľujú integrácie,
ktoré prežijú produkciu, od tých, ktoré generujú tickety:

- **Potvrďte rýchlo, spracujte asynchrónne.** Overte podpis, udalosť
  uložte, vráťte 200 a skutočnú prácu robte z fronty. Pomalé
  synchrónne handlery spôsobujú timeouty a timeouty spúšťajú ďalšie
  opakovania.
- **Autentifikujte každý webhook.** Webhook endpoint je
  neautentifikovaná URL na verejnom internete, ktorá mení stav vášho
  biznisu. Väčšina poskytovateľov podpíše payload pomocou HMAC, ktorý
  si prepočítate a porovnáte; niektorí (GoPay) vám dajú len ID
  a očakávajú, že si smerodajný stav znova stiahnete z ich API. Tak
  či onak, nikdy nekonajte na základe surovej požiadavky tak, ako
  prišla.
- **Majte dead-letter queue s nástrojom na replay.** Niektoré
  udalosti zlyhajú z dôvodov, ktoré opakovanie nevyrieši: zmazané
  SKU, diera v mapovaní. Odparkujte ich, alertujte na ne a z replayu
  jednej udalosti urobte tlačidlo, nie SSH session. Keď má API tretej
  strany výpadok, replay vám umožní dobehnúť zameškané bez
  vyhlasovania incidentu.

Test na všetko uvedené je jednoduchý: vezmite včerajšie
udalosti zo stagingu a každú z nich doručte dvakrát, v premiešanom
poradí. Ak koncový stav sedí s produkciou, vaša integrácia je
naozaj idempotentná.

Toto je štandard, podľa ktorého integrácie staviame. Presne toto sa
na našej stránke služieb skrýva za slovami
„[ustáť aj zlý deň API tretej strany](/sk/services/integrations/)“
a rovnaké uvažovanie sa objavuje v našom
[zákazkovom backendovom vývoji](/sk/services/custom-development/).
A ak vaše čísla zásob už driftujú, webhooková vrstva je
[prvé miesto, kde hľadať](/sk/blog/preco-sa-erp-a-eshop-nezhodnu-na-sklade/).