Skip to main content

BLIK - płatności cykliczne (subskrypcje)

Płatności cykliczne BLIK pozwalają obciążać klienta bez jego udziału przy każdej płatności - idealne dla subskrypcji i abonamentów. Klient jednorazowo rejestruje alias typu PAYID (potwierdzając kodem BLIK w aplikacji bankowej), a kolejne obciążenia inicjujesz z serwera, przekazując zapisany alias.

Jak to działa?

Proces składa się z dwóch etapów:

  1. Rejestracja aliasu PAYID - transakcja z kwotą 0, kodem BLIK i obiektem register_blik_recurring_alias. Klient potwierdza zgodę na płatności cykliczne w aplikacji bankowej.
  2. Obciążenia cykliczne - kolejne płatności z transactionType: "blik_recurring" i polem blik_alias, inicjowane przez Twój serwer bez udziału klienta.

Wymagania

  • Aktywny Punkt Płatności z włączoną obsługą płatności cyklicznych BLIK oraz wybranym modelem odnowienia (skontaktuj się z BOK dpay)
  • Możliwość przechowywania wartości aliasu po stronie serwera (powiązanej z kontem klienta)
  • Dostęp do adresu IP i User-Agent klienta przy rejestracji (wymagane przez regulacje)

Modele odnowienia

Przy rejestracji aliasu wskazujesz model kontroli obciążeń:

ModelOpis
AKontrola po stronie banku klienta - limity i odnowienia zarządza aplikacja bankowa
MKontrola po stronie sklepu - dpay waliduje każde obciążenie względem limitów podanych przy rejestracji (limit_amt, tot_limit_amt)
OBez kontroli limitów

Model musi być aktywny dla Twojego serwisu - użycie nieaktywnego modelu zwróci błąd rejestracji.

Endpoint

POST https://api-payments.dpay.pl/api/v1_0/payments/register
Content-Type: application/json

Krok 1: Rejestracja aliasu PAYID

Rejestracja to transakcja z kwotą równą 0 - klient nie jest obciążany, a jedynie potwierdza zgodę na płatności cykliczne kodem BLIK.

Parametry zapytania

PoleTypWymaganeOpis
transactionTypestringTak"blik_recurring"
servicestringTakNazwa serwisu z panelu
valuestringTakMusi być 0 (rejestracja bez obciążenia)
url_successstringTakURL po udanej rejestracji
url_failstringTakURL po nieudanej rejestracji
url_ipnstringTakURL do powiadomień IPN
checksumstringTakSuma kontrolna SHA-256
blik_codestringTak6-cyfrowy kod BLIK
user_ipstringTakAdres IP klienta
user_agentstringTakNagłówek User-Agent klienta
register_blik_recurring_aliasobjectTakParametry aliasu PAYID (poniżej)
alias_ipn_urlstringNieAdres URL do powiadomień o zmianach statusu aliasu (max 500 znaków); gdy pominięty, powiadomienia trafiają na url_ipn
descriptionstringNieOpis subskrypcji

Obiekt register_blik_recurring_alias

PoleTypWymaganeOpis
labelstringTakEtykieta subskrypcji widoczna dla klienta (max 50 znaków)
typestringTakTyp aliasu - musi być "PAYID"
modelstringTakModel odnowienia: "A", "M" lub "O"
frequencystringTakCzęstotliwość obciążeń: liczba 1-999 + jednostka D (dni), W (tygodnie), M (miesiące), Q (kwartały), Y (lata), np. "1M", "2W", "30D"
valuestringNieWłasna wartość aliasu (max 128 znaków). Gdy pominięta, dpay generuje wartość automatycznie
limit_amtintegerNieLimit pojedynczego obciążenia w groszach (np. 5999 = 59,99 PLN)
tot_limit_amtintegerNieŁączny limit wszystkich obciążeń w groszach
is_limit_amt_fixedbooleanNietrue - każde obciążenie musi być dokładnie równe limit_amt; false - limit_amt jest kwotą maksymalną
expiration_datestringNieData wygaśnięcia aliasu (YYYY-MM-DD, późniejsza niż dzisiejsza)
init_datestringNieData pierwszego obciążenia (YYYY-MM-DD, dzisiejsza lub późniejsza)
Rekomendacja: podaj własną wartość aliasu

Zalecamy przekazanie własnej wartości w register_blik_recurring_alias.value i zapisanie jej po stronie serwera w powiązaniu z kontem klienta - będzie potrzebna do kolejnych obciążeń oraz do sprawdzania statusu aliasu. Wartość musi być unikalna - próba rejestracji drugiego aktywnego aliasu o tej samej wartości zostanie odrzucona.

Generowanie checksum

Checksum generowany jest identycznie jak dla standardowej płatności:

sha256({service}|{SecretHash}|{value}|{url_success}|{url_fail}|{url_ipn})
Format kwoty w checksum

Kwota w checksumie jest normalizowana do dwóch miejsc po przecinku - dla rejestracji z value: 0 hashuj "0.00".

Przykład zapytania

cURL

curl -X POST https://api-payments.dpay.pl/api/v1_0/payments/register \
-H "Content-Type: application/json" \
-d '{
"transactionType": "blik_recurring",
"service": "abc123",
"value": 0,
"url_success": "https://mojsklep.pl/sukces",
"url_fail": "https://mojsklep.pl/blad",
"url_ipn": "https://mojsklep.pl/api/ipn",
"checksum": "e3b0c44298fc1c149afb...",
"blik_code": "123456",
"user_ip": "192.168.1.100",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"description": "Subskrypcja Premium",
"register_blik_recurring_alias": {
"label": "Subskrypcja Premium",
"type": "PAYID",
"value": "SUB-1234567890",
"model": "M",
"frequency": "1M",
"limit_amt": 5999,
"tot_limit_amt": 71988,
"is_limit_amt_fixed": false,
"expiration_date": "2027-07-01"
}
}'

PHP

<?php
$service = getenv('DPAY_SERVICE');
$secretHash = getenv('DPAY_SECRET_HASH');

$value = '0.00';
$urlSuccess = 'https://mojsklep.pl/sukces';
$urlFail = 'https://mojsklep.pl/blad';
$urlIpn = 'https://mojsklep.pl/api/ipn';

$checksum = hash('sha256',
$service . '|' . $secretHash . '|' . $value . '|' .
$urlSuccess . '|' . $urlFail . '|' . $urlIpn
);

$payload = json_encode([
'transactionType' => 'blik_recurring',
'service' => $service,
'value' => 0,
'url_success' => $urlSuccess,
'url_fail' => $urlFail,
'url_ipn' => $urlIpn,
'checksum' => $checksum,
'blik_code' => $_POST['blik_code'],
'user_ip' => $_SERVER['REMOTE_ADDR'],
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
'description' => 'Subskrypcja Premium',
'register_blik_recurring_alias' => [
'label' => 'Subskrypcja Premium',
'type' => 'PAYID',
'value' => 'SUB-' . $userId,
'model' => 'M',
'frequency' => '1M',
'limit_amt' => 5999,
'tot_limit_amt' => 71988,
'is_limit_amt_fixed' => false,
],
]);

$ch = curl_init('https://api-payments.dpay.pl/api/v1_0/payments/register');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);

$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);

Odpowiedź API

{
"error": false,
"msg": "Internal processing",
"status": true,
"transactionId": "abc-def-123-456"
}

Pole status jest wartością logiczną (true/false). Po otrzymaniu tej odpowiedzi klient musi potwierdzić rejestrację subskrypcji w swojej aplikacji bankowej. Wynik rejestracji otrzymasz przez IPN, a aktualny status aliasu sprawdzisz endpointem statusu (poniżej).

Krok 2: Obciążenie cykliczne

Kolejne płatności inicjujesz z serwera - bez kodu BLIK i bez udziału klienta.

Parametry zapytania

PoleTypWymaganeOpis
transactionTypestringTak"blik_recurring"
servicestringTakNazwa serwisu z panelu
valuestringTakKwota obciążenia w PLN (musi być większa od 0)
url_successstringTakURL po udanej płatności
url_failstringTakURL po nieudanej płatności
url_ipnstringTakURL do powiadomień IPN
checksumstringTakSuma kontrolna SHA-256
blik_aliasstringTakWartość aliasu PAYID z rejestracji (max 128 znaków)
no_delaybooleanNieDomyślnie true (odpowiedź natychmiastowa). false - BLIK może wstrzymać transakcję do 72 godzin, czekając na potwierdzenie klienta w aplikacji (modele M/O); wymaga wcześniejszej zgody dpay
user_ipstringNieAdres IP - opcjonalny przy obciążeniu server-to-server
user_agentstringNieUser-Agent - opcjonalny przy obciążeniu server-to-server
Wykluczanie pól

Przy obciążeniu cyklicznym nie przekazuj blik_code, register_blik_alias ani register_blik_recurring_alias - pole blik_alias wyklucza się z nimi.

Walidacja limitów (model M)

Dla aliasów z modelem M każde obciążenie jest walidowane po stronie dpay:

  • limit_amt z is_limit_amt_fixed: true - kwota obciążenia musi być dokładnie równa limitowi
  • limit_amt z is_limit_amt_fixed: false - kwota obciążenia nie może przekroczyć limitu
  • tot_limit_amt - suma dotychczasowych obciążeń plus bieżące nie może przekroczyć limitu łącznego

Przekroczenie limitu zwraca HTTP 400 z opisem w polu message.

Przykład zapytania

curl -X POST https://api-payments.dpay.pl/api/v1_0/payments/register \
-H "Content-Type: application/json" \
-d '{
"transactionType": "blik_recurring",
"service": "abc123",
"value": "59.99",
"url_success": "https://mojsklep.pl/sukces",
"url_fail": "https://mojsklep.pl/blad",
"url_ipn": "https://mojsklep.pl/api/ipn",
"checksum": "e3b0c44298fc1c149afb...",
"blik_alias": "SUB-1234567890"
}'

Odpowiedź API

{
"error": false,
"msg": "Internal processing",
"status": true,
"transactionId": "abc-def-123-456"
}

Wynik obciążenia otrzymasz przez IPN na url_ipn.

Sprawdzanie statusu aliasu

Aktualny status aliasu PAYID (wraz z parametrami rejestracji) pobierzesz dedykowanym endpointem:

POST https://api-payments.dpay.pl/api/v1_0/payments/blik/recurring/status
Content-Type: application/json

Parametry

PoleTypWymaganeOpis
servicestringTakNazwa serwisu z panelu
alias_valuestringTakWartość aliasu PAYID (max 128 znaków)
checksumstringTakSuma kontrolna SHA-256

Generowanie checksum

sha256({service}|{SecretHash}|{alias_value})

Przykład zapytania

curl -X POST https://api-payments.dpay.pl/api/v1_0/payments/blik/recurring/status \
-H "Content-Type: application/json" \
-d '{
"service": "abc123",
"alias_value": "SUB-1234567890",
"checksum": "f5a3b2c1d0..."
}'

Odpowiedź

{
"status": "success",
"data": {
"alias_value": "SUB-1234567890",
"alias_type": "PAYID",
"status": "ACTIVE",
"expiration_date": "2027-07-01",
"registration": {
"model": "M",
"frequency": "1M",
"limit_amt": 5999,
"tot_limit_amt": 71988,
"is_limit_amt_fixed": false,
"init_date": null,
"label": "Subskrypcja Premium",
"registered_at": "2026-07-01T12:00:00+02:00"
}
}
}
PoleTypOpis
alias_valuestringWartość aliasu
alias_typestringZawsze "PAYID"
statusstring|nullAktualny status aliasu, np. "ACTIVE", "INACTIVE", "UNREGISTERED", "EXPIRED"
expiration_datestring|nullData wygaśnięcia aliasu
registrationobject|nullParametry podane przy rejestracji (model, frequency, limity, etykieta, data rejestracji)

Limity zapytań

EndpointLimit
POST /payments/register120 zapytań/min
POST /blik/recurring/status60 zapytań/min

Obsługa błędów

Błędy walidacji biznesowej zwracane są z HTTP 400 w formacie {"status": "failed", "message": "...", "errors": {...}}. Najczęstsze komunikaty:

KomunikatPrzyczyna
BLIK Recurring is not enabled for this service.Płatności cykliczne nie są włączone dla serwisu
BLIK Recurring model M is not enabled for this service.Wskazany model odnowienia nie jest aktywny
BLIK Recurring registration requires value=0.Rejestracja z kwotą inną niż 0
An active BLIK Recurring alias with this value already exists.Duplikat wartości aliasu
BLIK Recurring payment requires value > 0.Obciążenie z kwotą 0
No active BLIK Recurring alias found for this value.Alias nie istnieje, wygasł lub został wyrejestrowany
Setting no_delay=false requires merchant approval (...). Contact support.Użycie no_delay: false bez zgody dpay

Odrzucenie płatności przez system BLIK zwraca odpowiedź {"error": true, "msg": "Transaction canceled", "status": false, ...} z kodem w polu additionalInfo.error - lista kodów jest wspólna dla wszystkich płatności BLIK, patrz BLIK OneClick - obsługa błędów.

tip

Jeśli alias wygasł lub klient wycofał zgodę w aplikacji bankowej, przeprowadź ponowną rejestrację aliasu (Krok 1) przy najbliższej okazji - np. przy odnowieniu subskrypcji.