Przejdź do treści
Ostatnia aktualizacja

Obsługa notyfikacji Płatności Online (IPN v2)

Informacja

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.

Zalecamy dodatkowo sprawdzanie adresu IP, z którego przyszedł IPN. Endpoint do pobierania adresów IP: https://api.simpay.pl/ip

Struktura notyfikacji

PoleTypOpis
typeEnumPrzesyłany event, pełna lista poniżej
notification_idchar(36)Unikalne ID notyfikacji
datedate (ISO 8601)Data i godzina wysyłki notyfikacji w formacie ISO 8601 (np. 2025-05-20T16:36:07Z)
dataObiektDane przesyłane w tym evencie
signaturestringWyliczona 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
Informacja

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:type
  • notification_id = 0196bf93-aca4-7253-8a2d-0941a037f25b
  • date = 2025-05-20T16:36:07Z
  • data ma pola:
    • status = transaction_paid
    • amount (obiekt)
      • amount.currency = PLN
      • amount.value = 5.25
    • transaction_id = 123123123123
    • meta = 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:

  1. TransactionStatusEnum - Enum(transaction_new, transaction_confirmed, transaction_generated, transaction_paid, transaction_failure, transaction_expired, transaction_canceled, transaction_refunded, transaction_fraud, transaction_fraud_possibility)
  2. RefundStatusEnum - Enum(refund_new, refund_pending, refund_completed, refund_rejected, refund_failed)
  3. BlikAliasStatusEnum - Enum(alias_pending_registration, alias_active, alias_expired, alias_unregistered)
  4. SubscriptionStatusEnum - Enum(subscription_pending, subscription_active, subscription_cancelled, subscription_expired, subscription_finished, subscription_fraudulent)
  5. SubscriptionModeEnum - Enum(BLIK, CARD)
  6. BlikSubscriptionModelEnum - Enum(A, O, M)

Dostępne wartości w polu type:

transaction:status_changed - zmiana statusu transakcji

Dane w polu data:

PoleTypOpisPrzykładowa wartość
idUUIDID transakcji przesyłany po wygenerowaniu transakcji00554475-7ebb-4f16-b30b-0ce21da1a03b
payer_transaction_idchar(8)ID transakcji pokazywane płacącemu4878R2PN
service_idchar(8)Identyfikator usługie65c7519
statusTransactionStatusEnumStatus transakcjitransaction_paid
amountObiektObiekt informacji o kwocie
amount.final_currencyISO 4217Waluta, w której płacący dokonał płatnościPLN
amount.final_valuestring (%.2f)Finalna kwota, którą płacący zapłacił (np. "0.30", "10.00", "12.37")8.47
amount.original_currencyISO 4217Waluta, która była zadeklarowana przy inicjacji płatnościEUR
amount.original_valuestring (%.2f)Zadeklarowana kwota przy inicjacji płatności (np. "0.30", "10.00", "12.37")2.00
amount.commission_systemstring (%.2f) or nullKwota prowizji, która została pobrana przez SimPay (np. "0.30", "10.00", "12.37")0.13
amount.commission_partnerstring (%.2f) or nullKwota prowizji, która została dla Partnera (np. "0.30", "10.00", "12.37")0.13
amount.commission_currencyISO 4217 or nullWaluta, w której została pobrana prowizja (PLN/EUR)PLN
controlstringPole przesyłane tylko wtedy, gdy zostało przekazane podczas inicjacji płatnościSHOP_ORDER_1
paymentObiektPole z informacjami o płatności
payment.channelstringKanał płatności, którym zapłacił płacącyblik
payment.typestringTyp/grupa metody płatnościblik
customerObiektObiekt informacji o płacącym
customer.country_codeISO 3166-1 Alpha-2 or nullKraj kupującego (np. "PL")PLN
paid_atISO 8601 or null (może nie być przesyłane, kiedy transakcja nie opłacona)Data i czas zapłaty2025-05-26T15:10:24Z
created_atISO 8601Data i czas utworzenia transakcji2025-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:

PoleTypOpisPrzykładowa wartość
idUUIDID zwrotu SimPay0194837c-69df-71dd-adff-4b3058f3fb58
service_idchar(8)Identyfikator usługie65c7519
statusRefundStatusEnumStatus zwroturefund_completed
amountObiektObiekt informacji o kwocie
amount.currencyISO 4217Waluta, w której zlecono zwrotPLN
amount.valuestring (%.2f)Kwota, zlecona w zwrocie8.47
amount.wallet_currencyISO 4217Waluta portfela, z którego pobrano środkiEUR
amount.wallet_valuestring (%.2f)Kwota, którą pobrano z portfela2.00
transactionObiektPole z informacjami o płatności
transaction.idUUIDID transakcji SimPay00554475-7ebb-4f16-b30b-0ce21da1a03b
transaction.payment_channelstringKanał płatności, którym zapłacił płacącyblik
transaction.payment_typestringTyp/grupa metody płatnościblik

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:

PoleTypOpisPrzykładowa wartość
service_idchar(8)Identyfikator usługie65c7519
noncestringLosowy ciąg znaków01JVZCXGZ77DJTM08WMSX34ETQ

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"
}

transaction_blik_level0:code_status_changed - zmiana statusu kodu BLIK

To powiadomienie jest wysyłane tylko przy transakcjach BLIK Level 0 oraz BLIK Płatności Powtarzalne.

Dane w polu data:

PoleTypOpisPrzykładowa wartość
ticket_statusstringStatus kodu BLIK (zobacz zakładkę BLIK Level 0 w dokumentacji)VALID
transactionobiektObiekt transakcji
transaction.idUuidUUID transakcji70bc5ab3-4973-4275-a0eb-08e3f2ab54f2
transaction.payer_transaction_idChar(8)Identyfikator płatności przekazany płacącemu6PB8JKKN
transaction.service_idChar(8)Identyfikator usługie65c7519
transaction.statusTransactionStatusEnumStatus transakcjitransaction_paid
transaction.amountObiektObiekt informacji o kwocie
transaction.amount.final_currencyISO 4217Waluta, w której płacący dokonał płatnościPLN
transaction.amount.final_valuestring (%.2f)Finalna kwota, którą płacący zapłacił (np. "0.30", "10.00", "12.37")8.47
transaction.amount.original_currencyISO 4217Waluta, która była zadeklarowana przy inicjacji płatnościEUR
transaction.amount.original_valuestring (%.2f)Zadeklarowana kwota przy inicjacji płatności (np. "0.30", "10.00", "12.37")2.00
transaction.amount.commission_systemstring (%.2f) or nullKwota prowizji, która została pobrana przez SimPay (np. "0.30", "10.00", "12.37")0.13
transaction.amount.commission_partnerstring (%.2f) or nullKwota prowizji, która została dla Partnera (np. "0.30", "10.00", "12.37")0.13
transaction.amount.commission_currencyISO 4217 or nullWaluta, w której została pobrana prowizja (PLN/EUR)PLN
transaction.controlstring or nullWartość pola control (jeśli brak - null)111122223333

Przykładowy wysyłany event (dla ipn key = UwSkKiIwlxIeOMF8MIq9iDkQWBTtjoJQ):

{
  "type": "transaction_blik_level0:code_status_changed",
  "notification_id": "019736c4-50c3-7108-944c-11a0f9c12b72",
  "date": "2025-06-03T19:08:44+02:00",
  "data": {
    "ticket_status": "VALID",
    "transaction": {
      "id": "70bc5ab3-4973-4275-a0eb-08e3f2ab54f2",
      "payer_transaction_id": "6PB8JKKN",
      "service_id": "e65c7519",
      "status": "transaction_paid",
      "amount": {
        "final_currency": "PLN",
        "final_value": "360.00",
        "original_currency": "PLN",
        "original_value": "360.00",
        "commission_system": "5.36",
        "commission_partner": "354.64",
        "commission_currency": "PLN"
      },
      "control": "111122223333"
    }
  },
  "signature": "236197b1a75a8e1c33b0feea94cab753f4b0d7f5ffd044abeea36ea8b89566cc"
}

blik:alias_status_changed - Zmiana statusu Aliasu BLIK.

To powiadomienie jest wysyłane tylko przy BLIK Płatności Powtarzalne w momencie zmiany statusu aliasu.

Dane w polu data:

PoleTypOpisPrzykładowa wartość
iduuidID aliasu019972b1-e4c0-714f-a10b-f88a158bee50
service_idChar(8)Identyfikator usługie65c7519
typestringTyp aliasuPAYID
valuestringWartość aliasuAABBCCDD
labelstringEtykieta wyświetlana w aplikacji mobilnej banku płacącegotesty
statusBlikAliasStatusEnumStatus aliasualias_active
created_atdatetime (ISO 8601)Data utworzenia aliasu2025-09-22T20:31:25+02:00
updated_atdatetime (ISO 8601)Data ostatniej aktualizacji aliasu2025-09-22T20:31:32+02:00

Przykładowy wysyłany event (dla ipn key = UwSkKiIwlxIeOMF8MIq9iDkQWBTtjoJQ):

{
  "type": "blik:alias_status_changed",
  "notification_id": "019972b2-0233-73d7-ad91-c114b62d56e3",
  "date": "2025-09-22T20:31:32+02:00",
  "data": {
    "id": "019972b1-e4c0-714f-a10b-f88a158bee50",
    "service_id": "e65c7519",
    "type": "PAYID",
    "value": "AABBCCDD",
    "label": "testy",
    "status": "alias_active",
    "created_at": "2025-09-22T20:31:25+02:00",
    "updated_at": "2025-09-22T20:31:32+02:00"
  },
  "signature": "8f1a0f6de3eb5c050e70ca0d7407588e380e8e607e131e289afb0a3a2996d4a1"
}

subscription:status_changed - Zmiana statusu subskrypcji.

To powiadomienie jest wysyłane tylko przy metodach płatności związanych z subskrypcjami/Płatnościami Powtarzalnymi.

Dane w polu data:

PoleTypOpisPrzykładowa wartość
iduuidID subskrypcji019972b1-e4df-70c4-8c9b-6a89f6ccc948
service_idChar(8)Identyfikator usługie65c7519
statusSubscriptionStatusEnumStatus subskrypcjisubscription_active
modeSubscriptionModeEnumTryb subskrypcjiBLIK
created_atdatetime (ISO 8601)Data utworzenia aliasu2025-09-22T20:31:25+02:00
updated_atdatetime (ISO 8601)Data ostatniej aktualizacji aliasu2025-09-22T20:31:32+02:00
blikobiektObiekt zawierający szczegóły o subskrypcji BLIK (przesyłany tylko przy mode == BLIK)
blik.modelBlikSubscriptionModelEnumModel subskrypcji BLIKO
blik.currencychar(3)Waluta subskrypcji BLIKPLN
blik.aliasobiektDane aliasu BLIK
blik.alias.iduuidID aliasu BLIK019972b1-e4c0-714f-a10b-f88a158bee50
blik.alias.typestringTyp aliasu BLIKPAYID
blik.alias.valuestringWartość aliasu BLIKAABBCCDD
blik.alias.labelstringEtykieta wyświetlana w aplikacji mobilnej bankutesty
blik.alias.statusBlikAliasStatusEnumStatus aliasu BLIKalias_active
blik.alias.created_atdatetime (ISO 8601)Data utworzenia aliasu2025-09-22T20:31:25+02:00
blik.alias.updated_atdatetime (ISO 8601)Data ostatniej aktualizacji aliasu2025-09-22T20:31:32+02:00

Przykładowy wysyłany event (dla ipn key = UwSkKiIwlxIeOMF8MIq9iDkQWBTtjoJQ):

{
  "type": "subscription:status_changed",
  "notification_id": "019972b2-0360-7177-a635-f26b05f632b8",
  "date": "2025-09-22T20:31:32+02:00",
  "data": {
    "id": "019972b1-e4df-70c4-8c9b-6a89f6ccc948",
    "service_id": "e65c7519",
    "status": "subscription_active",
    "mode": "BLIK",
    "created_at": "2025-09-22T20:31:25+02:00",
    "updated_at": "2025-09-22T20:31:32+02:00",
    "blik": {
      "model": "O",
      "currency": "PLN",
      "alias": {
        "id": "019972b1-e4c0-714f-a10b-f88a158bee50",
        "type": "PAYID",
        "value": "AABBCCDD",
        "label": "testy",
        "status": "alias_active",
        "created_at": "2025-09-22T20:31:25+02:00",
        "updated_at": "2025-09-22T20:31:32+02:00"
      }
    }
  },
  "signature": "0851c6bc63e92bff424a83ab9067c192d6e9a1b5d67ade9960f0cce67216d3f1"
}