Przejdź do głównej zawartości

Zwroty (Refunds)

dpay.pl umożliwia realizację zwrotów środków dla zakończonych transakcji. Obsługiwane są zarówno zwroty pełne, jak i częściowe. Zwroty można wykonywać programowo przez API lub ręcznie z poziomu panelu administracyjnego.

Obsługiwane metody płatności

MetodaZwrot pełnyZwrot częściowy
BLIKTakTak
BLIK BNPLTakTak
Przelewy bankowe (PBL)TakTak
Karty płatnicze (Visa / Mastercard)TakTak
MB WAYTakTak
PayPoTakNie
TwistoTakNie
Limit czasowy

Zwrot można wykonać w ciągu 180 dni od daty transakcji. Po tym okresie zwrot nie jest możliwy.

Endpoint API

POST https://api-payments.dpay.pl/api/v1/pbl/refund
Content-Type: application/json

Parametry zapytania

PoleTypWymaganeOpis
servicestringTakNazwa serwisu z panelu
transaction_idstringTakIdentyfikator transakcji do zwrotu
valuestringNieKwota zwrotu (np. "15.00"). Jeśli pominięte - zwrot pełny
checksumstringTakSuma kontrolna SHA-256
Zwrot częściowy

Aby wykonać zwrot częściowy, przekaż parametr value z kwotą mniejszą niż wartość transakcji. Kwota musi być liczbą nieujemną (np. "15.00").

Generowanie checksum

Format checksum zależy od typu zwrotu.

Zwrot pełny

sha256({service}|{transaction_id}|{secret_hash})

Zwrot częściowy (z parametrem value)

sha256({service}|{transaction_id}|{value}|{secret_hash})
ostrzeżenie

Gdy przekazujesz parametr value, musisz uwzględnić go w checksum. Użycie checksum bez value przy zwrocie częściowym spowoduje błąd Invalid checksum.

PHP

$service = 'abc123';
$transactionId = 'abc-def-123-456';
$secretHash = '9a8b7c6d5e4f3a2b1c0d';

// Zwrot pełny
$checksum = hash('sha256',
$service . '|' . $transactionId . '|' . $secretHash
);

// Zwrot częściowy
$value = '15.00';
$checksumPartial = hash('sha256',
$service . '|' . $transactionId . '|' . $value . '|' . $secretHash
);

JavaScript (Node.js)

const crypto = require('crypto');

const service = 'abc123';
const transactionId = 'abc-def-123-456';
const secretHash = '9a8b7c6d5e4f3a2b1c0d';

// Zwrot pełny
const checksum = crypto
.createHash('sha256')
.update(`${service}|${transactionId}|${secretHash}`)
.digest('hex');

// Zwrot częściowy
const value = '15.00';
const checksumPartial = crypto
.createHash('sha256')
.update(`${service}|${transactionId}|${value}|${secretHash}`)
.digest('hex');

Python

import hashlib

service = 'abc123'
transaction_id = 'abc-def-123-456'
secret_hash = '9a8b7c6d5e4f3a2b1c0d'

# Zwrot pełny
data = f'{service}|{transaction_id}|{secret_hash}'
checksum = hashlib.sha256(data.encode('utf-8')).hexdigest()

# Zwrot częściowy
value = '15.00'
data_partial = f'{service}|{transaction_id}|{value}|{secret_hash}'
checksum_partial = hashlib.sha256(data_partial.encode('utf-8')).hexdigest()

Przykłady zapytań

Zwrot pełny - cURL

curl -X POST https://api-payments.dpay.pl/api/v1/pbl/refund \
-H "Content-Type: application/json" \
-d '{
"service": "abc123",
"transaction_id": "abc-def-123-456",
"checksum": "e3b0c44298fc1c149afb..."
}'

Zwrot częściowy - cURL

curl -X POST https://api-payments.dpay.pl/api/v1/pbl/refund \
-H "Content-Type: application/json" \
-d '{
"service": "abc123",
"transaction_id": "abc-def-123-456",
"value": "15.00",
"checksum": "a1b2c3d4e5f6..."
}'

PHP

<?php
$service = getenv('DPAY_SERVICE');
$secretHash = getenv('DPAY_SECRET_HASH');
$transactionId = 'abc-def-123-456';
$value = '15.00'; // null dla zwrotu pełnego

// Generowanie checksum
if ($value !== null) {
$checksum = hash('sha256',
$service . '|' . $transactionId . '|' . $value . '|' . $secretHash
);
} else {
$checksum = hash('sha256',
$service . '|' . $transactionId . '|' . $secretHash
);
}

$payload = [
'service' => $service,
'transaction_id' => $transactionId,
'checksum' => $checksum,
];

if ($value !== null) {
$payload['value'] = $value;
}

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

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$result = json_decode($response, true);

if ($httpCode === 200 && $result['status'] === 'success') {
echo 'Zwrot zrealizowany pomyślnie';
} else {
echo 'Błąd zwrotu: ' . $result['message'];
}

Odpowiedź API

Sukces

{
"status": "success",
"refund": true,
"message": "Refund processed successfully"
}

Błąd

{
"status": "error",
"refund": false,
"message": "Transaction not found"
}

Wielokrotne zwroty częściowe

Dla metod obsługujących zwroty częściowe (BLIK, karty, MB WAY) możesz wykonać wiele zwrotów do jednej transakcji, dopóki suma zwrotów nie przekroczy kwoty pierwotnej transakcji.

dpay.pl śledzi łączną zwróconą kwotę w polu refunded_amount. Przykład:

OperacjaKwotarefunded_amountPozostało
Transakcja100.00 PLN0.00100.00
Zwrot #130.00 PLN30.0070.00
Zwrot #225.00 PLN55.0045.00
Zwrot #345.00 PLN100.000.00
uwaga

Próba zwrotu kwoty przekraczającej pozostałą wartość transakcji zakończy się błędem.

Najczęstsze błędy

BłądPrzyczynaRozwiązanie
Transaction not foundPodany transaction_id nie istniejeSprawdź identyfikator transakcji
Invalid checksumNieprawidłowa suma kontrolnaSprawdź kolejność pól i Secret Hash. Dla zwrotu częściowego uwzględnij value w checksum
Transaction not eligible for refundTransakcja nie kwalifikuje się do zwrotuSprawdź, czy metoda płatności obsługuje zwroty
Refund period expiredPrzekroczono okres 180 dni na zwrotZwrot nie jest możliwy po upływie limitu
Refund amount exceeds remaining valueKwota zwrotu przekracza pozostałą wartośćZmniejsz kwotę zwrotu

Zwroty w panelu administracyjnym

Możesz również wykonać zwrot ręcznie:

  1. Zaloguj się do panel.dpay.pl.
  2. Przejdź do sekcji Transakcje.
  3. Znajdź transakcję do zwrotu (użyj filtrów lub wyszukiwarki).
  4. Kliknij na transakcję, aby otworzyć jej szczegóły.
  5. Kliknij przycisk Zwróć środki.
  6. Wybierz typ zwrotu - pełny lub częściowy (jeśli dostępny dla danej metody).
  7. W przypadku zwrotu częściowego podaj kwotę.
  8. Potwierdź zwrot.