Files
bilety.brzezovka.pl/.paul/phases/05-purchase-redirect-hardening/05-01-PLAN.md
Jacek Pyziak 28b7a1dd54 feat(05-purchase-redirect-hardening): harden purchase redirect tracking
Phase 5 complete:

- guard purchase event per transaction in sessionStorage

- restore saved consent before GTM and purchase

- add centered Przelewy24 countdown redirect
2026-05-08 23:56:37 +02:00

6.9 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, delegation
phase plan type wave depends_on files_modified autonomous delegation
05-purchase-redirect-hardening 01 execute 1
templates/tickets/przelewy24.php
templates/site/layout-logged.php
true off
## Goal Zabezpieczyc event `purchase` przed ponownym wywolaniem po odswiezeniu strony Przelewy24 i przywrocic automatyczne przekierowanie do Przelewy24 z komunikatem oraz odliczaniem 5 sekund.

Purpose

Tracking ecommerce ma rejestrowac jedno zamowienie tylko raz w przegladarce, a uzytkownik ma po zlozeniu zamowienia zostac automatycznie przekierowany do platnosci po krotkim czasie pozwalajacym GTM przetworzyc event.

Output

Zmodyfikowane templates/tickets/przelewy24.php oraz templates/site/layout-logged.php.

- No clarifications needed - uzytkownik potwierdzil, ze `purchase` dziala po przycisku, ale wymaga zabezpieczenia przed odswiezeniem i powrotu automatycznego przekierowania z odliczaniem 5s. - Przyjete rozwiazanie: blokada duplikatu w `sessionStorage` per `transaction_id`, bo nie wymaga zmiany DB i chroni przed refresh w tej samej sesji przegladarki.

Project Context

@.paul/PROJECT.md @.paul/ROADMAP.md @.paul/STATE.md

Prior Work

@.paul/phases/02-purchase-event-prepayment/02-01-SUMMARY.md @.paul/phases/03-cookie-consent/03-01-SUMMARY.md @.paul/phases/04-cookie-notice-bugfix/04-01-SUMMARY.md

Source Files

@templates/tickets/przelewy24.php @templates/site/layout-logged.php @autoload/controls/class.Tickets.php

<acceptance_criteria>

AC-1: Purchase fires only once per browser session and transaction

Given user lands on /tickets/przelewy24/order=HASH with a valid purchase payload
When the page is loaded for the first time in the current browser session
Then the page pushes ecommerce reset and `event: purchase` to `window.dataLayer`

AC-2: Refresh does not duplicate purchase

Given the same browser session already sent purchase for the same transaction_id
When the user refreshes /tickets/przelewy24/order=HASH
Then the page does not push another `event: purchase` for that transaction_id

AC-3: Auto redirect returns with visible countdown

Given the user lands on the Przelewy24 redirect page
When the page finishes loading
Then a message says the user will be redirected to Przelewy24 and a visible countdown starts at 5 seconds before the form submits automatically
Given the user previously accepted analytics or marketing cookies
When a new page loads
Then saved CookieNoticePro preferences update Google Consent Mode before GTM and before the purchase event can be pushed

</acceptance_criteria>

Task 1: Add one-time purchase guard templates/tickets/przelewy24.php Replace the unconditional `window.dataLayer.push(...)` block with guarded JavaScript: - JSON-encode the existing purchase payload as now. - Read `transaction_id` from `purchaseDataLayer.ecommerce.transaction_id`. - Build a stable session key, e.g. `brzezovka_purchase_sent_` + transaction_id. - If no session key exists, push `{ ecommerce: null }` and the purchase payload, then set the session key. - If the key exists, skip the purchase push. - If `sessionStorage` is unavailable, fail open and still push purchase once for that page load. Avoid changing backend payload structure in `autoload/controls/class.Tickets.php`. rg -n "sessionStorage|brzezovka_purchase_sent_|dataLayer.push" templates/tickets/przelewy24.php AC-1 and AC-2 satisfied. Task 2: Restore auto redirect with five second countdown templates/tickets/przelewy24.php Replace the temporary submit button with: - A visible message explaining automatic redirect to Przelewy24. - A visible countdown starting at 5 seconds. - JavaScript that updates the countdown every second and submits `#form_data` after 5 seconds. - Keep a normal submit button as fallback/manual action only if JavaScript is delayed or user wants to continue immediately. Ensure the purchase guard executes before the redirect timer submits the form. rg -n "redirectCountdown|setInterval|setTimeout|form_data|Przelewy24" templates/tickets/przelewy24.php AC-3 satisfied. Task 3: Keep saved consent restore before GTM templates/site/layout-logged.php Preserve the current Consent Mode restore block added after default denied and before the GTM snippet: - Read `cnp_consent` and `cnp_prefs` cookies. - If consent is true, update analytics and marketing consent according to saved preferences. - Keep the GTM snippet after this restore block. Improve only if needed for syntax or robustness; do not move CookieNoticePro init into the head. rg -n "cnp_consent|cnp_prefs|gtag\\('consent', 'update'|Google Tag Manager|cookieNoticePro\\.init" templates/site/layout-logged.php AC-4 satisfied.

DO NOT CHANGE

  • autoload/controls/class.Tickets.php purchase payload builder unless verification proves a blocker.
  • Database schema and order write flow.
  • CookieNoticePro library files.
  • Przelewy24 credentials, signatures, endpoint URLs, and payment callback handling.
  • Existing unrelated .vscode/ftp-kr.sync.cache.json change.

SCOPE LIMITS

  • Client-side duplicate guard only; no DB-level event ledger in this plan.
  • No changes to GA4/GTM container configuration.
  • Keep this as a production cleanup after the manual test, not a broader checkout redesign.
Before declaring plan complete: - [ ] `php -l templates/tickets/przelewy24.php` - [ ] `php -l templates/site/layout-logged.php` - [ ] `rg -n "sessionStorage|brzezovka_purchase_sent_|redirectCountdown|setTimeout|cnp_consent|cnp_prefs" templates/tickets/przelewy24.php templates/site/layout-logged.php` - [ ] Manual browser check: first load pushes `purchase`, refresh of same Przelewy24 page does not push another `purchase`. - [ ] Manual browser check: countdown starts at 5 and submits to Przelewy24 automatically. - [ ] Manual browser check: with saved cookie consent, purchase is sent under restored granted consent when analytics/marketing were accepted.

<success_criteria>

  • purchase cannot be duplicated by simple refresh in the same browser session.
  • Przelewy24 redirect is automatic again after 5 seconds.
  • User sees clear redirect message and countdown.
  • Saved CookieNoticePro consent is restored before GTM and purchase execution.
  • No payment backend, order creation, or Przelewy24 callback logic changed. </success_criteria>
After completion, create `.paul/phases/05-purchase-redirect-hardening/05-01-SUMMARY.md`.