2026 · ATTENTIO — Stowarzyszenie Osób Dorosłych z ADHD

Od podpisu do stałego wsparcia

Nowy serwis petycji i darowizn ATTENTIO: od kliknięcia w reklamę w wyszukiwarce, przez podpis pod petycją i płatność, po przypomnienia i wsparcie co miesiąc. Zaprojektowany dla dorosłych z ADHD — ludzi, którym formularz potrafi uciec — i zbudowany tak, żeby każdy krok dało się zmierzyć.

Rola Projekt i realizacja end-to-end — Jakub Nowak

Zobacz petycję na żywo(otwiera się w nowej karcie)
ATTENTIO
  • 100/100Wydajność, dostępność, sprawdzone metody i SEO w PageSpeed Insights — na telefonie
  • 3/3Przeglądanie agentowe: serwis gotowy na asystentów AI
  • 1 731przypadków testowych w 278 plikach, w tym bramki sprawdzone sabotażem

Zakres

  • Strategia lejka i UX
  • UI i design system
  • Front-end
  • Back-end i płatności
  • Pomiar i kampanie
  • Dostępność
  • Wydajność
  • Bezpieczeństwo i prywatność

Next.js 16 · React 19 · Payload CMS 3 · PostgreSQL + Drizzle · Stripe · Vercel · Cloudflare Workers

Etap 1 z 9 · Reklama

Kliknięcie, za które płaci Google

Google Ad Grants to program dla organizacji pozarządowych: do 10 000 USD miesięcznie w kredycie na reklamy w wyszukiwarce. Serwis pilnuje, żeby każde kliknięcie dało się policzyć aż do wpłaty.

Dlaczego tak

  • Jedna petycja = jedna strona docelowa. Reklama prowadzi prosto na petycję.
  • Linki kampanii powstają w panelu wyłącznie z zarejestrowanych oznaczeń UTM.
  • gclid nie zdradza, z którego konta przyszło kliknięcie, więc konwersje trafiają do konta Grants albo płatnego według oznaczeń kampanii — każde konto ma osobne akcje: PODPIS, DAROWIZNA, UPSELL.
  • Dla Grants raport pokazuje koszt podpisu w kredycie, a nie ROAS.

Droga atrybucji: od kliknięcia do konwersji

  1. Kliknięciegclid · gbraid · wbraid · UTM
  2. Pamięć kliknięciapierwszy i ostatni kontakt, podpisane HMAC, 90 dni
  3. Migawkaniezmienna, zapisana obok podpisu
  4. Wpłatadziedziczy migawkę podpisu — nawet po 3 tygodniach
  5. Kolejka konwersjitylko sukces: podpis, zaksięgowana wpłata, subskrypcja
Google Ads · Data Manager APIMeta · Conversions APITikTok · Events API
Pod maską: pomiar, zgody i jakość strony docelowej
  • Konwersje idą z serwera, z kolejki obsługiwanej raz na dobę — nigdy w trakcie żądania użytkownika. Awaria platformy reklamowej nie spowalnia strony podziękowania.
  • Do kolejki trafia wyłącznie wynik końcowy. Wpłata wysłana jako konwersja przed zaksięgowaniem „uczy algorytm licytacji kupować ruch, który nie płaci”. Zwrot koryguje wartość netto.
  • Wspólny identyfikator zdarzenia dla piksela i serwera usuwa duplikaty. Ponowienia: 1 min, 5 min, 30 min, 2 h, 6 h, 24 h; zdarzenia starsze niż okno platformy są odrzucane przed wysyłką.
  • Consent Mode v2 w trybie zaawansowanym, domyślnie wszystko odmówione. Zgoda i sukces są sprawdzane ponownie w chwili wysyłki.
  • Bramka w buildzie odrzuca nazwy zdarzeń kojarzące się ze zdrowiem — jedno źle nazwane zdarzenie mogłoby oflagować cały zbiór danych u platformy.
  • Jakość strony docelowej waży w ocenie reklamy: dlatego strona petycji ma 100 punktów w PageSpeed Insights na telefonie.

Etap 2 z 9 · Petycja

Strona, która ma jeden cel

Za tę wizytę zapłaciła reklama, więc każdy piksel nad formularzem jest decyzją. Na telefonie kolejność w kodzie jest kolejnością czytania.

Strona petycji na telefonie — zrzut z produkcji, imiona osób zastąpione przykładowymi

Dlaczego tak

  • Przyklejony przycisk „Podpisuję petycję” pojawia się na telefonie tylko wtedy, gdy żadna część formularza nie jest widoczna.
  • Przycisk prowadzi na osobną stronę formularza, a to, co już wpisano, jedzie tam w pamięci sesji karty — nigdy w adresie ani w ciasteczku, bo adres trafia do pikseli reklamowych jako Referer.
  • Licznik odświeża się co minutę i po powrocie do karty, z pamięci podręcznej na brzegu sieci: tysiąc otwartych kart to wciąż jedno zapytanie do bazy na minutę.
  • Treść petycji jest w pamięci podręcznej na dni, stan podpisów — na sekundy; formularz nie czeka na nic.
Strona petycji na komputerze — zrzut z produkcji
Pod maską: animacja nowego podpisu
  • Gdy przybywa podpis, najnowsza osoba wjeżdża, przesuwa pozostałe, a trzecia znika — technika FLIP, animowany jest tylko transform.
  • Trzy ruchy Material 3 z tokenów design systemu: wejście 300 ms emphasized-decelerate, przesunięcie emphasized, wyjście 200 ms emphasized-accelerate.
  • Animacja rusza tylko wtedy, gdy licznik naprawdę wzrósł; odświeżenia nigdy nie trafiają do aria-live, więc czytnik ekranu nie przerywa co minutę.
  • Zapis podpisu w liście „ostatnich” jest okrojony już w chwili zapisu do imienia i inicjału — ścieżka odczytu fizycznie nie ma dostępu do nazwiska.

Etap 3 z 9 · Podpis

Podpis bez tarcia

Podpis jest jedyną konwersją tej strony, więc działa zawsze — także wtedy, gdy JavaScript się nie załaduje.

Dlaczego tak

  • Formularz serwerowy: POST → 303 → GET. Skrypt tylko dokłada wygodę — część płatnego ruchu mobilnego ma zablokowany JavaScript.
  • Spokojne błędy: nic nie krzyczy w trakcie pisania. Po wysłaniu — podsumowanie z odnośnikami do pól; błąd znika, gdy tylko pole jest poprawne.
  • Przycisk od razu mówi „Wysyłam podpis…”.
  • Ta sama walidacja w przeglądarce i na serwerze, na zod/mini.

Walidacja w paczce strony docelowej (gzip)

zod64 889 B
zod/mini5 212 B
Pod maską: prywatność podpisu
  • E-mail i telefon: skrót HMAC-SHA256 z „pieprzem” do wyszukiwania oraz szyfrogram AES-256-GCM z kluczem trzymanym wyłącznie w środowisku — wyciek zrzutu bazy nie daje jednocześnie szyfrogramu i klucza.
  • Adres IP nigdy nie jest zapisywany wprost — tylko jako skrót, a IPv6 przycięte do /64.
  • Dziennik zgód przechowuje skrót dokładnej treści klauzuli; test-kanarek wymusza nową wersję przy zmianie choćby słowa. Interfejs dzieli dokładnie ten sam napis, żeby wyświetlony i zapisany tekst nie mogły się rozjechać.
  • Ponowny podpis tą samą osobą wygląda identycznie jak nowy — formularz nie zdradza, czy adres e-mail jest już w bazie.
  • E-mail powitalny wychodzi po wysłaniu odpowiedzi, więc kliknięcie natychmiast przenosi na kolejny ekran; licznik na stronie podziękowania już zawiera Twój podpis.

Etap 4 z 9 · Podziękowanie

Najpierw dziękujemy. Potem prosimy.

Strona podziękowania to most od podpisu do darowizny. Jej układ to kolejność malejącego kosztu dla osoby, która właśnie podpisała.

01 potwierdzenie02 udostępnienie03 pieniądze
Strona podziękowania — zrzut z produkcji, dane wpłat ukryte

Wesprzyj nasze działania!

Petycję trzeba dowieźć: prawnik, który napisze stanowisko, spotkanie w ministerstwie, dojazd.

Wybierz kwotę:

200 zł150 zł100 zł70 zł55 zł35 zł

Dlaczego tak

  • Bez menu i stopki: krok lejka ma policzone wyjścia, a jedynym jest „Powrót”.
  • Pod nagłówkiem ten sam pasek postępu z zielonym „+1” — licznik już zawiera Twój podpis.
  • O zgodę na e-maile pytamy tylko wtedy, gdy nie padła przy podpisie — sprawdzamy to w bazie, nie w ciasteczku.
  • Karta wpłaty w pomarańczu ATTENTIO ma ciemny tekst (5,56:1); biały dałby tylko 3,16:1.
  • Sześć kwot (200 · 150 · 100 · 70 · 55 · 35 zł) i każdy kafel prowadzi do formularza z wybraną kwotą i cyklem miesięcznym.

Eksperyment A/B na tekście prośby

A

„Petycję trzeba dowieźć: prawnik, który napisze stanowisko, spotkanie w ministerstwie, dojazd…”

B

„Robimy to dla dorosłych z ADHD — żeby diagnoza, leczenie i codzienne sprawy przestały być torem przeszkód…”

  • Przydział to czysta funkcja skrótu SHA-256 z identyfikatora odwiedzającego — 50/50, bez osobnego ciasteczka wariantu.
Pod maską: udostępnianie
  • Na urządzeniach dotykowych jeden przycisk Web Share; na komputerze kanały w kolejności zasięgu — każdy link z własnym oznaczeniem UTM.
  • Tekst do udostępnienia mówi w imieniu osoby, która podpisała: „Podpisałem tę petycję. Podpiszesz? Zajmie Ci to minutę.”
  • Tło ASCII karty: suma trzech fal sinusoidalnych, 6 klatek na sekundę, pełny cykl 30 s — około 90 razy wolniej niż próg błysków WCAG.

Etap 5 z 9 · Wpłata

Pięć kroków, zero zgadywania

Formularz wpłaty to system decyzji: kwota, cykl, metoda, dane, zgody. Każdy wybór ma swoją regułę — i każda reguła działa także bez JavaScriptu. Poniżej trzy pierwsze kroki z prawdziwymi regułami.

1 Wybierz kwotę wsparcia
2 Rodzaj wpłaty
3 Metoda płatności

Wpłatę miesięczną przyjmujemy kartą i portfelem — BLIK, Revolut Pay i przelew zostają dla wpłat jednorazowych.

Ścieżka: Stripe Checkout · subskrypcja

Dlaczego tak

  • 11 kwot i „Inna kwota” dają dwa pełne rzędy po sześć. 800 zamiast 700, bo 700 stałoby dokładnie nad 70 zł.
  • 100 zł jest zaznaczone, a „Rekomendowana” stoi wewnątrz etykiety, więc czytnik ekranu to ogłasza. Na telefonie najpierw sześć kwot, reszta pod „Pokaż więcej”.
  • „Miesięcznie” jest domyślne, ale „Jednorazowo” stoi obok w tej samej wielkości.
  • Przycisk zawsze mówi, co się stanie: „Wpłacam 100 zł miesięcznie” — także bez JavaScriptu, dzięki selektorowi :has() w CSS.
  • Dane osoby, która podpisała przed chwilą, są już wpisane — z zaszyfrowanego ciasteczka, nigdy z adresu URL. Zgody nie trzeba zaznaczać drugi raz, jeśli padła przy podpisie.

Cztery ścieżki w przeglądarce, jeden rdzeń na serwerze

  • Pole karty na stronie wpłatyPayment Element
  • Okno kodu BLIKPaymentIntent · blik
  • Przycisk portfelaExpress Checkout
  • Strona Stripe (cykliczne, bez JS, zapas)Checkout

przygotujWplate()

Jeden rdzeń, bo dwie ścieżki budujące ten sam adres powrotu na dwa sposoby to przepis na błąd.

Formularz wpłaty na telefonie — zrzut z produkcji
Formularz wpłaty na komputerze — zrzut z produkcji, stan zbiórki rozmyty
Pod maską: kwoty i limity
  • Parser kwoty przyjmuje „1 000,50”, „30.50” i „zł” i zaokrągla do pełnych groszy (30,10 × 100 to w liczbach zmiennoprzecinkowych 3009,999…).
  • Minimum 2 zł (minimum operatora dla PLN), BLIK do 2 000 zł, maksimum 50 000 zł jako zabezpieczenie przed literówką.
  • Dzień obciążenia wpłaty miesięcznej to min(dzień, 28) — żaden miesiąc nie wypadnie, a marzec nie dostanie dwóch.
  • Bez sztucznego rankingu „najczęściej wybieranych” — jest jawna reguła zamiast udawanych danych.

Etap 6 z 9 · Płatność

W oknie płatności

Wspólna zasada: dane płatnicze nie dotykają serwera ATTENTIO. Karta żyje w ramkach Stripe, kod BLIK idzie z przeglądarki prosto do operatora — dlatego zakres PCI DSS to SAQ A.

Twoja wpłata100 złco miesiąc

Metoda płatności

  • Karta
  • BLIK
  • Apple Pay
  • Google Pay
ramka Stripe1234 1234 1234 1234MM / RRCVClink Zapłać szybciej z Link

Co miesiąc 100 zł · rezygnacja jednym kliknięciem

Wpłacam 100 zł

Płatność obsługuje Stripe

01 · Karta

Karta zostaje w ramce operatora

  • Pole karty Stripe działa w trybie odroczonym: najpierw sprawdzany jest format karty, dopiero potem powstaje płatność — błędna karta nie zostawia śladu u operatora.
  • Wygląd pola jest mierzony z naszego pola formularza w pikselach (rem w ramce liczy się od korzenia Stripe), z celem dotyku 48 px także wewnątrz ramki.
  • Płatność dostaje dokładnie tę metodę, którą wybrano — bez drugiego pytania o metodę i z poprawnym uzgodnieniem wyciągu. W polu karty działa Link.
Twoja wpłata70 złjednorazowo

Metoda płatności

  • Karta
  • BLIK
  • Apple Pay
  • Google Pay

Płatność kodem z aplikacji banku

  1. Kliknij „Wpłacam 70 zł”
  2. Wpisz 6 cyfr kodu
  3. Zatwierdź w aplikacji banku

Płatność obsługuje Stripe

02 · BLIK

Kod dopiero po kliknięciu, bank w 60 sekund

  • Kod jest pytany dopiero po kliknięciu „Wpłacam”, w osobnym oknie.
  • Kod idzie z przeglądarki do operatora i nigdy przez nasz serwer. Płatność powstaje dopiero po wpisaniu kodu.
  • Panel „Potwierdź w aplikacji banku” z odliczaniem 60 s pojawia się PRZED odpowiedzią banku — bo wywołanie operatora wraca dopiero, gdy bank zdecyduje.
  • Po odmowie zużyty kod jest czyszczony.
Twoja wpłata100 złco miesiąc

Metoda płatności

  • Karta
  • BLIK
  • Apple Pay
  • Google Pay
Apple PayAnuluj
Karta
Visa •••• 4242
Odbiorca
ATTENTIO
Razem
100,00 zł

Kliknij dwukrotnie przycisk boczny

Płatność obsługuje Stripe

03 · Portfele

Tylko portfel, który wybrano

  • Przycisk portfela pokazuje wyłącznie portfel wybrany przez darczyńcę.
  • Płatność powstaje dopiero przy potwierdzeniu w arkuszu; domena jest zarejestrowana, a plik weryfikacyjny Apple serwowany z korzenia domeny.
Twoja wpłata100 złco miesiąc

Metoda płatności

  • Karta
  • BLIK
  • Apple Pay
  • Google Pay

Coś nie działa?

Ta sama kwota i ten sam cykl na bezpiecznej stronie Stripe’a.

Zapłać na stronie Stripe’a

Formularz renderowany na serwerze — działa bez JavaScriptu

Płatność obsługuje Stripe

04 · Strona zapasowa

Zawsze jest druga droga do wpłaty

  • Strona płatności zawsze ma zapasowy formularz serwerowy prowadzący do Stripe Checkout — to też ścieżka wpłat miesięcznych i wejść bez JavaScriptu.
  • Zanim zapas otworzy Checkout, anuluje pierwotną płatność; gdy ta jest już opłacona lub w toku, odmawia. Bez tego darczyńca mógłby zapłacić dwa razy.
  • Sekret płatności jedzie do strony płatności w podpisanym ciasteczku HttpOnly ważnym 15 minut, nigdy w adresie — pełny adres trafia do platform reklamowych.

Metody

  • KartaVisa · Mastercard · Linkjednorazowoco miesiąc
  • Apple Pay · Google Payportfel z telefonujednorazowoco miesiąc
  • BLIKkod z aplikacji bankujednorazowo
  • Revolut Payprzez Stripe Checkoutjednorazowo
  • Przelewstrona z wygenerowanym tytułemjednorazowo

Tarcza strony płatności

  • CSP nonce + strict-dynamic, bez unsafe-inline
  • frame-src · connect-src tylko Stripe i Link
  • worker-src'none'
  • form-action'self' + Checkout
  • Nagłówki HSTS · COOP · X-Frame-Options DENY
  • Permissions-Policy 12 funkcji wyłączonych, „payment” celowo nie

Zakres PCI DSS: SAQ A

Pod maską: inwentarz skryptów i nadzór nad nagłówkami
  • Każdy skrypt na stronach płatności ma pisemne uzasadnienie w inwentarzu, a test pada, gdy pojawi się skrypt bez uzasadnienia.
  • Menedżer tagów jest wyłączony na trasach płatności bramką, która stoi przed odczytem konfiguracji; wejście na stronę płatności to pełne przeładowanie, nie nawigacja kliencka.
  • Codzienne zadanie porównuje nagłówki i skrypty produkcji z zamrożonym wzorcem; nowy zewnętrzny skrypt jest różnicą blokującą.
  • worker-src 'none', bo na tej samej domenie działa WordPress, a jego service worker mógłby widzieć stronę płatności.

Etap 7 z 9 · Księgowanie

Księguje tylko potwierdzenie

Kliknięcie „Wpłacam” jeszcze niczego nie księguje. Akcja serwera kończy najdalej na „oczekuje” — „zaksięgowana” ustawia wyłącznie webhook operatora albo nocne uzgadnianie.

Dziękujemy za wpłatę!

100 zł · miesięcznie

Strona serwera

inicjowanaoczekujezaksięgowananieudanaanulowanazwróconaUPDATE … WHERE status IN (…)spóźnione zdarzenie nie cofnie stanu
  • checkout.session.completed
  • checkout.session.async_payment_succeeded
  • checkout.session.async_payment_failed
  • payment_intent.processing
  • payment_intent.succeeded
  • payment_intent.payment_failed
  • charge.refunded
  • invoice.paid
  • invoice.payment_failed
  • customer.subscription.deleted

Dlaczego tak

  • Najpierw wiersz, potem pieniądze: wpłata (i subskrypcja) istnieje w bazie, zanim padnie pierwsze wywołanie do operatora.
  • Idempotencja: deterministyczny klucz z sesji, kwoty i kanału, wysyłany do operatora jako Idempotency-Key. Okno 5 minut odróżnia podwójne kliknięcie od nowej, świadomej wpłaty.
  • Webhook bez SDK: podpis HMAC-SHA256 sprawdzany ręcznie, 300 s tolerancji czasu, porównanie w stałym czasie. Skrzynka zdarzeń po identyfikatorze zdarzenia — duplikat jest pomijany tylko wtedy, gdy oryginał przeszedł bez błędu.
  • Kwota od operatora musi się równać zarezerwowanej, inaczej zdarzenie jest odrzucane i ponawiane.
  • Lista dziesięciu obsługiwanych zdarzeń jest czytana z kodu trasy i zamrożona testem — zdarzenie obsługiwane, ale niewłączone u operatora, po prostu nigdy nie przychodzi.

Subskrypcje i nocne uzgadnianie

  • Subskrypcja staje się aktywna dopiero po zdarzeniu wpłaty.
  • Codziennie o 01:00 UTC wpłaty utknięte w „oczekuje” są sprawdzane u operatora i zamykane tymi samymi funkcjami co webhook; porzucone po 72 godzinach.
  • Zwroty częściowe sumują się w osobnej kolumnie.
Pod maską: hamulec bezpieczeństwa
  • Przyjmowanie wpłat można wstrzymać jednym ustawieniem.
  • Kanał bez poświadczeń kończy się nazwaną odmową.
  • Testy webhooka uruchamiają prawdziwą trasę na Postgresie skompilowanym do WebAssembly.

Etap 8 z 9 · Przypomnienia

Podpisali, nie wpłacili: cztery wiadomości

Dwa kanały remarketingu: własne wiadomości i sygnały z serwera, z których platformy reklamowe budują grupy odbiorców.

makieta interaktywna · treści z szablonów serwisu
  • +1 h e-mail — „Wróć do wpłaty — zajmie minutę”
  • +3 d e-mail — „Na co pójdzie Twoja wpłata”
  • +10 d SMS — zaplanowane
  • +30 d e-mail — zaplanowane

Odebrane

  • ATTENTIONa co pójdzie Twoja wpłata
  • ATTENTIOWróć do wpłaty — zajmie minutę

ATTENTIO

Konkretnie: na co idą pieniądze

Podpisów przybywa, ale sam podpis nie opłaci konsultacji prawnej ani wysyłki pism do ministerstwa. Jedna kwota = jedna godzina pracy prawnika.

Wesprzyj petycję

Dlaczego tak

  • Przed każdym krokiem system wyklucza osoby, które już wpłaciły, mają wpłatę miesięczną (aktywną, oczekującą lub wstrzymaną), nie mają zgody albo dostały prośbę w ostatnich 24 godzinach.
  • Zasady treści: jedna wiadomość = jedno działanie = jeden przycisk.
  • +1 h: „najskuteczniejszy moment w całej kadencji: człowiek jeszcze pamięta, po co tu wszedł”. SMS tylko między 9:00 a 20:00, e-maile między 6:00 a 22:00.
  • Ostatnia wiadomość jest naprawdę ostatnia. Wypisanie to jedno kliknięcie bez pytań, z nagłówkiem List-Unsubscribe One-Click (RFC 8058).

Codzienne zadanie, godzinowe kroki

Każdy krok ma pasmo nadrabiania 36 h i karencję powtórki 24 h — dobrane tak, żeby nic nie wypadło i nic nie wyszło dwa razy:

26 h najdłuższa przerwa<36 h pasmo<71 h najkrótszy odstęp kroków
14 h nakładka pasm<24 h karencja<71 h

„Pominięte przypomnienie jest stratą, powtórzone jest szkodą” — więc token powstaje przed wysyłką, a nie po niej.

Pod maską: bezpieczne linki i sygnały dla platform reklamowych
  • Każda wiadomość ma dwa osobne tokeny — do wpłaty i do wypisania. Wspólny prowadziłby ludzi z „wypisz mnie” do formularza wpłaty, a wtedy klikają „to spam”.
  • Link działa tylko przy prawdziwej nawigacji (nagłówki Sec-Fetch), więc skanery poczty go nie zużywają; potem przekierowanie 303 na czysty adres, żeby token nie trafił do pikseli przez Referer.
  • Link w SMS nie niesie identyfikatora osoby — nikt, kto podał cudzy e-mail ze swoim numerem, nie otworzy cudzego panelu.
  • Atrybucja przeżywa pętlę e-maili: wpłata z przypomnienia po trzech tygodniach jest przypisana kampanii, która kupiła podpis.
  • Remarketing w platformach: grupy odbiorców powstają w Google, Meta i TikTok ze zdarzeń wysyłanych z serwera — podpis bez późniejszej wpłaty, kliknięcie w przypomnienie. Tylko przy zgodzie na personalizację reklam; poziom danych zgoda może wyłącznie obniżyć.
  • Skróty kontaktu dla platform to osobny, niesolony SHA-256 z normalizacją polskich liter („Łukasz” nie staje się „ukasz”); surowy adres IP nigdy nie wychodzi.

Etap 9 z 9 · Co miesiąc

Z jednorazowej na comiesięczną: jedna propozycja

„Co miesiąc” jest domyślne w całym lejku, ale nigdy wymuszone. Kto wpłacił raz, dostaje jedną propozycję zmiany — a kto wspiera co miesiąc, może przerwać jednym kliknięciem.

  1. dzień 0 wpłata jednorazowa
  2. dzień 21 jedna propozycja
  3. dzień 45 granica sensu
makieta interaktywna · reguła z kodu serwisu

100 zł

max(10 zł, wpłata ÷ 3, zaokrąglone do 5 zł)

Propozycja35 złmiesięcznie

Zamienić na 35 zł miesięcznie?30/45 znaków

ATTENTIO

Jedna propozycja

Regularna wpłata pozwala planować dłużej niż do końca kwartału — a przy pracy z ministerstwem wszystko trwa dłużej niż kwartał. Wpłatę cykliczną zatrzymujesz albo wstrzymujesz na miesiąc w panelu, jednym kliknięciem.

Ustaw wpłatę miesięczną

Dlaczego tak

  • 21. dzień po zaksięgowanej wpłacie: „wcześniej jest za wcześnie (…prośba brzmi jak brak wdzięczności), później wpłata przestaje być pamiętana”.
  • Pomijamy każdego, kto ma wpłatę miesięczną — także wstrzymaną — i każdego bez zgody na e-maile.
  • Link otwiera formularz z cyklem miesięcznym, a konwersja z tej wiadomości wraca do kampanii, która przyprowadziła pierwszą wpłatę.
  • Wpłata miesięczna trafia do platform reklamowych jako osobne zdarzenie z wartością 12 × kwota miesięczna — bo darczyńca cykliczny to zobowiązanie, nie jedna płatność. Takie osoby wypadają z kampanii pozyskania.

Panel „Moje wsparcie”

Wpłata miesięczna

100 zł / mies.

Aktywna

„Labirynt rezygnacyjny działa na osoby z ADHD silniej.”
Pod maską: pauza, rezygnacja, raty
  • Pauza na miesiąc to wstrzymanie poboru u operatora z datą wznowienia — plus unieważnienie wpłat już otwartych, bo operator ponawiałby je w trakcie pauzy.
  • Rezygnacja kończy jednym kliknięciem wszystkie wpłaty miesięczne osoby, bez okien potwierdzeń; panel działa bez JavaScriptu.
  • Zmiany wykonane po naszej stronie, a niedoniesione do operatora, nocne uzgadnianie wypycha do operatora.
  • Przychód miesięczny jest odtwarzany z dziennika zdarzeń subskrypcji, a nie z bieżącego stanu — więc historia się nie przepisuje.

Agentic Giving

Coraz więcej osób pyta asystenta AI, zamiast szukać samemu. Serwis rozmawia z asystentami ich językami: asystent znajdzie petycję, pozna zasady i przygotuje darowiznę — a ostatni krok, zatwierdzenie płatności, zawsze należy do człowieka.

Chcę wesprzeć petycję o refundację leczenia ADHD dorosłych kwotą 50 zł.

attentio-przygotuj-darowizne · kwotaZl: 50

Przygotowałem wpłatę 50 zł na tę petycję. Otwórz stronę i potwierdź płatność — kwota jest już wpisana.

attentio.org.pl/petycje/…/wesprzyj · 50 zł

Płatność zatwierdza człowiek

Dlaczego tak

  • Serwer MCP nie obciąża karty: zwraca adres strony wpłaty z wpisaną kwotą. Okno czatu nie ma instrumentu płatniczego, więc obciążenie wymaga poświadczenia, które wnosi człowiek.
  • Narzędzie nie przyjmuje danych osobowych — e-mail wpisuje człowiek na stronie.
  • Gdy baza jest niedostępna, narzędzie i tak zwraca adres: utrata wiersza to utrata atrybucji, a utrata adresu — utrata darowizny.
  • Zwykły GET na adres serwera zwraca czytelny opis zamiast błędu 405 — asystent, który zajrzy przeglądarką, nie zrezygnuje.
„Serwer NIE obciąża karty — ostatni krok wykonuje człowiek.”
z opisu serwera MCP
  • MCPzdalny serwer w oficjalnym rejestrze MCP: cztery narzędzia — petycje, katalog darowizn, zasady, przygotowanie darowizny
  • WebMCP7 narzędzi opisanych na formularzach strony i 3 narzędzia tylko do odczytu, bez automatycznego wysłania
  • UCPprofil /.well-known/ucp, sesje checkoutu, token Google Pay, podpisy HTTP RFC 9421
  • ACPdokument /.well-known/acp.json, sesje checkoutu z Shared Payment Token i powiadomienia o zamówieniach
  • AP2mandaty płatnicze SD-JWT weryfikowane przy finalizacji, podpis sprzedawcy nad każdą odpowiedzią
  • Stripe ACSkatalog darowizn dla agentów zakupowych w formacie operatora
  • Web Bot Authtożsamość agenta weryfikowana podpisem — do dziennika i atrybucji
  • llms.txtopis serwisu dla modeli językowych, serwowany z korzenia domeny

Jeden rdzeń, cienkie wiązania

  • Wszystkie protokoły korzystają z jednego rdzenia sesji darowizny — tego samego, który obsługuje formularz na stronie. Sesja to zwykły wiersz wpłaty w stanie „inicjowana”, bez osobnej tabeli.
  • Identyfikator sesji to HMAC z platformy i klucza idempotencji: powtórzone żądanie trafia w ten sam wiersz, a ten sam klucz z innym koszykiem dostaje odmowę.
  • Katalog: drabina kwot 25–1000 zł oraz „cegiełka” 1 zł × ilość na kwotę własną. Wsparcie miesięczne agent może pokazać, ale założenie go prowadzi na stronę serwisu.
  • Weryfikacja 3-D Secure, której nie da się przejść w rozmowie, zamienia się w przekazanie człowiekowi z adresem do dokończenia.
  • Wpłata od agenta dostaje atrybucję agent / protokół / platforma bez żadnych ciasteczek, więc raporty kampanii widzą ten kanał obok reklam.

Strona „Zapytaj asystenta”

Pięć przycisków otwiera popularnych asystentów z gotowym pytaniem o petycje ATTENTIO. Zasada tekstu: nigdy „asystent zapłaci za Ciebie”.

  • ChatGPT
  • Gemini
  • Claude
  • Copilot
  • Perplexity
Pod maską: serwer MCP
  • Rdzeń JSON-RPC napisany bez SDK, żeby nie dokładać zależności do zakresu PCI; obsługuje dwie ery protokołu MCP (z sesją i bez).
  • Serwer jest wpisany do oficjalnego rejestru MCP z dowodem własności domeny serwowanym z korzenia.
  • Metody, które odpytują automaty (inicjalizacja, lista narzędzi, ping), nie budzą bazy — liczniki tych wywołań żyją w pamięci.

Cztery razy sto — na telefonie

Raport PageSpeed Insights dla strony petycji, na którą prowadzą reklamy. Szybkość jest tu kosztem pozyskania, nie ozdobą.

100
Wydajność
100
Ułatwienia dostępu
100
Sprawdzone metody
100
SEO
3/3
Przeglądanie agentowe
Zrzut raportu PageSpeed Insights: 100, 100, 100, 100 i 3/3
  1. −60 kBwalidacja na zod/mini zamiast pełnego zoda
  2. −20,6%blokujący CSS: nowy rdzeń bez masek ilustracji, potem podział na trasy — 5 407 elementów × 45 właściwości porównanych, 0 różnic
  3. −25 kBkroje przycięte do używanych osi i glifów; zapasowe fonty skalibrowane na polskim zdaniu: CLS 0,031 → ≈0
  4. −1 250 msobraz LCP (4 KB AVIF) wpisany wprost w HTML — koniec kolejki za dokumentem
  5. 99,55krój marki dopiero po LCP i jeden krok sieci mniej — Lighthouse zaokrągla to do 100
  6. 100w PageSpeed Insights na telefonie
Pod maską: co jeszcze zostało zmierzone
  • CSS wpisany w dokument: FCP 1 804 → 1 001 ms w pomiarze lokalnym, kosztem 21 kB na dokument.
  • Krój Onest przycięty z 29 656 do 26 948 B — poniżej progu 27 500 B, przy którym model sieci Lighthouse zyskuje cały krok 75 ms.
  • Usunięty no-store ze stron publicznych: natychmiastowy powrót z pamięci bfcache; strony z danymi osobowymi zostają bez cache.
  • Dokument mniejszy o 22% po tym, jak drzewo strony 404 przestało być serializowane do każdej strony.

Zaprojektowane dla uwagi, która ucieka

Design system i dostępność to tu jedna decyzja: dla dorosłych z ADHD każda zbędna decyzja, zagadka i labirynt jest kosztem, nie drobiazgiem.

Ruch: sprężyny Material 3 Expressive

Sześć sprężyn przeliczonych w buildzie do krzywych CSS linear() — dokładnych dla każdego dystansu i bez JavaScriptu w przeglądarce. Wybierz jedną:

default spatialζ 0,8 · 431 ms

Kontrast na pomarańczu

Wesprzyj

Ziarno #F26430 w wariancie FIDELITY: build sprawdza, że kontener główny to dokładnie ziarno. Poziom kontrastu 0,2 zamiast 0 podnosi pary tekstu na kontenerach z 4,53 do 5,56:1. CI pilnuje 74 par i 14 par zakazanych.

Dwukolorowy fokus

Żaden pojedynczy kolor nie daje 3:1 jednocześnie na bieli i na pomarańczu — pierścień ma więc dwa: ciemny obrys i jasną poświatę. Przejdź klawiszem Tab.

Kontrakt glifów

ĄĆĘŁŃÓŚŹŻ ąćęłńóśźż „” –—

Brak polskiego znaku w podzbiorze kroju zatrzymuje build. Bricolage Grotesque (nagłówki), Onest (tekst), Atkinson Hyperlegible Next w trybie czytania — wszystkie hostowane u siebie.

12 kształtów M3 Expressive

Wyłącznie polygon() — biblioteka z 30 do 16,8 kB.

Zasady, które wynikają z ADHD

  • Bez labiryntu rezygnacji, bez dwóch przycisków w jednej wiadomości.
  • Spokojna walidacja i formularze, które pamiętają, co wpisano (WCAG 3.3.7 — brak ponownego wpisywania).
  • Kolejność w DOM = kolejność wizualna, cele dotyku 48 px, etykiety zgodne z nazwą dostępną.
  • Ograniczony ruch zatrzymuje zapętlone animacje, ale nie łamie funkcji; tryb czytania zmienia krój na Atkinson Hyperlegible Next.
  • Dokumenty prawne pisane językiem neutralnym płciowo — pilnuje tego test.
  • Testy dostępności: axe oraz osobny zestaw „czego axe nie umie” — reflow przy 320 px, odstępy tekstu, odstępy celów.

To, czego nie widać, trzyma resztę

Architektura, prywatność i jakość — zaprojektowane tak samo starannie jak ekrany.

Jedna domena, dwa światy

attentio.org.plworkerCloudflare/petycje → Next.jsVercel · Frankfurtreszta domenyWordPress

Worker scala też dwie mapy witryny w jedną i serwuje z korzenia domeny wąską listę adresów aplikacji (llms.txt, pliki weryfikacyjne). Przeniesienie kolejnej sekcji serwisu to dopisanie jej prefiksu.

Sześć zadań na dobę (UTC)

  • 01:00 uzgadnianie płatności
  • 03:00 sprzątanie i retencja
  • 04:00 nagłówki stron płatności
  • 05:00 wysyłka konwersji
  • 06:00 zdrowie brzegu i pochodzenia
  • 08:00 przypomnienia i propozycje

Prywatność od projektu

  • Publicznie widać tylko imię i inicjał. Adresat petycji dostaje imię, nazwisko i datę podpisu — bez danych kontaktowych — w pliku CSV chronionym przed wstrzyknięciem formuł.
  • Kroje hostowane u siebie, bez CDN Google Fonts. Panel redakcji z drugim składnikiem: klucze dostępu WebAuthn — samo hasło nigdy nie tworzy sesji.
  • Środowisko testowe ma własną, pustą bazę budowaną z migracji; wdrożenie nieprodukcyjne odmawia połączenia z bazą produkcyjną po jej odcisku.
  • Ścieżki odpytywane przez automaty nie budzą bazy — liczniki dla nich są w pamięci.

Każde wydanie przechodzi przez bramki

  1. prebuild
  2. typecheck
  3. test
  4. check:measurement
  5. baza testowa
  6. schemat
  7. build

Czerwony test blokuje wydanie, także poprawkę awaryjną. Większość bramek ma zapisany sabotaż — celowe zepsucie, które dowodzi, że zapala się na czerwono. Do tego testy w środowisku o kształcie produkcji i skanery: Snyk, Semgrep, Aikido, Socket oraz filtr złośliwych paczek przy instalacji.

Łańcuch dostaw pod kontrolą

Serwis przyjmuje pieniądze, więc każda zależność jest częścią strony płatności. Cztery skanery i filtr złośliwych paczek odpowiadają na cztery różne pytania — od chwili, gdy paczka wychodzi z rejestru, do wydania.

rejestr paczek

  1. Czy ta paczka w ogóle się zainstaluje?Safe Chainlista złośliwych paczek · wiek wydania ≥ 48 h
  2. Czy zależność robi coś złego, choć nie ma znanej podatności?Socketskrypty instalacyjne · ruch sieciowy · literówki w nazwach
  3. Czy w zależnościach siedzi znana podatność?npm audit · Snyk Open Sourcepróg „high”, tylko zależności produkcyjne
  4. Czy w naszym kodzie jest dziura albo sekret?Semgrep · Snyk Code · Aikidoanaliza statyczna · sekrety · konfiguracja infrastruktury

wydanie

Filtr złośliwych paczek

Zła paczka nie dociera do dysku

Gdzie działa
lokalny pośrednik między menedżerem paczek a rejestrem
Co wychodzi
nic o naszym buildzie — pobiera tylko listy
Kiedy
przy każdej instalacji: środowisko pracy, CI, build hostingu
  • Nakładki na npm, npx, pip i uvx puszczają pobieranie przez lokalnego pośrednika. Ten odrzuca paczki z listy złośliwych i wersje opublikowane mniej niż 48 godzin temu — w tym czasie zatrute wydania zwykle zostają wykryte i wycofane.
  • Stoi w trzech miejscach: przed instalacją zależności w środowisku pracy, przed każdym npm ci w GitHub Actions i w komendzie instalacji builda na hostingu. Błąd instalacji zatrzymuje wdrożenie — poprzednia wersja zostaje na produkcji.
  • Wersja i suma SHA-256 instalatora mają jedno miejsce w repozytorium, a instalator sam sprawdza sumę pobieranego programu. Test pilnuje, że nikt po cichu nie dopisze wyjątku od reguły 48 h.
  • Granica jest zapisana wprost: paczka podana z lokalnej pamięci podręcznej npm nie przechodzi przez pośrednika — chroni ją wtedy suma z pliku blokad.

Zachowanie zależności

Ocenia paczki, nie nasz kod

Gdzie działa
serwis Socket — analiza paczek z rejestru npm
Co wychodzi
nazwa i wersja paczki; kod źródłowy — nie
Kiedy
raport przy każdym pushu na main
  • Jedyny w zestawie, który patrzy na ZACHOWANIE pakietu, a nie na listę znanych podatności: skrypty instalacyjne, dostęp do sieci, zaciemniony kod, nazwy podszywające się literówką pod popularne paczki.
  • Służy też jako sprawdzian przed podbiciem zależności: ocena nowej wersji i przegląd jej skryptów instalacyjnych, zanim trafi do pliku blokad.
  • Alerty są zamykane kodem: nadpisaniem wersji w łańcuchu narzędzi deweloperskich albo zaślepką w miejscu paczki, którą zależność deklaruje, ale nigdy nie ładuje — zaślepka rzuca błąd, gdyby ktoś jednak sięgnął.

Podatności i przepływ danych

Zależności i kod, śledzone między plikami

Gdzie działa
chmura Snyka
Co wychodzi
drzewo zależności; przy analizie kodu — pliki źródłowe
Kiedy
na żądanie, dwoma skryptami: kod i zależności
  • Snyk Open Source czyta drzewo zależności z pliku blokad i porównuje je z bazą podatności — obok bramki npm audit, nie zamiast niej.
  • Snyk Code śledzi przepływ danych od źródła do ujścia między plikami, czego lokalne narzędzia w wersji bezpłatnej nie robią.
  • Analiza kodu wysyła pliki do chmury, polityka wyłącza z niej eksport treści dotychczasowej strony i zbudowany CSS — skanowany jest tylko nasz kod.
  • Wersja narzędzia jest przypięta i pilnowana testem: „najnowsza” przy każdym uruchomieniu to kod, którego nikt nie przejrzał.

Analiza statyczna, lokalnie

Kod zostaje na miejscu, z sieci przychodzą tylko reguły

Gdzie działa
lokalnie, w środowisku pracy
Co wychodzi
kodu nie wysyła; śledzenie wywołań wyłączone
Kiedy
na żądanie, skryptem
  • Semgrep Community Edition analizuje kod na miejscu; z sieci pobiera wyłącznie zestawy reguł.
  • Własne reguły zamieniają jedną znalezioną usterkę w pytanie o całe repozytorium: czy ten sam wzorzec nie stoi jeszcze gdzieś indziej.
  • Złapał to, czego nie złapały pozostałe narzędzia — dlatego zestaw ma kilka skanerów kodu, a nie jeden.

Kod, sekrety i infrastruktura

Trzy silniki w jednym skanie

Gdzie działa
lokalnie: analiza statyczna, sekrety, konfiguracja infrastruktury
Co wychodzi
zgłoszenia ze ścieżkami; sekret zamaskowany poza ostatnimi 4 znakami
Kiedy
przed każdym commitem (sekrety) i przy wydaniu w CI
  • Jeden skan uruchamia trzy silniki: analizę statyczną kodu, wyszukiwanie sekretów w plikach roboczych i kontrolę konfiguracji infrastruktury (hosting, worker na brzegu, workflowy CI).
  • Hak przed commitem szuka sekretów, zanim trafią do historii gita — z historii nie da się ich już usunąć, tylko unieważnić.
  • Skan wydania w CI działa w trybie raportu: zgłoszenie trafia do przeglądu, a nie blokuje wydania bez oceny człowieka.

Zasady pracy z wynikami

  • Wynik skanu to zgłoszenie do weryfikacji, nie dowód: każde jest sprawdzane w kodzie — czy ścieżka do usterki naprawdę istnieje od żądania darczyńcy — zanim cokolwiek się zmieni.
  • Każde narzędzie ma przypiętą wersję i test, który zapala się na czerwono, gdy ktoś ją zdejmie albo poluzuje konfigurację.
  • Narzędzia uruchamiane lokalnie startują ze środowiskiem z białej listy.

Bramka zależności w każdym wydaniu

npm run audit

  • próg: „high” i wyżej
  • tylko zależności produkcyjne — narzędzia deweloperskie nie jadą na produkcję
  • zamknięta lista wyjątków, każdy z terminem
  • wyjątek wygasa sam, gdy wyjdzie poprawka

Jedna osoba, dziewięć etapów, jeden system

  1. Reklamakliknięcie z Ad Grants trafia na petycję z zapamiętaną atrybucją
  2. Petycjaformularz przed treścią, dowód społeczny tuż nad nim
  3. Podpisdziała bez JavaScriptu, jedna transakcja
  4. Podziękowanienajpierw dziękujemy, potem prosimy
  5. Wpłataco miesiąc domyślnie, jednorazowo na równi
  6. Płatnośćdane karty tylko u operatora, cztery ścieżki, jeden rdzeń
  7. Księgowanie„zaksięgowana” ustawia tylko potwierdzenie
  8. Przypomnieniacztery wiadomości
  9. Co miesiącjedna propozycja w 21. dniu; pauza i rezygnacja jednym kliknięciem

Rola Projekt i realizacja end-to-end — Jakub Nowak

Porozmawiajmy o tym projekcie