Obsługa notyfikacji Płatności Online (IPN v2)
Notyfikacje wysyłane są metodą POST za pomocą Content-Type application/json. Każda notyfikacja musi zwrócić w response jako plaintext odpowiedź OK
ze statusem HTTP 200
.
Struktura notyfikacji
Pole | Typ | Opis |
---|---|---|
type | Enum | Przesyłany event, pełna lista poniżej |
notification_id | char(36) | Unikalne ID notyfikacji |
date | date (ISO 8601) | Data i godzina wysyłki notyfikacji w formacie ISO 8601 (np. 2025-05-20T16:36:07Z ) |
data | Obiekt | Dane przesyłane w tym evencie |
signature | string | Wyliczona sygnatura, szczegóły poniżej |
Wyliczanie sygnatury
Sygnature generujemy za pomocą zestawienia ze sobą wartości pola type
, notification_id
, wszystkich odebranych parametrów (oprócz signature) do API w kolejności z tabel poniżej, oddzielając je seperatorem |
i dodając na końcu klucz dostępny w Panelu Klienta w usłudze. Hashowanie musi odbyć się za pomocą sha256.
Bazowo ciąg do zahashowania powinnien wyglądać tak:
type|notification_id|date|data_value1|data_value2|data_valueN|key
Wartości z pola data
powinny być dołączane do sygnatury w takiej kolejności, jak zostały wypisane w dokumentacji.
Przykładowy sposób generowania sygnatury dla poniższych przykładowych danych:
type
= example:typenotification_id
= 0196bf93-aca4-7253-8a2d-0941a037f25bdate
= 2025-05-20T16:36:07Zdata
ma pola:status
= transaction_paidamount
(obiekt)amount.currency
= PLNamount.value
= 5.25
transaction_id
= 123123123123meta
= test
key
= keyFromPanel
Łącząc wszystkie elementy prawidłowo będzie wyglądać tak:
example:type|0196bf93-aca4-7253-8a2d-0941a037f25b|2025-05-20T16:36:07Z|transaction_paid|PLN|5.25|123123123123|test|keyFromPanel
Jeśli jakieś pole w dokumentacji informuje nas o tym, że może nie występować jeśli np. nie został przekazany podczas inicjacji płatności to pomijamy całkowicie ten element podczas generowania sygnatury.
Patrząc na przykład, załóżmy, że pole meta
może nie występować i faktycznie nie występuje. W takim przypadku konkatenacja elementów będzie wyglądać tak:
example:type|0196bf93-aca4-7253-8a2d-0941a037f25b|2025-05-20T16:36:07Z|transaction_paid|PLN|5.25|123123123123|keyFromPanel
Tak przygotowany łańcuch znaków przekazujemy funkcji hashującej sha256. SimPay przesyła sygnaturę jako string lower-case.
Przykład generowania wartości sygnatury w wybranych językach i SDK:
<?php
class SimPaySignatureValidator
{
public function isValid(): bool
{
$payload = json_decode(@file_get_contents('php://input'), true);
if (empty($payload)) {
return false;
}
$data = $this->flattenArray($payload);
$data[] = 'KLUCZ_IPN_USŁUGI';
$signature = hash('sha256', implode('|', $data));
return hash_equals($signature, $payload['signature']);
}
private function flattenArray(array $array): array
{
unset($array['signature']);
$return = [];
array_walk_recursive($array, function ($a) use (&$return) {
$return[] = $a;
});
return $return;
}
}
$validator = new SimPaySignatureValidator();
if(!$validator->isValid()) {
http_response_code(403);
echo 'INVALID_SIGNATURE';
die();
}
// reszta ipn
Dostępne globalne typy danych:
- TransactionStatusEnum - Enum(
transaction_new
,transaction_confirmed
,transaction_generated
,transaction_paid
,transaction_failed
,transaction_expired
,transaction_canceled
,transaction_refunded
) - RefundStatusEnum - Enum(
refund_new
,refund_pending
,refund_completed
,refund_rejected
,refund_failed
)
Dostępne wartości w polu type
:
transaction:status_changed
- zmiana statusu transakcji
Dane w polu data:
Pole | Typ | Opis | Przykładowa wartość |
---|---|---|---|
id | UUID | ID transakcji przesyłany po wygenerowaniu transakcji | 00554475-7ebb-4f16-b30b-0ce21da1a03b |
payer_transaction_id | char(8) | ID transakcji pokazywane płacącemu | 4878R2PN |
service_id | char(8) | Identyfikator usługi | e65c7519 |
status | TransactionStatusEnum | Status transakcji | transaction_paid |
amount | Obiekt | Obiekt informacji o kwocie | |
amount.final_currency | ISO 4217 | Waluta, w której płacący dokonał płatności | PLN |
amount.final_value | string (%.2f) | Finalna kwota, którą płacący zapłacił (np. "0.30", "10.00", "12.37") | 8.47 |
amount.original_currency | ISO 4217 | Waluta, która była zadeklarowana przy inicjacji płatności | EUR |
amount.original_value | string (%.2f) | Zadeklarowana kwota przy inicjacji płatności (np. "0.30", "10.00", "12.37") | 2.00 |
amount.commission_system | string (%.2f) or null | Kwota prowizji, która została pobrana przez SimPay (np. "0.30", "10.00", "12.37") | 0.13 |
amount.commission_partner | string (%.2f) or null | Kwota prowizji, która została dla Partnera (np. "0.30", "10.00", "12.37") | 0.13 |
amount.commission_currency | ISO 4217 or null | Waluta, w której została pobrana prowizja (PLN/EUR) | PLN |
control | string | Pole przesyłane tylko wtedy, gdy zostało przekazane podczas inicjacji płatności | SHOP_ORDER_1 |
payment | Obiekt | Pole z informacjami o płatności | |
payment.channel | string | Kanał płatności, którym zapłacił płacący | blik |
payment.type | string | Typ/grupa metody płatności | blik |
customer | Obiekt | Obiekt informacji o płacącym | |
customer.country_code | ISO 3166-1 Alpha-2 or null | Kraj kupującego (np. "PL") | PLN |
paid_at | ISO 8601 or null (może nie być przesyłane, kiedy transakcja nie opłacona) | Data i czas zapłaty | 2025-05-26T15:10:24Z |
created_at | ISO 8601 | Data i czas utworzenia transakcji | 2025-05-26T15:09:59Z |
Przykładowy wysyłany event (dla ipn key = UwSkKiIwlxIeOMF8MIq9iDkQWBTtjoJQ
):
{
"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"
}
transaction_refund:status_changed
- zmiana statusu zwrotu
Dane w polu data:
Pole | Typ | Opis | Przykładowa wartość |
---|---|---|---|
id | UUID | ID zwrotu SimPay | 0194837c-69df-71dd-adff-4b3058f3fb58 |
service_id | char(8) | Identyfikator usługi | e65c7519 |
status | RefundStatusEnum | Status zwrotu | refund_completed |
amount | Obiekt | Obiekt informacji o kwocie | |
amount.currency | ISO 4217 | Waluta, w której zlecono zwrot | PLN |
amount.value | string (%.2f) | Kwota, zlecona w zwrocie | 8.47 |
amount.wallet_currency | ISO 4217 | Waluta portfela, z którego pobrano środki | EUR |
amount.wallet_value | string (%.2f) | Kwota, którą pobrano z portfela | 2.00 |
transaction | Obiekt | Pole z informacjami o płatności | |
transaction.id | UUID | ID transakcji SimPay | 00554475-7ebb-4f16-b30b-0ce21da1a03b |
transaction.payment_channel | string | Kanał płatności, którym zapłacił płacący | blik |
transaction.payment_type | string | Typ/grupa metody płatności | blik |
Przykładowy wysyłany event (dla ipn key = UwSkKiIwlxIeOMF8MIq9iDkQWBTtjoJQ
):
{
"type": "transaction_refund:status_changed",
"notification_id": "0196ff00-376d-7399-a457-d166c9adf073",
"date": "2025-05-23T23:15:26+02:00",
"data": {
"id": "0194837c-69df-71dd-adff-4b3058f3fb58",
"service_id": "e65c7519",
"status": "refund_completed",
"amount": {
"currency": "PLN",
"value": "1.00",
"wallet_currency": "PLN",
"wallet_value": "1.00"
},
"transaction": {
"id": "e568d9ba-a85a-444c-87c4-3b1e431428d1",
"payment_channel": "paysafecard",
"payment_type": "paysafe"
}
},
"signature": "835819c5720c74f01b8d10a58b2dc43185f05379ea26f25a15158061f3bce10c"
}
ipn:test
- testowe powiadomienie
To powiadomienie można wysłać z Panelu Klienta.
Dane w polu data:
Pole | Typ | Opis | Przykładowa wartość |
---|---|---|---|
service_id | char(8) | Identyfikator usługi | e65c7519 |
nonce | string | Losowy ciąg znaków | 01JVZCXGZ77DJTM08WMSX34ETQ |
Przykładowy wysyłany event (dla ipn key = UwSkKiIwlxIeOMF8MIq9iDkQWBTtjoJQ
):
{
"type": "ipn:test",
"notification_id": "0196fece-c3e7-71ba-ac8a-ac64056d7d6b",
"date": "2025-05-23T22:21:25+02:00",
"data": {
"service_id": "e65c7519",
"nonce": "01JVZCXGZ77DJTM08WMSX34ETQ"
},
"signature": "02df1a420def7e5de9b316d2bd1ef70796f50abc461561a85bb1243f0a08984d"
}