{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-simpay-flow/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition","tabs","tab"]},"type":"markdown"},"seo":{"title":"Webhooki","description":"Znajdziesz tutaj wszystkie niezbędne informacje dotyczące integracji i obsługi systemu płatności SimPay.pl","siteUrl":"https://docs.simpay.pl","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"webhooki","__idx":0},"children":["Webhooki"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["W SimPay Flow działają dwa niezależne rodzaje powiadomień:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Rodzaj"},"children":["Rodzaj"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Czego dotyczy"},"children":["Czego dotyczy"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Domyślny adres i klucz"},"children":["Domyślny adres i klucz"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Webhooki Flow"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Zmiany statusów submerchantów, ich kanałów płatności i wypłat"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Adres i klucz ustawione w usłudze Flow w Panelu Partnera SimPay"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Webhooki płatności (IPN)"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Transakcje, zwroty, kody BLIK, subskrypcje i aliasy BLIK submerchantów - ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/notifications/payment"},"children":["standardowe powiadomienia IPN"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Adres i klucz IPN usługi nadrzędnej"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Dla każdego submerchanta możesz nadpisać oba adresy - zobacz ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#w%C5%82asne-adresy-dla-submerchanta"},"children":["Własne adresy dla submerchanta"]},"."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"webhooki-flow","__idx":1},"children":["Webhooki Flow"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"struktura-powiadomienia","__idx":2},"children":["Struktura powiadomienia"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Webhooki Flow są wysyłane metodą ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}," jako JSON, z nagłówkiem ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["User-Agent: SimPay-IPN/2.0"]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"type\": \"flow_submerchant_withdraw:status_changed\",\n  \"webhook_id\": \"0199a6c2-5f3e-7d21-8b4a-2c3d4e5f6a7b\",\n  \"attempt\": 0,\n  \"flow_service\": {\n    \"id\": \"flow_aaaabbbb\",\n    \"name\": \"Moja platforma\"\n  },\n  \"date\": \"2026-10-01T12:00:00+02:00\",\n  \"data\": {\n    \"id\": \"0199a5f0-2b8c-7c1e-9e3a-1f2b3c4d5e6f\",\n    \"short_id\": \"1f2b3c4d\",\n    \"amount\": 150.5,\n    \"created_at\": \"2026-10-01T10:00:00+02:00\",\n    \"updated_at\": \"2026-10-01T12:00:00+02:00\",\n    \"wallet\": {\n      \"id\": \"0199a5f0-1111-7c1e-9e3a-1f2b3c4d5e6f\",\n      \"currency\": \"PLN\"\n    },\n    \"status\": {\n      \"previous\": \"accepted\",\n      \"current\": \"done\"\n    },\n    \"submerchant\": {\n      \"id\": \"flsm_aaaabbbb\",\n      \"custom_id\": \"user-123\"\n    }\n  },\n  \"signature\": \"eb4f27ad689b4613fd7cbeff1aa7b130b5cbe00e6fe3bc93772fb72fa037e472\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Pole"},"children":["Pole"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Opis"},"children":["Opis"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Typ zdarzenia (patrz niżej)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["webhook_id"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Unikalne ID powiadomienia (UUID). Każda kolejna próba wysyłki ma nowe ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["webhook_id"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["attempt"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Numer próby wysyłki, liczony od ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["flow_service.id"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["ID usługi Flow"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["flow_service.name"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Nazwa usługi Flow"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["date"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Data wysłania powiadomienia (ISO 8601)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["data"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Dane zdarzenia - zależne od ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signature"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Sygnatura SHA-256 - zobacz ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#weryfikacja-sygnatury"},"children":["Weryfikacja sygnatury"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"odpowiedź","__idx":3},"children":["Odpowiedź"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Powiadomienie uznajemy za dostarczone, gdy Twój serwer odpowie:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["kodem ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["200"]}," z treścią ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["OK"]},", lub"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["kodem ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["202"]}," albo ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["204"]},"."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Każda inna odpowiedź, błąd połączenia lub przekroczenie czasu (5 s na połączenie, 15 s na odpowiedź) oznacza nieudaną próbę."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"ponowienia","__idx":4},"children":["Ponowienia"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Nieudane powiadomienia są ponawiane - maksymalnie ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["30 prób"]},":"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Próby"},"children":["Próby"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Odstęp między próbami"},"children":["Odstęp między próbami"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["1-10"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["ok. 1 minuty"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["11-15"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["ok. 5 minut"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["16-20"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["ok. 30 minut"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["21-30"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["ok. 1 godziny"]}]}]}]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Wysyłamy tylko aktualny stan"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Jeśli przed ponowieniem stan obiektu zmieni się ponownie (np. wypłata przejdzie z ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["accepted"]}," na ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["done"]},"), nieaktualne powiadomienie nie zostanie już wysłane - otrzymasz tylko powiadomienie o najnowszej zmianie. Dlatego zawsze traktuj ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["current"]}," jako aktualny stan, a nie zakładaj, że otrzymasz każdą pośrednią zmianę."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Historię wysłanych webhooków (wraz z odpowiedziami Twojego serwera) znajdziesz w Panelu Partnera SimPay, w ustawieniach usługi Flow. Stamtąd możesz też wysłać powiadomienie testowe."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"zdarzenia-flow","__idx":5},"children":["Zdarzenia Flow"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"flow_submerchantstatus_changed","__idx":6},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["flow_submerchant:status_changed"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Zmienił się status submerchanta - np. po przekazaniu danych w onboardingu, po akceptacji przez SimPay lub po zablokowaniu konta."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"\"data\": {\n  \"submerchant\": {\n    \"id\": \"flsm_aaaabbbb\",\n    \"custom_id\": \"user-123\"\n  },\n  \"previous\": {\n    \"status\": \"client_verify\",\n    \"aml_level\": 1,\n    \"aml_status\": \"sent\",\n    \"fully_active\": false\n  },\n  \"current\": {\n    \"status\": \"client_active\",\n    \"aml_level\": 2,\n    \"aml_status\": \"accepted\",\n    \"fully_active\": true\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Pole"},"children":["Pole"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Opis"},"children":["Opis"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Status konta submerchanta w SimPay (np. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client_new"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client_verify"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client_active"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client_block"]},")"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["aml_level"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Poziom weryfikacji AML (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["2"]}," - pełna weryfikacja)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["aml_status"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Status weryfikacji AML (np. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sent"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["accepted"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["declined"]},")"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fully_active"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]},", gdy submerchant jest w pełni aktywny i może przyjmować płatności"]}]}]}]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Wskazówka"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Do decyzji, czy submerchant może przyjmować płatności, używaj pola ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["current.fully_active"]},". Pozostałe pola mają charakter informacyjny."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"flow_submerchant_payment_channelstatus_changed","__idx":7},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["flow_submerchant_payment_channel:status_changed"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Zmienił się status kanału płatności submerchanta - np. kanał wysłany do weryfikacji został zaakceptowany lub odrzucony, zmienił się status BLIK OneClick lub aktywne modele BLIK Płatności Powtarzalnych."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"\"data\": {\n  \"submerchant\": {\n    \"id\": \"flsm_aaaabbbb\",\n    \"custom_id\": \"user-123\"\n  },\n  \"channel\": {\n    \"slug\": \"blik-level0\",\n    \"name\": \"BLIK Level 0\"\n  },\n  \"previous\": {\n    \"status\": \"active\",\n    \"blik_one_click_status\": \"REGISTERED_WAITING_ACTIVATION\",\n    \"blik_recurrent_a\": null,\n    \"blik_recurrent_m\": null,\n    \"blik_recurrent_o\": null\n  },\n  \"current\": {\n    \"status\": \"active\",\n    \"blik_one_click_status\": \"ACTIVE\",\n    \"blik_recurrent_a\": null,\n    \"blik_recurrent_m\": null,\n    \"blik_recurrent_o\": null\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Pole"},"children":["Pole"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Opis"},"children":["Opis"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["channel.slug"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["ID kanału płatności (to samo co ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["id"]}," w ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/apis/flow/flowgetsubmerchantpaymentchannels"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET .../payment-channels"]}]},")"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Status kanału: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["new"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["in_progress"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["active"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rejected"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["blik_one_click_status"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Status BLIK OneClick (tylko ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["blik-level0"]},"): ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PENDING_REGISTRATION"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["REGISTERED_WAITING_ACTIVATION"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ACTIVE"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["REJECTED"]}," lub ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["blik_recurrent_a"]}," / ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["_m"]}," / ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["_o"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Czy model BLIK Płatności Powtarzalnych AUTO / MANUAL / OPEN jest aktywny (tylko ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["blik-recurrent"]},") lub ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"flow_submerchant_withdrawstatus_changed","__idx":8},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["flow_submerchant_withdraw:status_changed"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Zmienił się status wypłaty submerchanta. Przykład ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["data"]}," - patrz ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#struktura-powiadomienia"},"children":["Struktura powiadomienia"]},"."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Pole"},"children":["Pole"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Opis"},"children":["Opis"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["id"]}," / ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["short_id"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["ID wypłaty (UUID) i krótkie ID wypłaty"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["amount"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Kwota wypłaty"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["wallet.id"]}," / ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["wallet.currency"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Portfel, z którego realizowana jest wypłata, i jego waluta"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status.previous"]}," / ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status.current"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Poprzedni i aktualny status wypłaty: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["new"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["accepted"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["waiting"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["done"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rejected"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"flowtest","__idx":9},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["flow:test"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Powiadomienie testowe wysyłane z Panelu Partnera. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["data"]}," zawiera tylko losowe pole ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nonce"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"\"data\": {\n  \"nonce\": \"01K6FZ8X3Q9V2N7M4T5R1W0YAB\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"weryfikacja-sygnatury","__idx":10},"children":["Weryfikacja sygnatury"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Każdy webhook Flow zawiera pole ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signature"]}," - hash ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["SHA-256"]}," (lowercase hex). Zasada jest taka sama jak w ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/notifications/payment/signature"},"children":["powiadomieniach płatności"]},":"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["weź ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["wszystkie wartości"]}," z powiadomienia (bez pola ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signature"]},") w kolejności, w jakiej występują w JSON, spłaszczając zagnieżdżone obiekty,"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["połącz je separatorem ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["|"]},","]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["dołącz na końcu klucz webhooków Flow,"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["policz SHA-256 i porównaj z ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signature"]}," bezpieczną funkcją porównującą."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"text","header":{"controls":{"copy":{}}},"source":"type|webhook_id|attempt|flow_service.id|flow_service.name|date|data_value1|...|data_valueN|KLUCZ_WEBHOOKÓW_FLOW\n","lang":"text"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Wartości logiczne, null i liczby"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["W odróżnieniu od powiadomień płatności webhooki Flow zawierają wartości ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]},"/",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," i liczby. Przed połączeniem zamień je na tekst tak jak PHP:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]}," → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["1"]},","]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]}," → pusty ciąg,"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," → pusty ciąg,"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["liczby → zapis bez zbędnych zer (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["2"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["150.5"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["100"]}," dla ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["100.0"]},")."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["W JavaScript ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["String(true)"]}," daje ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"true\""]},", a w Pythonie ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["str(True)"]}," daje ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"True\""]}," - bez konwersji sygnatura się nie zgodzi."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Klucz:"]}," jeśli submerchant ma ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#w%C5%82asne-adresy-dla-submerchanta"},"children":["własny adres webhooków Flow"]},", powiadomienia o nim są podpisywane jego kluczem. W pozostałych przypadkach - kluczem webhooków ustawionym w usłudze Flow."]},{"$$mdtype":"Tag","name":"details","attributes":{},"children":[{"$$mdtype":"Tag","name":"summary","attributes":{},"children":["Zobacz wyliczenie sygnatury dla przykładu powyżej"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Klucz: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FLOW_WEBHOOK_KEY_64"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"text","header":{"controls":{"copy":{}}},"source":"flow_submerchant_withdraw:status_changed|0199a6c2-5f3e-7d21-8b4a-2c3d4e5f6a7b|0|flow_aaaabbbb|Moja platforma|2026-10-01T12:00:00+02:00|0199a5f0-2b8c-7c1e-9e3a-1f2b3c4d5e6f|1f2b3c4d|150.5|2026-10-01T10:00:00+02:00|2026-10-01T12:00:00+02:00|0199a5f0-1111-7c1e-9e3a-1f2b3c4d5e6f|PLN|accepted|done|flsm_aaaabbbb|user-123|FLOW_WEBHOOK_KEY_64\n","lang":"text"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["SHA-256: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["eb4f27ad689b4613fd7cbeff1aa7b130b5cbe00e6fe3bc93772fb72fa037e472"]}]}]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"div","attributes":{"label":"PHP","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"php","header":{"controls":{"copy":{}}},"source":"<?php\n\nfunction simpayFlowSignatureValid(array $payload, string $key): bool\n{\n    $signature = $payload['signature'] ?? '';\n    unset($payload['signature']);\n\n    $values = [];\n    array_walk_recursive($payload, function ($value) use (&$values) {\n        $values[] = $value;\n    });\n    $values[] = $key;\n\n    // implode() zamienia true na \"1\", a false i null na pusty ciąg\n    return hash_equals(hash('sha256', implode('|', $values)), $signature);\n}\n\n$payload = json_decode(file_get_contents('php://input'), true);\n\nif (!is_array($payload) || !simpayFlowSignatureValid($payload, 'KLUCZ_WEBHOOKÓW_FLOW')) {\n    http_response_code(403);\n    exit('INVALID_SIGNATURE');\n}\n\n// obsługa zdarzenia $payload['type']\n\necho 'OK';\n","lang":"php"},"children":[]}]},{"$$mdtype":"Tag","name":"div","attributes":{"label":"Node","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"js","header":{"controls":{"copy":{}}},"source":"const crypto = require('crypto');\n\nfunction toPhpString(value) {\n    if (value === true) return '1';\n    if (value === false || value === null) return '';\n    return String(value);\n}\n\nfunction flatten(value, result = []) {\n    if (value !== null && typeof value === 'object') {\n        Object.values(value).forEach((item) => flatten(item, result));\n    } else {\n        result.push(toPhpString(value));\n    }\n    return result;\n}\n\nfunction simpayFlowSignatureValid(payload, key) {\n    const { signature, ...rest } = payload;\n    if (typeof signature !== 'string' || !/^[0-9a-f]{64}$/.test(signature)) {\n        return false;\n    }\n\n    const values = flatten(rest);\n    values.push(key);\n\n    const expected = crypto.createHash('sha256').update(values.join('|')).digest('hex');\n\n    return crypto.timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(signature, 'hex'));\n}\n\n// Express.js\napp.post('/webhooks/simpay/flow', express.json(), (req, res) => {\n    if (!simpayFlowSignatureValid(req.body, process.env.SIMPAY_FLOW_WEBHOOK_KEY)) {\n        return res.status(403).send('INVALID_SIGNATURE');\n    }\n\n    // obsługa zdarzenia req.body.type\n\n    res.send('OK');\n});\n","lang":"js"},"children":[]}]},{"$$mdtype":"Tag","name":"div","attributes":{"label":"Python","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"import hashlib\nimport hmac\n\n\ndef to_php_string(value) -> str:\n    if value is True:\n        return '1'\n    if value is False or value is None:\n        return ''\n    if isinstance(value, float) and value.is_integer():\n        return str(int(value))\n    return str(value)\n\n\ndef flatten(value, result):\n    if isinstance(value, dict):\n        for item in value.values():\n            flatten(item, result)\n    elif isinstance(value, list):\n        for item in value:\n            flatten(item, result)\n    else:\n        result.append(to_php_string(value))\n    return result\n\n\ndef simpay_flow_signature_valid(payload: dict, key: str) -> bool:\n    data = {k: v for k, v in payload.items() if k != 'signature'}\n    values = flatten(data, [])\n    values.append(key)\n\n    expected = hashlib.sha256('|'.join(values).encode()).hexdigest()\n\n    return hmac.compare_digest(expected, payload.get('signature', ''))\n","lang":"python"},"children":[]}]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"webhooki-płatności-ipn-w-simpay-flow","__idx":11},"children":["Webhooki płatności (IPN) w SimPay Flow"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Powiadomienia o transakcjach, zwrotach, kodach BLIK, subskrypcjach i aliasach BLIK submerchantów to ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/notifications/payment"},"children":["standardowe powiadomienia IPN"]}," - z tą samą strukturą i tym samym sposobem ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/notifications/payment/signature"},"children":["wyliczania sygnatury"]},". W SimPay Flow różnią się kilkoma szczegółami."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"adres-i-klucz","__idx":12},"children":["Adres i klucz"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Sytuacja"},"children":["Sytuacja"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Adres"},"children":["Adres"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Klucz do sygnatury"},"children":["Klucz do sygnatury"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Submerchant ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["nie ma"]}," własnego adresu IPN"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Adres IPN usługi nadrzędnej"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Klucz IPN usługi nadrzędnej"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Submerchant ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["ma"]}," własny adres IPN"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Własny adres submerchanta"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Klucz IPN submerchanta (zwrócony przy ustawianiu adresu)"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Dzięki temu w podstawowej konfiguracji obsługujesz powiadomienia wszystkich submerchantów jednym endpointem i jednym kluczem - tym samym, którego używasz dla usługi nadrzędnej."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"service_id","__idx":13},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["service_id"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["We ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["wszystkich"]}," powiadomieniach płatności dotyczących submerchantów (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction:status_changed"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction_refund:status_changed"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction_blik_level0:code_status_changed"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["subscription:status_changed"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["blik:alias_status_changed"]},") pole ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["service_id"]}," zawiera ID ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["usługi nadrzędnej"]}," - tej, którą podajesz w ścieżce ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/payment/{serviceId}/..."]},". Wewnętrzna usługa submerchanta nigdy nie pojawia się w powiadomieniach."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"obiekt-dataflow","__idx":14},"children":["Obiekt ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["data.flow"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Każde powiadomienie płatności dotyczące submerchanta (wszystkie zdarzenia poza ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ipn:test"]},") zawiera w ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["data"]}," obiekt ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["flow"]},". Dla zwykłych usług Płatności Online obiekt nie występuje."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Pole"},"children":["Pole"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Opis"},"children":["Opis"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["flow.submerchant_id"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["ID submerchanta (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["flsm_..."]},")"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["flow.submerchant_custom_id"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["customId"]}," submerchanta"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["flow.flow_service_id"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["ID usługi Flow"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Ponieważ ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["service_id"]}," wskazuje usługę nadrzędną, to właśnie obiekt ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["flow"]}," pozwala przypisać transakcję, zwrot, subskrypcję czy alias do właściwego submerchanta w Twoim systemie."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"\"flow\": {\n  \"submerchant_id\": \"flsm_aaaabbbb\",\n  \"submerchant_custom_id\": \"user-123\",\n  \"flow_service_id\": \"flow_aaaabbbb\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"zmiany-w-transactionstatus_changed","__idx":15},"children":["Zmiany w ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction:status_changed"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Dodatkowo w zdarzeniu ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transaction:status_changed"]}," pojawia się pole ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["amount.commission_flow"]}]}," - Twoja prowizja Flow od transakcji (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["string"]},", format ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["%.2f"]},"). Występuje tylko, gdy prowizja jest większa od zera."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"type\": \"transaction:status_changed\",\n  \"notification_id\": \"0199a6d0-1234-7abc-9def-0123456789ab\",\n  \"date\": \"2026-10-01T12:05:00+02:00\",\n  \"data\": {\n    \"id\": \"0199a6cf-aaaa-7bbb-8ccc-0123456789ab\",\n    \"payer_transaction_id\": \"Q68KLAKN\",\n    \"service_id\": \"252b85c9\",\n    \"status\": \"transaction_paid\",\n    \"amount\": {\n      \"final_currency\": \"PLN\",\n      \"final_value\": \"49.99\",\n      \"original_currency\": \"PLN\",\n      \"original_value\": \"49.99\",\n      \"commission_system\": \"0.60\",\n      \"commission_partner\": \"49.14\",\n      \"commission_currency\": \"PLN\",\n      \"commission_flow\": \"0.25\"\n    },\n    \"control\": \"order-1001\",\n    \"payment\": {\n      \"channel\": \"blik\",\n      \"type\": \"blik\"\n    },\n    \"customer\": {\n      \"country_code\": \"PL\"\n    },\n    \"paid_at\": \"2026-10-01T12:04:58+02:00\",\n    \"created_at\": \"2026-10-01T12:03:10+02:00\",\n    \"flow\": {\n      \"submerchant_id\": \"flsm_aaaabbbb\",\n      \"submerchant_custom_id\": \"user-123\",\n      \"flow_service_id\": \"flow_aaaabbbb\"\n    }\n  },\n  \"signature\": \"...\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Sygnatura obejmuje nowe pola"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Pola ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["commission_flow"]}," i ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["flow"]}," biorą udział w wyliczaniu sygnatury jak każde inne pole obiektu ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["data"]},". Jeśli Twój walidator dynamicznie spłaszcza cały payload (tak jak w ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/notifications/payment/signature"},"children":["przykładach"]},"), nie musisz niczego zmieniać."]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"własne-adresy-dla-submerchanta","__idx":16},"children":["Własne adresy dla submerchanta"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Domyślnie wszystkie powiadomienia trafiają na adresy wspólne dla całej usługi. Dla wybranego submerchanta możesz ustawić osobne adresy - np. gdy każdy z Twoich Klientów ma własną instancję aplikacji."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Aktualne ustawienia pobierzesz przez ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/apis/flow/flowgetsubmerchantwebhooks"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET .../submerchants/{submerchantId}/webhooks"]}]},", a zmienisz je przez ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/apis/flow/flowupdatesubmerchantwebhooks"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PATCH .../submerchants/{submerchantId}/webhooks"]}]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -X PATCH \"https://api.simpay.pl/flow/{flowServiceId}/submerchants/user-123/webhooks\" \\\n  -H \"Authorization: Bearer TWÓJ_TOKEN_API\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"flow\": { \"customUrl\": \"https://klient-123.example.com/webhooks/flow\" },\n    \"payment\": { \"customUrl\": \"https://klient-123.example.com/webhooks/ipn\" }\n  }'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"success\": true,\n  \"data\": {\n    \"paymentNewIpnKey\": \"aVeryLongAndSecureKeyFor32Chars0\",\n    \"flowNewIpnKey\": \"...\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Zapisz klucze z odpowiedzi"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Przy pierwszym ustawieniu własnego adresu SimPay generuje dla submerchanta ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["osobny klucz"]}," do weryfikacji sygnatury powiadomień. Klucz jest zwracany ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["tylko raz"]}," - w odpowiedzi na to żądanie. Przy kolejnych zmianach adresu klucz się nie zmienia, a pole w odpowiedzi ma wartość ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]},"."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Aby wrócić do adresu domyślnego, wyślij ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{\"flow\": {\"useDefault\": true}}"]}," (lub ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment"]},"). Własny adres i klucz submerchanta zostaną usunięte, a powiadomienia wrócą na adres i klucz usługi."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"nowy-klucz","__idx":17},"children":["Nowy klucz"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Jeśli klucz wyciekł lub go zgubiłeś, wygeneruj nowy przez ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/apis/flow/flowupdatesubmerchantwebhookkey"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PATCH .../webhooks/key"]}]}," z ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{\"type\": \"flow\"}"]}," lub ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{\"type\": \"payment\"}"]},". Działa to tylko dla submerchantów z własnym adresem webhooków danego typu. Po wygenerowaniu nowego klucza poprzedni przestaje być używany."]}]},"headings":[{"value":"Webhooki","id":"webhooki","depth":1},{"value":"Webhooki Flow","id":"webhooki-flow","depth":2},{"value":"Struktura powiadomienia","id":"struktura-powiadomienia","depth":3},{"value":"Odpowiedź","id":"odpowiedź","depth":3},{"value":"Ponowienia","id":"ponowienia","depth":3},{"value":"Zdarzenia Flow","id":"zdarzenia-flow","depth":2},{"value":"flow_submerchant:status_changed","id":"flow_submerchantstatus_changed","depth":3},{"value":"flow_submerchant_payment_channel:status_changed","id":"flow_submerchant_payment_channelstatus_changed","depth":3},{"value":"flow_submerchant_withdraw:status_changed","id":"flow_submerchant_withdrawstatus_changed","depth":3},{"value":"flow:test","id":"flowtest","depth":3},{"value":"Weryfikacja sygnatury","id":"weryfikacja-sygnatury","depth":2},{"value":"Webhooki płatności (IPN) w SimPay Flow","id":"webhooki-płatności-ipn-w-simpay-flow","depth":2},{"value":"Adres i klucz","id":"adres-i-klucz","depth":3},{"value":"service_id","id":"service_id","depth":3},{"value":"Obiekt data.flow","id":"obiekt-dataflow","depth":3},{"value":"Zmiany w transaction:status_changed","id":"zmiany-w-transactionstatus_changed","depth":3},{"value":"Własne adresy dla submerchanta","id":"własne-adresy-dla-submerchanta","depth":2},{"value":"Nowy klucz","id":"nowy-klucz","depth":3}],"frontmatter":{"seo":{"title":"Webhooki"}},"lastModified":"2026-10-01T15:18:54.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/simpay-flow/webhooks","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}