Redirect z platební brány není výsledek platby
import { Aside } from ‘@astrojs/starlight/components’;
Symptom
Sekce “Symptom”Zákazník zaplatí, peníze se strhnou, služba se (přes IPN) správně aktivuje — ale obrazovka po návratu z brány hlásí „platba neproběhla / zrušena”. Zákazníci volají podpoře nebo platí podruhé. V jiné variantě se naopak ukáže „úspěch” po zrušené platbě.
Root cause
Sekce “Root cause”Dvě nezávislé vady návratové stránky:
- Redirect parametr je statický.
redirectUrlse do brány posílá s natvrdo zapečeným?status=success— brána na něj přesměruje i při zrušené/selhané platbě. Parametr nenese žádnou informaci. - Skutečné potvrzení chodí asynchronně. Brána potvrzuje server-to-server (IPN/webhook), který může dorazit až PO návratu uživatele. Stránka, která hned čte stav z DB (nebo čeká parametr jiné brány — zde
session_idze Stripe, který po migraci na Barion nikdy nepřijde), vidí starý stav.
// ❌ soudí z redirectu (a z parametru mrtvé brány)if (params.get('status') === 'success' && params.get('session_id')) { showSuccess(); }else { showCancelled(); } // ← sem spadne KAŽDÁ úspěšná platba nové brányFix
Sekce “Fix”Jediný zdroj pravdy = vlastní DB stav potvrzený IPN. Návratová stránka polluje:
// ✅ "Ověřujeme platbu…" + poll (à 2 s, ~40 s)const paid = orders.some(o => o.payment_status === 'paid'); // → úspěchconst failed = orders.every(o => o.payment_status === 'failed'); // → zrušeno// timeout → měkké "stále ověřujeme, ozveme se" — nikdy tvrdé selháníJak se tomu vyvarovat v jiných systémech
Sekce “Jak se tomu vyvarovat v jiných systémech”- Detection: grep návratových stránek na čtení
status/successzURLSearchParams; zkontroluj, zdaredirectUrlposílaný do brány obsahuje zapečený výsledek. Test: zruš platbu na bráně a sleduj, co stránka ukáže. - Anti-pattern: jedna redirect URL s
?status=success; UI stav odvozený z requestu místo z DB; po migraci bran ponechané parametry staré brány (session_id). - Lepší přístup: redirect URL bez výsledku; návratová stránka = polling vlastního API; IPN idempotentní (viz [[webhook-confirms-payment-on-one-rail-only]]).
Sister bugs / související
Sekce “Sister bugs / související”Stejný vzor u ročního členství téhož webu (stránka předplatného četla stav dřív, než dorazil IPN → „platba neproběhla”, autor málem platil podruhé). [[webhook-confirms-payment-on-one-rail-only]].