Skip to main content

Refunds

dpay.pl enables refund processing for completed transactions. Both full refunds and partial refunds are supported. Refunds can be issued programmatically via the API or manually from the admin panel.

Supported payment methods

MethodFull refundPartial refund
BLIKYesYes
BLIK BNPLYesYes
Bank transfers (PBL)YesYes
Payment cards (Visa / Mastercard)YesYes
MB WAYYesYes
PayPoYesNo
TwistoYesNo
Time limit

A refund can be issued within 180 days of the transaction date. After this period, refunds are no longer possible.

API endpoint

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

Request parameters

FieldTypeRequiredDescription
servicestringYesService name from the panel
transaction_idstringYesTransaction ID to refund
valuestringNoRefund amount (e.g. "15.00"). If omitted - full refund
checksumstringYesSHA-256 checksum
Partial refund

To issue a partial refund, pass the value parameter with an amount less than the transaction value. The amount must be a non-negative number (e.g. "15.00").

Generating the checksum

The checksum format depends on the refund type.

Full refund

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

Partial refund (with value parameter)

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

When passing the value parameter, you must include it in the checksum. Using a checksum without value for a partial refund will result in an Invalid checksum error.

PHP

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

// Full refund
$checksum = hash('sha256',
$service . '|' . $transactionId . '|' . $secretHash
);

// Partial refund
$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';

// Full refund
const checksum = crypto
.createHash('sha256')
.update(`${service}|${transactionId}|${secretHash}`)
.digest('hex');

// Partial refund
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'

# Full refund
data = f'{service}|{transaction_id}|{secret_hash}'
checksum = hashlib.sha256(data.encode('utf-8')).hexdigest()

# Partial refund
value = '15.00'
data_partial = f'{service}|{transaction_id}|{value}|{secret_hash}'
checksum_partial = hashlib.sha256(data_partial.encode('utf-8')).hexdigest()

Request examples

Full refund - 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..."
}'

Partial refund - 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 for a full refund

// Generate 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 'Refund processed successfully';
} else {
echo 'Refund error: ' . $result['message'];
}

API response

Success

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

Error

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

Multiple partial refunds

For methods that support partial refunds (BLIK, cards, MB WAY), you can issue multiple refunds for a single transaction, as long as the total refunded amount does not exceed the original transaction amount.

dpay.pl tracks the cumulative refunded amount in the refunded_amount field. Example:

OperationAmountrefunded_amountRemaining
Transaction100.00 PLN0.00100.00
Refund #130.00 PLN30.0070.00
Refund #225.00 PLN55.0045.00
Refund #345.00 PLN100.000.00
caution

Attempting to refund an amount that exceeds the remaining transaction value will result in an error.

Common errors

ErrorCauseSolution
Transaction not foundThe provided transaction_id does not existVerify the transaction ID
Invalid checksumInvalid checksumCheck the field order and Secret Hash. For partial refunds, include value in the checksum
Transaction not eligible for refundThe transaction is not eligible for a refundCheck whether the payment method supports refunds
Refund period expiredThe 180-day refund period has been exceededRefunds are no longer possible after the time limit
Refund amount exceeds remaining valueThe refund amount exceeds the remaining valueReduce the refund amount

Refunds in the admin panel

You can also issue a refund manually:

  1. Log in to panel.dpay.pl.
  2. Go to the Transactions section.
  3. Find the transaction to refund (use filters or the search bar).
  4. Click on the transaction to open its details.
  5. Click the Refund button.
  6. Select the refund type - full or partial (if available for the given payment method).
  7. For a partial refund, enter the amount.
  8. Confirm the refund.