Jeśli budujesz sklep — integracja płatności to kilka godzin roboty. Jeśli budujesz marketplace — to kilka tygodni, przepisywanie modułów i realne ryzyko, że operator płatności po prostu odmówi współpracy.
To nie jest clickbait. To różnica architektoniczna i prawna, która potrafi zatopić projekt na etapie, gdy wydaje się, że wszystko już działa.
Jest to jedno z pytań , o które powinieneś zadać przed założeniem sklepu e-commerce.
Część 1 — Sklep: prosty model, prosta integracja
W klasycznym sklepie flow płatności wygląda tak:
Klient → płaci → pieniądze trafiają do Ciebie
Jeden merchant, jeden odbiorca, zero splitów. Nie ma tu mowy o payout orchestration, compliance marketplace ani KYC sprzedawców. To zwykła transakcja — i właśnie dlatego integracja jest prosta.
Stripe w Polsce — stan faktyczny
Stripe obsługuje dziś w Polsce pełen zestaw metod płatności:
- Przelewy24 (jako metoda płatności przez Stripe)
- BLIK
- Karty (Visa, Mastercard, Amex)
- Apple Pay / Google Pay
- Klarna i inne BNPL
- Przelewy bankowe
Dla zdecydowanej większości sklepów jeden provider wystarczy. PayU i Przelewy24 jako samodzielne integracje nadal mają sens — pełnią tę samą rolę agregatora metod płatności — ale przy mniejszym GMV trudno uzasadnić dodatkowy koszt utrzymania integracji.
Medusa.js — integracja Stripe
Medusa.js dostarcza oficjalny plugin:
@medusajs/payment-stripeKonfiguracja w medusa-config.ts:
{
resolve: "@medusajs/payment-stripe",
options: {
api_key: process.env.STRIPE_API_KEY,
webhook_secret: process.env.STRIPE_WEBHOOK_SECRET,
},
}Pod spodem Medusa tworzy PaymentIntent przy inicjalizacji checkout:
await stripe.paymentIntents.create({
amount: cart.total,
currency: "pln",
automatic_payment_methods: {
enabled: true,
},
});Flaga automatic_payment_methods: true pozwala Stripe'owi dynamicznie dobierać dostępne metody płatności na podstawie lokalizacji klienta i konfiguracji konta — w Polsce oznacza to automatyczne pojawienie się BLIK-a i P24.
Dlaczego to zajmuje kilka godzin
Bo cały flow to:
Klient → checkout → Stripe → webhook → order paid
I koniec. Jeden merchant, jeden odbiorca, brak splitów, brak payout orchestration. Webhook payment_intent.succeeded trafia do backendu, Medusa oznacza zamówienie jako opłacone. Gotowe.
Kiedy PayU lub Przelewy24 mają sens
Przy dużym GMV — powyżej kilku milionów złotych miesięcznie — warto rozmawiać z PayU lub P24 o indywidualnych stawkach. Enterprise support, dedykowany opiekun, możliwość negocjacji prowizji. Ale: większy koszt utrzymania integracji, własna dokumentacja, własne webhooki, własne środowiska testowe. Dla startupu na wczesnym etapie to rzadko uzasadniony trade-off.
Część 2 — Marketplace: to nie jest płatność, to system finansowy
Model marketplace wygląda inaczej:
Klient → płaci → platforma → sprzedawcy
I właśnie ten środkowy krok — platforma — zmienia wszystko. Kiedy pieniądze klienta trafiają najpierw do Ciebie, a potem rozdzielasz je między sprzedawców, przestajesz być zwykłym sklepem. Stajesz się podmiotem przetwarzającym środki finansowe w imieniu osób trzecich. To ma konsekwencje prawne, compliance'owe i techniczne.
Co się zmienia w stosunku do sklepu
- Wielu odbiorców — każda transakcja może trafiać do innego sprzedawcy (lub kilku)
- Prowizje platformy — musisz wyciąć swoją część przed wypłatą
- Payouty — harmonogram wypłat, przetrzymywanie środków, powiązanie ze zwrotami
- KYC/AML — musisz weryfikować tożsamość sprzedawców
- Compliance — w zależności od modelu możesz potrzebować licencji instytucji płatniczej
W bazowej implementacji wygląda to następująco:

Problem z polskimi operatorami
Tu zaczyna się realna ściana. PayU i Przelewy24 oferują produkty marketplace (split payments, subkonta), ale ich procesy onboardingowe są zaprojektowane pod duże, ugruntowane firmy. Wymagania dokumentacyjne, czas weryfikacji, brak wsparcia dla startupów na wczesnym etapie — to nie jest teoria.
Konkretny case: zbudowany moduł PayU marketplace, kilka tygodni integracji, testy na środowisku sandbox — i odmowa współpracy na etapie produkcji. Projekt do kosza, harmonogram w rozsypce. To nie jest wyjątek. To wzorzec.
Stripe Connect jako rozwiązanie
Stripe Connect rozwiązuje ten problem przez przeniesienie compliance na siebie. Stripe weryfikuje sprzedawców (KYC), obsługuje AML, przechowuje środki i zarządza payoutami. Ty jako platforma nie musisz być instytucją płatniczą — Stripe jest nią za Ciebie. Dla marketplace w Polsce to często jedyna realna opcja na wczesnym etapie.
Typy kont w Stripe Connect
Standard — sprzedawca ma własne konto Stripe, sam zarządza ustawieniami. Najmniej kontroli po stronie platformy, ale też najmniej odpowiedzialności.
Express — optymalny wybór dla większości marketplace. Stripe dostarcza gotowy onboarding UI, obsługuje KYC, ale platforma zachowuje kontrolę nad payoutami i branding jest częściowo Twój. Sprzedawca widzi uproszczony dashboard.
Custom — pełna kontrola, pełna odpowiedzialność. Budujesz własny onboarding, własny dashboard, własne UX. Stripe działa w tle jako silnik. Droższe, bardziej skomplikowane, uzasadnione przy dużej skali.
Dla 90% marketplace startujących w Polsce: Express.
Modele płatności w Stripe Connect
Destination charges — płatność trafia do platformy, Stripe automatycznie transferuje część do sprzedawcy. Prosta implementacja, ale platforma jest stroną transakcji wobec klienta.
await stripe.paymentIntents.create({
amount: total,
currency: "pln",
application_fee_amount: platformFee,
transfer_data: {
destination: sellerStripeAccountId,
},
});Separate charges and transfers — płatność trafia do platformy, transfer do sprzedawcy jest osobną operacją. Więcej elastyczności (możesz transferować do wielu kont, opóźniać transfer, powiązać z fulfillment), ale też więcej kodu do napisania i więcej webhooków do obsłużenia.
Kiedy używać którego? Destination charges sprawdza się przy prostym modelu 1 zamówienie = 1 sprzedawca. Separate charges and transfers — gdy masz koszyk z produktami od wielu sprzedawców, złożone prowizje lub chcesz uzależnić transfer od statusu zamówienia.
Delayed payouts — przetrzymywanie środków
Stripe Connect pozwala konfigurować harmonogram wypłat na poziomie konta sprzedawcy. Możesz ustawić:
- Payout po N dniach od transakcji (np. 7 dni — czas na obsługę zwrotów)
- Payout manualny — platforma wyzwala wypłatę ręcznie lub programowo
- Payout automatyczny — Stripe wypłaca zgodnie z domyślnym harmonogramem
Delayed payouts to nie tylko wygoda — to mechanizm zarządzania ryzykiem. Jeśli klient zgłosi zwrot, masz czas na cofnięcie transferu zanim środki opuszczą platformę.
Webhooki w Stripe Connect
W modelu Connect musisz obsługiwać webhooki zarówno dla konta platformy, jak i dla kont połączonych (connected accounts). Kluczowe eventy:
account.updated— zmiana statusu onboardingu sprzedawcy (np. zakończenie KYC)payment_intent.succeeded— potwierdzenie płatnościtransfer.created— transfer do sprzedawcypayout.paid/payout.failed— status wypłaty do sprzedawcyaccount.application.deauthorized— sprzedawca odłączył konto
Webhooki dla connected accounts wymagają przekazania nagłówka Stripe-Account przy weryfikacji sygnatury — inaczej weryfikacja się nie powiedzie.
W marketplace Artovnia implementacja w uproszczeniu wygląda następująco:

Część 3 — Krytyczne detale, które bolą w produkcji
Refundy w marketplace
Refund w sklepie to prosta operacja: cofasz PaymentIntent, Stripe zwraca pieniądze klientowi. W marketplace to kaskada:
- Cofasz transfer do sprzedawcy (lub tworzysz reversal)
- Zwracasz pieniądze klientowi
- Obsługujesz prowizję platformy (czy ją zwracasz?)
Jeśli środki zdążyły trafić do sprzedawcy i zostały wypłacone na jego konto bankowe, Stripe nie może ich automatycznie cofnąć. Musisz mieć mechanizm rozliczeń z sprzedawcą — albo potrącenie z kolejnych payoutów, albo ręczna windykacja. To nie jest edge case — to scenariusz, który musisz zaprojektować przed uruchomieniem.
Idempotency keys
Każde żądanie do Stripe API, które tworzy lub modyfikuje zasób, powinno mieć idempotency_key. To string, który Stripe zapamiętuje przez 24 godziny — jeśli wyślesz to samo żądanie dwa razy z tym samym kluczem, Stripe zwróci wynik pierwszego wywołania bez tworzenia duplikatu.
await stripe.paymentIntents.create(
{
amount: total,
currency: "pln",
application_fee_amount: platformFee,
transfer_data: { destination: sellerStripeAccountId },
},
{
idempotencyKey: `order_${orderId}_payment`,
}
);Bez idempotency keys retry logic przy timeoutach sieciowych może skutkować podwójnymi płatnościami. W marketplace, gdzie jeden checkout może triggerować wiele operacji (PaymentIntent + transfer + payout schedule), to nie jest opcjonalne.
Webhooki jako source of truth
Nigdy nie polegaj na odpowiedzi z frontendu jako potwierdzeniu płatności. Klient może zamknąć przeglądarkę, stracić połączenie, dostać błąd JS — a płatność i tak mogła przejść. Jedynym wiarygodnym źródłem prawdy jest webhook payment_intent.succeeded odebrany przez backend.
Praktyczne konsekwencje:
- Backend musi być idempotentny na webhooki (ten sam event może przyjść kilka razy)
- Musisz weryfikować sygnaturę webhooka (
stripe.webhooks.constructEvent) - Kolejność eventów nie jest gwarantowana — projektuj state machine, nie sekwencję
Środowiska: test, live, Connect
Stripe ma osobne klucze API dla środowisk test i live — to oczywiste. Mniej oczywiste jest to, że w Stripe Connect każde connected account ma własne klucze i własne środowisko. Testowe connected accounts nie działają z live kluczami platformy i odwrotnie. Przy onboardingu sprzedawców w środowisku testowym używaj kont testowych Stripe (dostępnych przez dashboard) — nie możesz testować pełnego KYC flow na produkcji bez realnych danych.
Słownik pojęć — dla mniej technicznych czytelników
PaymentIntent
PaymentIntent to obiekt reprezentujący intencję pobrania płatności od klienta. Nie jest to sama płatność — to jej lifecycle manager. Stripe zaprojektował go pod asynchroniczne metody płatności: BLIK wymaga potwierdzenia w aplikacji bankowej, 3DS wymaga interakcji użytkownika, przelewy bankowe mogą czekać godzinami. PaymentIntent śledzi stan przez cały ten czas.
Stany, które musisz obsługiwać:
requires_payment_method— klient nie wybrał jeszcze metody płatnościrequires_action— wymagana dodatkowa akcja (3DS, BLIK confirmation)processing— płatność w toku (typowe dla BLIK i przelewów)succeeded— płatność zakończona sukcesemcanceled— anulowana (przez klienta lub timeout)requires_capture— przy płatnościach z manual capture (np. pre-autoryzacja)
W Medusa.js stan PaymentIntent jest synchronizowany przez webhooki — nie pollingujesz API.
Idempotency key
String przekazywany w nagłówku Idempotency-Key do Stripe API. Stripe zapamiętuje wynik żądania z danym kluczem przez 24 godziny. Kolejne żądania z tym samym kluczem zwracają cached response bez wykonywania operacji. Klucz powinien być unikalny per operacja, nie per sesja. Dobry pattern: {entityType}_{entityId}_{operation} — np. order_abc123_payment_create.
Webhook
HTTP POST wysyłany przez Stripe na Twój endpoint gdy zmienia się stan zasobu. Stripe gwarantuje dostarczenie (z retry), ale nie gwarantuje kolejności ani dokładnie jednego dostarczenia. Każdy webhook zawiera sygnaturę w nagłówku Stripe-Signature — weryfikuj ją zawsze, bez wyjątków. Niezweryfikowany webhook to potencjalny wektor ataku. W Stripe Connect webhooki mogą pochodzić z konta platformy lub z connected account. Te drugie zawierają pole account w payloadzie — musisz je rozróżniać w logice routingu.
Stripe Connect
System zarządzania kontami sprzedawców i przepływem środków między nimi. Stripe Connect to nie plugin — to osobna warstwa architektury, która: obsługuje onboarding i KYC sprzedawców (Stripe zbiera i weryfikuje dane), przechowuje środki w imieniu sprzedawców, zarządza payoutami na konta bankowe i przenosi odpowiedzialność compliance na Stripe. Dla marketplace w Polsce oznacza to, że nie musisz ubiegać się o licencję instytucji płatniczej — Stripe jest licencjonowaną instytucją i działa jako pośrednik. To nie jest detal — to fundament modelu prawnego całej platformy.
Podsumowanie — decyzja, którą podejmujesz raz
Stripe Connect nie jest "wygodną opcją" ani skrótem. To decyzja architektoniczna, która determinuje jak zbudujesz onboarding sprzedawców, jak zaprojektujesz flow płatności, jak obsłużysz zwroty i jak będziesz skalować.
To też decyzja prawna. Bez Stripe Connect lub podobnego rozwiązania (Mangopay, Adyen for Platforms) musisz sam zadbać o compliance — KYC, AML, przechowywanie środków, raportowanie. W Polsce oznacza to albo licencję KIP, albo współpracę z licencjonowanym partnerem. Żaden z polskich operatorów nie ułatwia tego startupom.
I wreszcie — to często jedyna realna opcja dla marketplace w Polsce na wczesnym etapie. Nie dlatego, że Stripe jest najlepszy we wszystkim. Dlatego, że alternatywy albo nie obsługują modelu marketplace, albo wymagają skali i zasobów, których startup nie ma.
Jeśli budujesz marketplace i zastanawiasz się, czy "da się to zrobić prościej" — odpowiedź brzmi: nie. Ale da się to zrobić mądrze. I to jest właśnie ta różnica.
Możesz skorzystać z mojego doświadczenia w budowaniu e-commerce i umówić się na bezpłatną konsultację.


