Skip to main content

Error codes and response statuses

A complete list of HTTP codes, transaction statuses, validation errors, and dpay.pl API response codes. Decline reasons of payments, refunds and payouts in webhooks are described in Decline codes.

HTTP response codes​

CodeMeaningDescription
200SuccessThe request was processed successfully
400Bad requestBusiness validation error (for example, an invalid registration checksum, disabled channel, or invalid amount)
401UnauthorisedMissing or invalid credentials; also an invalid checksum for refunds, transaction details, and payout details (Unauthorized request)
403ForbiddenNo permission to access the resource (errorcode: err01)
404Not foundThe resource does not exist
422Field validation errorThe request failed formal field validation (see the format below)
500Server errorInternal server error

Response formats​

Success response (payment registration)​

{
"error": false,
"msg": "https://secure.dpay.pl/transfer@pay@A75AEBB4-4B89-4834-AD43-EF442C133769",
"status": true,
"transactionId": "A75AEBB4-4B89-4834-AD43-EF442C133769"
}

The msg field in a successful registration response has different values depending on the scenario:

Scenariomsg valueAdditional fields
Redirect to the payment gatewayPayment gateway URLnone
Test modeInternal payment simulation page URLnone
Internal processing without a redirect, for example a payment initiated with a codeInternal processingnone
Transaction paid immediatelyTransaction paidadditionalInfo.transaction with transaction details

Success response - paid transaction​

{
"error": false,
"msg": "Transaction paid",
"status": true,
"transactionId": "A75AEBB4-4B89-4834-AD43-EF442C133769",
"additionalInfo": {
"transaction": {
"payment_id": "A75AEBB4-4B89-4834-AD43-EF442C133769",
"pid": null,
"mtid": null,
"email": "customer@example.com",
"description": "Order #1234",
"name": null,
"surname": null,
"value": "29.99",
"status": "paid",
"creation_date": "2026-05-03 17:40:07",
"payment_date": "2026-05-03 17:40:12"
}
}
}

The Transaction statuses section describes the values in additionalInfo.transaction.status.

Transaction error response (for example, cancelled)​

{
"error": true,
"msg": "Transaction canceled",
"status": false,
"transactionId": "42191111-A7AE-392E-8C09-7965C1DC6B0B"
}

Business validation error (HTTP 400)​

Returned for merchant-side errors such as an invalid checksum, disabled channel, or invalid amount. The message field contains the specific error message, while errors is an object mapping a field name to a message, not an array:

{
"status": "failed",
"message": "Invalid checksum",
"errors": {
"checksum": "Invalid checksum"
}
}
{
"status": "failed",
"message": "Amount is less than 0.01 PLN",
"errors": {
"value": "Invalid value"
}
}

Field validation error (HTTP 422)​

When a request fails formal field validation, for example because a required field is missing or a value has the wrong type, the API returns the standard validation response. In this format, errors maps a field name to an array of messages:

{
"message": "The value field is required.",
"errors": {
"value": [
"The value field is required."
]
}
}

Error response with a code (403)​

{
"error": true,
"errorcode": "err01",
"message": "Access denied",
"status": false
}

Card response - success​

{
"success": true,
"status": "success",
"message": {
"redirectText": "",
"redirectType": "SUCCESS",
"dccOffer": null
}
}
The message field

On success (success: true), message is an object in which dccOffer is always present. It is null when no currency conversion offer was made. On failure (success: false), message is a string containing the error message.

Card response - 3D Secure required​

{
"success": true,
"status": "success",
"message": {
"redirectText": "PGZvcm0gbWV0aG9kPSJQT1NUIi4uLg==",
"redirectType": "FORM",
"dccOffer": null
}
}

Card response - error​

{
"success": false,
"status": "error",
"message": "DCC_OFFER_EXPIRED"
}

Card response - DCC offer (foreign card)​

{
"success": true,
"status": "success",
"message": {
"redirectText": null,
"redirectType": "DCC_OFFER",
"dccOffer": {
"currencyConversionId": "00509166251006151007",
"originalAmount": 3.00,
"originalCurrency": "EUR",
"convertedAmount": 13.52,
"convertedCurrency": "PLN",
"exchangeRate": 4.507968,
"validUntil": "2026-05-03T17:40:07+00:00",
"declarationText": "Make sure you understand the costs of currency conversions...",
"markup": [{ "rate": 6.0, "additionalInfo": "Mastercard" }],
"europeanEconomicArea": true
}
}
}

For the complete flow, see Dynamic Currency Conversion (DCC).

BLIK response - error​

{
"error": true,
"msg": "Transaction canceled",
"status": false,
"transactionId": "42191111-A7AE-392E-8C09-7965C1DC6B0B",
"additionalInfo": {
"error": "USER_DECLINED",
"error_description": null
}
}

Transaction statuses​

The status field in a transaction details response (pbl/details) and in refund statuses:

StatusDescription
createdTransaction created and awaiting payment
processingPayment being processed
paidPayment completed successfully
capturedFunds captured after an earlier pre-authorisation
expiredTransaction cancelled or expired
A second status map - registration response

The additionalInfo.transaction.status field in a registration response (the Transaction paid variant) uses a different mapping: pending, paid, captured, and canceled. The pending and canceled statuses occur only there, while created, processing, and expired occur only in the transaction details response.

Payout statuses​

The state field in the payout details response (pbl/withdraws/details):

ValueStatusDescription
0PendingThe payout is awaiting processing
1CompletedThe payout was processed
-1ErrorThe payout failed

In addition to state, the amount fields (net, fee, and gross), and the creation date (creation_date), the response contains:

FieldDescription
idPayout identifier
paysafecard1 when the payout settles Paysafecard payments; otherwise 0 (present when direct_settlement = 0)
declined1 if the payout was declined; otherwise 0
decline_reasonReason for declining the payout (present only when declined = 1)
decline_statusStatus of the decline process (present only when declined = 1)
direct_settlement1 when the payout is processed as a settlement directed to specified accounts
nrbPayout account number (present when direct_settlement = 0)
receiverObject containing the recipients of a directed settlement (present instead of nrb when direct_settlement = 1)

Payout contents​

The pbl/withdraws/details/full endpoint returns everything pbl/withdraws/details returns, plus the transactions the payout consists of. The response has four parts:

FieldDescription
settlementPayout header - the same fields as in pbl/withdraws/details, plus currency_code and export_date
summarynet, fee, gross, and count for the whole payout, regardless of pagination
transactionsOne page of positions: payment_id, date, net, fee, gross, service_id, service_name, custom, ipksef
metapage, per_page, total, total_pages
Amounts as decimal strings

Every amount in this response - in the header, in summary, and in the positions - is a string with two decimal places (for example "27.15"). The currency is in settlement.currency_code.

Pagination is page-based (page starts at 1, per_page defaults to 100 and is capped at 500). A page beyond the last one returns an empty transactions array rather than the last page, so you can iterate until the response is empty. The summary totals always describe the whole payout, so you can reconcile the transfer amount without fetching every page.

A payout covering exactly one payment (directed settlement, refund form payout) returns one position carrying the header amounts - the contract is the same for every payout type. When the positions are not known, transactions is an empty array and summary.count is 0.

Matching positions to your own orders​

Every position carries two identifiers, so you can reconcile a payout against your system without guessing by amount and date:

FieldMeaning
payment_idThe dpay transaction identifier - the same one you receive in IPN as id
customYour own data passed when registering the payment - the same value IPN returns as custom (null when the payment carried none)

The commission is calculated per payment, not spread proportionally across positions: transactions[].fee is what that transaction actually cost.

Refunds and balance charges are separate positions with negative amounts, not a correction hidden in the header totals. Their payment_id names the source: ZWROT-{payment_id} for a refund ordered from the panel, REFUND-FORM-{uuid} for a refund form payout.

Finding a payout identifier​

The pbl/withdraws endpoint lists your payouts, newest first. Take id from there and query the details with it:

FieldDescription
withdraws[].idPayout identifier - use it as withdraw_id
withdraws[].typestandard, direct (a payout of a single payment), or paysafecard
withdraws[].stateAs above: 0 pending, 1 completed, -1 error
withdraws[].export_dateWhen the transfer was sent to the bank; null until then
metapage, per_page, total, total_pages

Filters: date_from, date_to (by creation date), state, and type. per_page defaults to 50 and is capped at 200. The list carries no account number or receiver details - those are served by the payout detail endpoints.

Payment registration errors​

Messages returned in the message field of an HTTP 400 response (see Business validation error):

MessageCauseSolution
Invalid checksumInvalid checksumCheck the field order and Hash key. Format: sha256(service|hash|value|url_success|url_fail|url_ipn), with value normalised to two decimal places. Without url_ipn the last segment is empty, but the separator before it stays
Service not foundUnknown service nameCheck the service field in the dpay.pl dashboard
Amount is less than 0.01 PLNAmount below the minimumProvide at least 0.01, using a decimal point (for example, "29.99"); errors.value then contains Invalid value
Currency code "EUR" does not match the service currency code "PLN".The currency from currency_code is not enabled for the service (for example EUR for MB WAY or Multibanco)Ask your dpay.pl account manager to enable the currency for the service
Multibanco is not enabled for this service.The Multibanco channel is not active for the serviceAsk your dpay.pl account manager to activate the channel - see Multibanco

BLIK error codes​

When a BLIK payment is rejected, additionalInfo.error contains the raw rejection code from the BLIK system, forwarded 1:1 without mapping by dpay. The list of codes is open-ended and depends on the customer's bank and the BLIK system. Treat this field as diagnostic information and do not base business logic on it.

The exceptions are codes issued by dpay: INTERNAL_ERROR (internal error - the payment result is unknown, check the transaction status) and WRONG_TICKET_BLOCKED (a code payment stopped after a series of wrong codes - see protection against Wrong Ticket attacks).

In test mode, payments are simulated and additionalInfo.error has one of the following values:

CodeDescription
DECLINETransaction declined by the issuer
EXPIRED_CARDPayment instrument expired
INSUFFICIENT_FUNDSInsufficient funds
USER_DECLINEDUser declined the transaction
TIMEOUTConfirmation timed out
ALIAS_NOT_FOUNDAlias not found
SYSTEM_ERRORSimulated system error

MB WAY error codes​

The additionalInfo.error field in an MB WAY payment response when error: true, status: false. In production, mainly errors detected at registration are returned this way - a customer's decline in the app and a missing confirmation arrive later, with the payment.failed webhook (IPN is sent only on success). Details: MB WAY - payment result.

In test mode, payments are simulated and the field takes simulator codes - all of them are returned immediately in the registration response:

CodeTest numberDescription
USER_DECLINED+351900000400The user declined the payment in the app
TIMEOUT+351900000401No confirmation within the required time
ALIAS_NOT_FOUND+351900000402Phone number not registered with MB WAY
SYSTEM_ERROR+351900000500Simulated system error

Production codes:

CodeDescriptionSolution
E0506The phone number is not registered in the MB WAY applicationAsk the customer to register it in MB WAY or provide another number
E0508The phone number is temporarily unavailable in MB WAYTry again shortly or use another payment method
E0099The operation is not permitted for this numberThe customer should contact MB WAY support
E0103Invalid request dataCheck the phone number format (PT: 9 digits, prefix 351) and the other fields
E0309Transaction not foundCheck transactionId or initiate a new payment
E0399Transaction declinedThe customer declined the transaction in the application or confirmation timed out
E0000Fallback code - the system returned no error codeTreat it as a generic error; inspect error_description and escalate to support if it repeats
other E*Generic MB WAY processor errorerror_description contains details; escalate to support if it repeats

Complete MB WAY error response format:

{
"error": true,
"msg": "Transaction canceled",
"status": false,
"transactionId": "42191111-A7AE-392E-8C09-7965C1DC6B0B",
"additionalInfo": {
"error": "E0506",
"error_description": "The provided alias does not exists"
}
}

Card response codes​

The message.redirectType field in a card payment response. The following list of values is complete:

ValueMeaningAction
SUCCESSPayment completedRedirect the customer to the success page
FORM3D Secure requiredDisplay the 3DS form from redirectText (Base64 encoded)
URLRedirect to an external URLRedirect the customer to the URL in redirectText
DCC_OFFERCurrency conversion offer (DCC)Show the customer both amounts from dccOffer, then call the endpoint again with dccDecision after the customer decides (see DCC)

DCC error codes​

DCC errors are returned with HTTP 200 in the {"success": false, "status": "error", "message": "..."} format. The message field is then a string containing the error code:

{
"success": false,
"status": "error",
"message": "DCC_OFFER_EXPIRED"
}
MessageHTTPCauseSolution
DCC_OFFER_EXPIRED200The decision was submitted after the DCC offer's validUntilShow "Offer expired", return to the payment method screen, and start a new flow
INVALID_FLOW_STATE200dccDecision was submitted without an earlier offer, for example for a finalised transactionTechnical error - log it and redirect to an error screen
caution

Do not identify these errors by HTTP code because the response uses HTTP 200. Check the success field in the response body.

DCB error codes​

DCB registration errors (secure.dpay.pl/dcb/register endpoint)​

Messages returned in msg when error: true:

MessageHTTPCauseSolution
missing guid or value or url success/fail or chcksum400One of the required fields is missing: guid, value, url_success, url_fail, or checksumSupply all required request fields
Could not find service by GUID400Unknown GUIDCheck the GUID in the dpay.pl dashboard
Service not verified.401The Payment Point has not been verifiedComplete Payment Point verification
Invalid checksum400Invalid checksumUse the amount in Polish zloty with two decimal places in the checksum and omit url_ipn; see Generating checksums
note

The missing guid or value or url success/fail or chcksum message contains a typo (chcksum) in the API and is returned literally in this form.

DCB payment statuses​

ValueStatusDescription
1PAIDPayment completed
0PENDINGPayment awaiting confirmation
-1REJECTEDPayment rejected
2REFUNDEDPayment refunded

DCB verification statuses​

ValueStatusDescription
1VERIFIEDNumber verified
0NOT_VERIFIEDNumber not verified
-1BLOCKEDNumber blocked
-2REQUIRES_CONTACTSupport contact required

SMS code statuses​

ValueStatusDescription
1USEDCode used
0PENDINGCode awaiting use
-1REJECTEDCode rejected