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".
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łówek | Wartość |
|---|---|
Content-Type | application/json |
User-Agent | SimPay-IPN/2.0 |
Aby Twój system mógł prawidłowo odbierać powiadomienia od SimPay, musi spełniać kilka rygorystycznych warunków technicznych:
- 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. - 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.
- Poprawna odpowiedź HTTP: Oczekujemy konkretnej odpowiedzi potwierdzającej odebranie żądania. Twój serwer musi zwrócić jedną z poniższych opcji:
- Status
HTTP 200 OKz nagłówkiemContent-Type: text/plainoraz ciałem odpowiedzi zawierającym wyłącznie słowoOK. - Status
HTTP 202 AcceptedlubHTTP 204 No Content(bez ciała odpowiedzi / pusty response).
- Status
Aby zapewnić maksymalne bezpieczeństwo i wydajność, rekomendujemy obsługę każdego przychodzącego powiadomienia w dokładnie takiej kolejności:
- Weryfikacja adresu IP – sprawdź, czy adres IP nadawcy znajduje się na naszej liście autoryzowanych adresów. Odrzuć żądanie, jeśli IP nie pasuje.
- 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. - Rozpoznanie typu (routing) – odczytaj wartość z pola
typei na jej podstawie oddeleguj dane (z obiektudata) do asynchronicznej kolejki w Twoim systemie (Queue/Worker). - 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.
Gdy Twój endpoint odbierze żądanie, jego ciało (body) będzie zawierać następujące pola:
| Pole | Typ | Opis |
|---|---|---|
type | string (Enum) | Typ przesyłanego zdarzenia (np. transaction:status_changed). Na jego podstawie wiesz, jakiego schematu spodziewać się w polu data. |
notification_id | char(36) | Unikalny identyfikator (UUID) konkretnej notyfikacji. Pozwala na zapobieganie przetwarzaniu tego samego powiadomienia wielokrotnie. |
date | string (ISO 8601) | Data i godzina wygenerowania/wysyłki notyfikacji przez nasz system (np. 2025-05-20T16:36:07Z). |
data | object | Obiekt zawierający szczegółowe dane biznesowe dotyczące konkretnego zdarzenia. |
signature | string | Podpis kryptograficzny (hash SHA-256) wygenerowany z wartości pól. Służy do weryfikacji autentyczności powiadomienia. |
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"
}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.