Dupli webhook, dupla naplata: idempotentnost prostim rečima
Zašto isti događaj stigne dvaput i naplati dvaput, šta tačno piše u zvaničnoj dokumentaciji o ponovnim pokušajima, i šest pravila koja to zaustavljaju.
Izaberi iznos ili skeniraj kod bez iznosa pa ga upiši u banci. Novac ide direktno na račun autora (GoSimple), Trek ne uzima ništa i nije posrednik u plaćanju.
Na telefonu: preuzmi kod, pa ga u aplikaciji banke učitaj iz galerije.
Ažurirano: 12.10.2026. | Verzija 1.0
Kupac plati jednom, a vaša aplikacija napravi dve porudžbine, pošalje dva mejla i izda dva računa. To nije kvar platnog sistema. To je očekivano ponašanje na koje vaša aplikacija nije spremna.
Ovaj tekst objašnjava zašto se to dešava i šta tačno treba uraditi, sa citatima iz zvanične dokumentacije.
Ovo nije retka nezgoda, nego pravilo
Zvanična Stripe dokumentacija kaže tri stvari koje rešavaju većinu zabune:
- „Odredišta za webhook ponekad mogu da prime isti događaj više puta." Preporuka je da beležite identifikatore obrađenih događaja i da već obrađene preskačete.
- „Stripe ne garantuje da će događaji stići redosledom kojim su nastali." I izričito: ne koristite vreme nastanka da biste utvrdili redosled ili da li ste događaj već obradili, nego pratite identifikatore.
- Pokušaji isporuke traju do tri dana, sa sve većim razmacima.
Prevedeno: sistem obećava da će poruka stići bar jednom, ne tačno jednom. „Tačno jednom" se ne postiže u prenosu, nego kod vas, na prijemu.
Primer iz prakse
Jedan programer je opisao svoj slučaj: obrada potvrde o plaćanju trajala je duže od dozvoljenog, platni sistem je devet sekundi kasnije pokušao ponovo, nastao je drugi radni prostor za istog kupca, podaci su se tiho podelili na dva mesta, a kupac je otkazao nedelju dana kasnije.
Drugi slučaj je još bliži temi: agent je napisao obradu potvrde o plaćanju koja je prošla i pregled i automatske provere, jer su testovi slali svaki događaj tačno jednom. U stvarnom radu, kad je događaj stigao dvaput, naplata je bila dvostruka.
Šest pravila koja to zaustavljaju
1. Odgovorite brzo, pa tek onda radite
Dokumentacija je izričita: vratite uspešan odgovor pre složene logike koja bi mogla da izazove istek vremena. Posao stavite u red i obradite ga odvojeno. Preusmeravanja se broje kao neuspeh.
2. Pamtite identifikator događaja
Pre obrade proverite da li ste taj identifikator već videli. Ako jeste, odgovorite potvrdno i ne radite ništa. Ovo je najvažnije pravilo u celom tekstu.
3. Dodajte jedinstveno ograničenje u bazu
Provera iz prethodne tačke može da padne ako dva zahteva stignu u istom trenutku. Jedinstveno ograničenje u bazi je brava koja drži i tada. To je razlika između „obično radi" i „radi".
4. Koristite ključ idempotentnosti kad vi pozivate
Kad vaša aplikacija poziva platni sistem, šaljite ključ idempotentnosti. Preporučuje se nasumična vrednost, najviše 255 znakova.
Dve stavke koje se previde:
- Ključ ima rok. Sistem ga čuva najmanje 24 sata, a posle toga isti ključ pravi nov zahtev. Ključ, dakle, nije večna zaštita.
- Isti ključ sa drugačijim sadržajem daje grešku, namerno, da bi se sprečila zabuna. Ključevi važe samo za zahteve koji nešto menjaju.
5. Proverite potpis, uvek
Bez provere potpisa svako može da pošalje lažno obaveštenje i pokrene isporuku, dodelu pristupa ili izmenu zapisa. Dokumentacija preporučuje i proveru potpisa i spisak dozvoljenih adresa.
Tri detalja koja ruše proveru u produkciji, a lokalno rade:
- Telo zahteva mora da ostane netaknuto. Svaka obrada pre provere ruši potpis.
- Ne postavljajte toleranciju vremena na nulu. Zvanične biblioteke koriste pet minuta, a nula gasi proveru svežine.
- Ruta za obaveštenja mora da bude izuzeta iz zaštite od zahteva sa drugog sajta, inače ispravna obaveštenja propadaju.
6. Ne zaključujte redosled po vremenu
Vreme nastanka se beleži u sekundama, pa više događaja deli istu oznaku. Redosled se ne izvodi iz njega.
Šta tražiti od AI alata
Ako obradu plaćanja piše agent, ovo ubacite doslovno u zahtev:
Napiši obradu obaveštenja o plaćanju koja:
1. prvo proveri potpis, bez menjanja sirovog tela zahteva,
2. odmah vrati uspešan odgovor, pa posao stavi u red,
3. zapamti identifikator događaja i preskoči već obrađene,
4. ima jedinstveno ograničenje u bazi na tom identifikatoru,
5. ne koristi vreme nastanka za redosled.
Napiši i testove u kojima isti događaj stiže DVA PUTA i u kojima
stižu van redosleda. Pokaži mi da testovi prvo padaju.
Zadnja rečenica je ključna. Testovi koji svaki događaj šalju jednom ne dokazuju ništa, a upravo takve testove alati najčešće napišu.
Veza sa računom
Ako vaša aplikacija izdaje fiskalni račun, duplikat nije samo neprijatnost nego i problem sa evidencijom. Zato ozbiljni sistemi za fiskalizaciju garantuju da se ista porudžbina fiskalizuje tačno jednom, čak i ako obaveštenje i povlačenje stignu istovremeno, a to obezbeđuju ograničenjem u bazi, ne proverom u kodu.
Isto pravilo primenite i kod sebe: jedinstveno ograničenje nad brojem porudžbine iz prodavnice.
Česta pitanja
Zašto platni sistem uopšte šalje isti događaj dvaput? Zato što ne zna da li ste prvi put primili poruku. Ponavljanje je jedini način da se garantuje isporuka preko nepouzdane mreže.
Da li je dovoljna provera „da li ovaj račun već postoji"? Nije, ako dva zahteva stignu u istom trenutku. Potrebno je jedinstveno ograničenje u bazi.
Koliko dugo stižu ponovni pokušaji? Kod Stripe-a do tri dana, sa sve većim razmacima. Ručno ponovno slanje je moguće i kasnije.
Da li ključ idempotentnosti traje zauvek? Ne. Čuva se najmanje 24 sata, pa isti ključ posle toga pravi nov zahtev.
Kako da testiram da je rešeno? Pošaljite isti događaj dvaput u test okruženju i proverite da je nastao tačno jedan zapis, jedan mejl i jedan račun.
Sledeći korak
Pošaljite isti testni događaj dvaput u svoje test okruženje. Ako nastanu dva zapisa, imate ovaj problem. Dalje pročitajte tekst o izboru načina naplate za firme iz Srbije.
GoSimple · Ivan Dabetić
Izvori (provereno 12.10.2026)
- Stripe, webhook obaveštenja, duplikati i ponovni pokušaji: https://docs.stripe.com/webhooks
- Stripe, ključ idempotentnosti i rok čuvanja: https://docs.stripe.com/api/idempotent_requests
- AWS, isporuka bar jednom kao svojstvo reda poruka: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/standard-queues.html
- Opisan slučaj duple obrade: https://dev.to/alexcloudstar/stripe-webhooks-in-production-idempotency-retries-and-the-mistakes-that-cost-me-real-money-5haf