Płatności i subskrypcje w aplikacji SaaS: Stripe w praktyce
Subskrypcja w aplikacji SaaS to cały cykl płatności. Opisujemy stany subskrypcji, webhooki, SCA i odnowienia w Stripe na przykładzie Offer Exchange.
Subskrypcja w aplikacji SaaS (oprogramowaniu udostępnianym w abonamencie) obejmuje cały cykl: wybór planu, pierwszą płatność, odnowienia, nieudane obciążenia, zmianę planu, anulowanie i faktury. Przy integracji ze Stripe stosujemy jedną zasadę. O dostępie do płatnych funkcji decyduje stan subskrypcji przekazany przez webhooki (automatyczne powiadomienia ze Stripe). Sam powrót użytkownika ze strony płatności niczego nie przesądza. Poniżej opisujemy, co trzeba zaprojektować, na przykładzie Offer Exchange, platformy SaaS z bezpłatnym planem i trzema płatnymi subskrypcjami. Fakty o Stripe podajemy według dokumentacji producenta, stan na 25.09.2026.
Plany i limity w aplikacji SaaS
W Offer Exchange z aplikacji można korzystać bezpłatnie, z limitami liczby zapytań w miesiącu, odbiorców zapytania i produktów. Jedna z trzech płatnych subskrypcji podnosi te limity.
Z takiego modelu wynika podział pracy między aplikację a Stripe:
| Odpowiada Stripe | Odpowiada aplikacja |
|---|---|
| ceny i plany, obciążanie karty, odnowienia | liczenie wykorzystania (ile zapytań wysłano w tym miesiącu) |
| faktury i ponawianie nieudanych płatności | blokowanie akcji po przekroczeniu limitu |
| stan subskrypcji | przypisanie limitów do planu i komunikaty dla użytkownika |
Stripe nie wie, ile zapytań wysłał użytkownik. Limity trzeba więc trzymać w bazie aplikacji i sprawdzać przy każdej akcji. Sprawdzenie musi być w kodzie serwera, bo blokada w samym interfejsie nie wystarczy. Więcej o tym, jak budujemy takie produkty, piszemy na stronie o platformach SaaS i MVP.
Jakie stany subskrypcji musi obsłużyć aplikacja?
Subskrypcja w Stripe przechodzi przez kilka stanów (dokumentacja: How subscriptions work). Przy każdym trzeba zdecydować, co użytkownik widzi w aplikacji.
| Stan w Stripe | Co oznacza | Co robi aplikacja |
|---|---|---|
incomplete |
pierwsza płatność nie przeszła albo czeka na uwierzytelnienie; klient ma 23 godziny | nie włącza planu, prosi o dokończenie płatności |
incomplete_expired |
pierwsza płatność nie doszła do skutku w ciągu 23 godzin | traktuje jak brak subskrypcji |
trialing |
okres próbny | daje dostęp do planu |
active |
subskrypcja w porządku | daje dostęp do planu |
past_due |
ostatnia płatność nie przeszła, Stripe może ją ponawiać | informuje użytkownika, prosi o zmianę karty; decyzja biznesowa, czy ograniczać dostęp |
unpaid |
ponowienia się skończyły, faktury nieopłacone | odbiera płatne funkcje |
canceled |
subskrypcja anulowana (stan końcowy) | wraca do planu bezpłatnego |
paused |
okres próbny skończył się bez metody płatności (przy takim ustawieniu) | wstrzymuje płatne funkcje do wznowienia |
Najwięcej decyzji wymaga past_due. Odcięcie dostępu po pierwszej nieudanej płatności zniechęca klientów, którym po prostu wygasła karta. Zostawienie pełnego dostępu na tygodnie oznacza darmowe korzystanie z płatnego planu. To trzeba ustalić z właścicielem produktu przed wdrożeniem.
Skąd aplikacja wie, że klient zapłacił?
Z webhooków, czyli powiadomień, które Stripe wysyła na adres aplikacji. Przekierowanie po płatności może nie dojść (zamknięta karta przeglądarki, przerwane połączenie), a odnowienia dzieją się bez udziału użytkownika. W subskrypcjach najważniejsze są m.in. te zdarzenia (lista zdarzeń):
invoice.paid: faktura opłacona; po potwierdzeniu, że subskrypcja jestactive, przedłużasz dostęp,invoice.payment_failed: płatność nie przeszła; powiadamiasz klienta,invoice.payment_action_required: bank wymaga uwierzytelnienia; prosisz klienta o dokończenie płatności,customer.subscription.updatedicustomer.subscription.deleted: zmiana planu, odnowienie, zakończenie subskrypcji.
Przy obsłudze webhooków pilnujemy kilku zasad z dokumentacji Stripe o webhookach:
- weryfikujemy podpis z nagłówka
Stripe-Signaturena surowej treści żądania, bo bez tego ktoś mógłby włączyć sobie płatny plan fałszywym żądaniem, - odpowiadamy szybko kodem 2xx, a cięższą logikę przenosimy do kolejki; przy błędach Stripe ponawia dostarczenie w trybie produkcyjnym do trzech dni,
- zapisujemy identyfikatory przetworzonych zdarzeń, bo to samo zdarzenie może przyjść więcej niż raz,
- nie zakładamy kolejności zdarzeń, bo Stripe jej nie gwarantuje; w razie wątpliwości aplikacja pobiera aktualny stan subskrypcji z API.
Silne uwierzytelnianie (SCA) przy płatnościach cyklicznych
Silne uwierzytelnianie klienta (SCA) wynika z dyrektywy PSD2 i obowiązuje od 14 września 2019 r. Przy płatnościach kartą klientów z Europejskiego Obszaru Gospodarczego oznacza w praktyce 3D Secure, czyli potwierdzenie płatności w aplikacji banku (Stripe: Strong Customer Authentication).
Przy subskrypcjach klient uwierzytelnia kartę przy pierwszej płatności, gdy jest w aplikacji. Kolejne odnowienia Stripe obciąża już bez jego udziału. Bank może jednak w każdej chwili zażądać ponownego potwierdzenia, bo zwolnienia z SCA nie są gwarantowane. Dlatego aplikacja musi umieć zaprosić klienta z powrotem do dokończenia płatności (zdarzenie invoice.payment_action_required). Gotowe elementy Stripe (Checkout, Billing i Payment Intents) obsługują ten przepływ, więc nie budujemy go od zera.
Co się dzieje, gdy odnowienie się nie uda?
Stripe ponawia nieudane płatności automatycznie. Dla nowych kont domyślnie włączone są Smart Retries: do 8 prób w ciągu 2 tygodni, w momentach wybranych przez model Stripe (Automate payment retries). Co dzieje się po ostatniej próbie, zależy od ustawień. Subskrypcja zostaje anulowana, oznaczona jako nieopłacona albo pozostaje zaległa. Jeśli spełnia warunki, może też zostać wstrzymana.
Przy niektórych odmowach (np. karta zgłoszona jako skradziona albo zgubiona) ponowienie nie ma sensu bez nowej karty. Dlatego e-mail do klienta po nieudanej płatności powinien prowadzić prosto do miejsca, w którym zmieni metodę płatności.
Czy budować własny panel płatności dla klienta?
Zwykle nie. W portalu klienta Stripe klient aktualizuje dane do faktury i metodę płatności, zmienia lub anuluje subskrypcję i pobiera faktury. Portal działa po polsku i można go dopasować do wyglądu marki (Customer portal). Ma też ograniczenia. Na przykład nie da się go osadzić w ramce (iframe), a subskrypcję z kilkoma produktami klient może w portalu tylko anulować, bez zmiany planu.
BLIK i faktury dla polskich klientów
Stripe obsługuje cykliczne płatności BLIK w subskrypcjach (BLIK recurring payments). Klient zatwierdza zgodę w aplikacji banku, a kolejne płatności są pobierane bez nowego kodu. Są ograniczenia: tylko złotówki, do 2 000 zł za jedno obciążenie, tylko klienci wybranych banków. Dla produktu kierowanego do polskich firm warto to rozważyć obok karty.
Osobny temat to faktury. Dokument wygenerowany przez Stripe nie musi spełniać wymogów polskiej faktury VAT ani trafiać do KSeF. Zanim zdecydujesz, czy faktury wystawia Stripe, czy Twój program księgowy, ustal to z księgowością. Od tej decyzji zależy, jaka integracja będzie potrzebna.
Nasza lista kontrolna przy wdrażaniu subskrypcji
- stan subskrypcji zapisany w bazie aplikacji i aktualizowany z webhooków,
- limity sprawdzane po stronie serwera,
- osobne środowisko testowe Stripe i przetestowane scenariusze: odmowa karty, 3D Secure, wygaśnięcie karty, zmiana planu w trakcie okresu,
- jasne komunikaty dla użytkownika w stanach
past_dueiincomplete.
O tym, kiedy płatności powinny wejść już do pierwszej wersji produktu, piszemy we wpisie MVP dla startupu. Jeśli planujesz aplikację z subskrypcjami, opisz nam swój model cenowy. Pomożemy przełożyć go na plany, limity i integrację ze Stripe.