Przejdź do treści
Ostatnia aktualizacja

Struktura i obsługa powiadomienia IPN

Każde powiadomienie IPN (Webhook) wysyłane przez system SimPay posiada spójną, bazową strukturę. Niezależnie od tego, jakiego zdarzenia dotyczy powiadomienie (np. dokonana wpłata czy zwrot), przesyłane żądanie zawsze składa się z tych samych nagłówków HTTP oraz głównych elementów JSON – swoistej "koperty".


Nagłówki HTTP (Headers)

Każde żądanie POST wysyłane przez nasze serwery będzie zawierało następujące nagłówki. Zwróć uwagę na User-Agent, który może posłużyć jako pierwszy, wstępny (choć niewystarczający do pełnego bezpieczeństwa) filtr odrzucający ruch z botów:

NagłówekWartość
Content-Typeapplication/json
User-AgentSimPay-IPN/2.0

Wymagania techniczne

Aby Twój system mógł prawidłowo odbierać powiadomienia od SimPay, musi spełniać kilka rygorystycznych warunków technicznych:

  1. Dostępność publiczna: Twój endpoint IPN musi być wystawiony w publicznej sieci Internet. Powiadomienia nie dotrą na środowiska lokalne (localhost), chyba że użyjesz narzędzi typu ngrok.
  2. Szybka odpowiedź: Czas oczekiwania naszego serwera na odpowiedź jest ograniczony. Ciężkie operacje (wysyłka e-maili, generowanie PDF) bezwzględnie deleguj do systemów kolejkowych pracujących w tle.
  3. Poprawna odpowiedź HTTP: Oczekujemy konkretnej odpowiedzi potwierdzającej odebranie żądania. Twój serwer musi zwrócić jedną z poniższych opcji:
    • Status HTTP 200 OK z nagłówkiem Content-Type: text/plain oraz ciałem odpowiedzi zawierającym wyłącznie słowo OK.
    • Status HTTP 202 Accepted lub HTTP 204 No Content (bez ciała odpowiedzi / pusty response).

Rekomendowana kolejność obsługi

Aby zapewnić maksymalne bezpieczeństwo i wydajność, rekomendujemy obsługę każdego przychodzącego powiadomienia w dokładnie takiej kolejności:

  1. Weryfikacja adresu IP – sprawdź, czy adres IP nadawcy znajduje się na naszej liście autoryzowanych adresów. Odrzuć żądanie, jeśli IP nie pasuje.
  2. Weryfikacja sygnatury – przelicz hash z otrzymanych danych i porównaj go z polem signature. Zyskasz 100% pewności, że nikt nie zmodyfikował ładunku w locie.
  3. Rozpoznanie typu (routing) – odczytaj wartość z pola type i na jej podstawie oddeleguj dane (z obiektu data) do asynchronicznej kolejki w Twoim systemie (Queue/Worker).
  4. Zakończenie połączenia – natychmiast po wysłaniu zadania w tło, zwróć do nas poprawną odpowiedź (np. 200 OK text/plain), zamykając połączenie z serwerem SimPay.

Struktura JSON (Koperta)

Gdy Twój endpoint odbierze żądanie, jego ciało (body) będzie zawierać następujące pola:

PoleTypOpis
typestring (Enum)Typ przesyłanego zdarzenia (np. transaction:status_changed). Na jego podstawie wiesz, jakiego schematu spodziewać się w polu data.
notification_idchar(36)Unikalny identyfikator (UUID) konkretnej notyfikacji. Pozwala na zapobieganie przetwarzaniu tego samego powiadomienia wielokrotnie.
datestring (ISO 8601)Data i godzina wygenerowania/wysyłki notyfikacji przez nasz system (np. 2025-05-20T16:36:07Z).
dataobjectObiekt zawierający szczegółowe dane biznesowe dotyczące konkretnego zdarzenia.
signaturestringPodpis kryptograficzny (hash SHA-256) wygenerowany z wartości pól. Służy do weryfikacji autentyczności powiadomienia.

Przykładowe żądanie (Request)

POST /twoj-endpoint-ipn HTTP/1.1
Host: twoj-sklep.pl
Content-Type: application/json
User-Agent: SimPay-IPN/2.0

// przesyłane body nie jest formatowane (nie zawiera spacji, nowych linii itp.)
{
  "type": "transaction:status_changed",
  "notification_id": "0196fec6-7a61-7219-9458-bcc45237c252",
  "date": "2025-05-23T22:12:22+02:00",
  "data": {
    "id": "dbc87423-b121-4ad4-977f-b63c3d3831e8",
    "payer_transaction_id": "Q68KLAKN",
    "service_id": "e65c7519",
    "status": "transaction_failure",
    "amount": {
      "final_currency": "PLN",
      "final_value": "8.00",
      "original_currency": "PLN",
      "original_value": "8.00",
      "commission_system": "0.06",
      "commission_partner": "7.94",
      "commission_currency": "PLN"
    },
    "control": "3e63e31d-f08d-4942-a223-3bad2dce8096",
    "payment": {
      "channel": "blik",
      "type": "blik"
    },
    "customer": {
      "country_code": null
    },
    "created_at": "2024-08-10T15:41:50+02:00"
  },
  "signature": "095a7be5d77c4bab667dbd0f35d9b1cb0c9cec50d8af42842cc37a95b233925e"
}

Co dalej?

Kiedy znasz już bazową strukturę, czas wdrożyć zabezpieczenia i zapoznać się z konkretnymi danymi, które wysyłamy:

👉 Weryfikacja sygnatury i bezpieczeństwo – dowiedz się, jak poprawnie wyliczyć i zweryfikować hash w kroku 2.

👉 Zdarzenie: transaction:status_changed – zobacz strukturę pola data dla najważniejszego eventu dotyczącego opłacenia transakcji.