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
| Metoda | Zwrot pełny | Zwrot częściowy |
|---|---|---|
| BLIK | Tak | Tak |
| BLIK BNPL | Tak | Tak |
| Przelewy bankowe (PBL) | Tak | Tak |
| Karty płatnicze (Visa / Mastercard) | Tak | Tak |
| MB WAY | Tak | Tak |
| PayPo | Tak | Nie |
| Twisto | Tak | Nie |
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
| Pole | Typ | Wymagane | Opis |
|---|---|---|---|
service | string | Tak | Nazwa serwisu z panelu |
transaction_id | string | Tak | Identyfikator transakcji do zwrotu |
value | string | Nie | Kwota zwrotu (np. "15.00"). Jeśli pominięte - zwrot pełny |
checksum | string | Tak | Suma kontrolna SHA-256 |
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})
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:
| Operacja | Kwota | refunded_amount | Pozostało |
|---|---|---|---|
| Transakcja | 100.00 PLN | 0.00 | 100.00 |
| Zwrot #1 | 30.00 PLN | 30.00 | 70.00 |
| Zwrot #2 | 25.00 PLN | 55.00 | 45.00 |
| Zwrot #3 | 45.00 PLN | 100.00 | 0.00 |
Próba zwrotu kwoty przekraczającej pozostałą wartość transakcji zakończy się błędem.
Najczęstsze błędy
| Błąd | Przyczyna | Rozwiązanie |
|---|---|---|
Transaction not found | Podany transaction_id nie istnieje | Sprawdź identyfikator transakcji |
Invalid checksum | Nieprawidłowa suma kontrolna | Sprawdź kolejność pól i Secret Hash. Dla zwrotu częściowego uwzględnij value w checksum |
Transaction not eligible for refund | Transakcja nie kwalifikuje się do zwrotu | Sprawdź, czy metoda płatności obsługuje zwroty |
Refund period expired | Przekroczono okres 180 dni na zwrot | Zwrot nie jest możliwy po upływie limitu |
Refund amount exceeds remaining value | Kwota zwrotu przekracza pozostałą wartość | Zmniejsz kwotę zwrotu |
Zwroty w panelu administracyjnym
Możesz również wykonać zwrot ręcznie:
- Zaloguj się do panel.dpay.pl.
- Przejdź do sekcji Transakcje.
- Znajdź transakcję do zwrotu (użyj filtrów lub wyszukiwarki).
- Kliknij na transakcję, aby otworzyć jej szczegóły.
- Kliknij przycisk Zwróć środki.
- Wybierz typ zwrotu - pełny lub częściowy (jeśli dostępny dla danej metody).
- W przypadku zwrotu częściowego podaj kwotę.
- Potwierdź zwrot.