Transaction lifecycle
Every transaction in dpay.pl moves through a defined set of states, from creation to final settlement or cancellation. Understanding the transaction lifecycle helps you handle payments correctly in your application.
POST/api/v1/pbl/detailsCheck transaction status: parameters, checksum, and response fields.Full contract in the API Reference
Transaction statuses
| Status | Description | Final? |
|---|---|---|
created | The transaction has been registered, but the customer has not paid yet | No |
processing | The payment is being processed by the operator | No |
paid | The payment was successful (for card pre-authorisation: the funds were authorised) | Yes* |
captured | The pre-authorised card payment was captured and the funds were collected | Yes |
expired | The transaction expired or did not complete (timeout, rejection, or customer cancellation) | Yes |
* For card payments using the pre-authorisation/capture model, a paid transaction (authorisation) can still move to captured after the funds are captured. For all other methods, paid is final.
State diagram
The state labelled "canceled" in the diagram is returned as expired by the transaction status API. In addition, pre-authorised card payments can move from paid to the final captured state.
State transition descriptions
created → processing
The customer selected a payment method and started authorisation. For some methods, such as BLIK and cards, the transaction moves to processing immediately after the payment data is submitted.
processing → paid
The payment operator (bank, BLIK, or card processor) confirmed authorisation. The funds were collected from the customer's account. dpay.pl sends a confirmation IPN.
processing → expired
The payment failed. Common reasons include:
- The customer cancelled the payment
- An invalid BLIK code or rejection in the banking application
- Insufficient funds
- A timeout because the customer did not complete the payment in time
- Rejection by the anti-fraud system
created → expired
The customer took no action and the transaction expired (timeout).
paid → captured (pre-authorised cards only)
This transition applies only to card payments using the pre-authorisation/capture model. After authorisation (paid), you capture the funds and the transaction moves to the final captured state.
Behaviour by payment method
Different payment methods have different lifecycles:
| Method | Moves through processing? | Typical time to pay |
|---|---|---|
| BLIK | Yes | ~2 minutes (code lifetime) |
| Bank transfers (PBL) | Yes | Up to 15 minutes |
| Payment cards | Yes (authorisation + optional 3DS) | Up to 5 minutes |
| Google Pay / Apple Pay | Yes | Seconds |
| MB WAY | Yes (confirmation in the application) | Up to 5 minutes |
| DCB | Yes | Up to 2 minutes |
| Premium SMS | Not applicable (different model) | - |
How to check transaction status
IPN (recommended)
The best way to track transaction status is to handle IPN. dpay.pl automatically sends an HTTP POST notification to your endpoint when the transaction reaches the paid state.
IPN is sent only for successful transactions (paid, and additionally captured for pre-authorised cards). Expired and failed transactions do not generate IPN.
Polling (querying the API)
If the IPN did not arrive or you need additional verification, you can check the status manually:
POST https://panel.dpay.pl/api/v1/pbl/details
Content-Type: application/json
{
"service": "abc123",
"transaction_id": "A75AEBB4-4B89-4834-AD43-EF442C133769",
"checksum": "sha256(service|transaction_id|secret_hash)"
}
See Querying transaction status manually for endpoint details and code examples.
Do not query the API too frequently. The recommended approach is:
- Primary mechanism - IPN (automatic and immediate)
- Fallback - a cron job that checks transactions which have been awaiting payment for more than 15 minutes
Mapping statuses to IPN
| Transaction status | IPN sent? | IPN type |
|---|---|---|
created | No | - |
processing | No | - |
paid | Yes | transfer |
captured (pre-authorised card capture) | Yes | capture |
expired | No | - |
Handling states in your application
Example server-side status handling logic:
// Map dpay.pl statuses to order statuses
switch ($transactionStatus) {
case 'created':
// The order is awaiting payment
// Show the customer an "Awaiting payment" message
break;
case 'processing':
// Payment in progress - do not change the order status
// The customer sees a waiting page
break;
case 'paid':
// Payment confirmed by IPN
// Update the order and send a confirmation email
markOrderAsPaid($orderId);
break;
case 'captured':
// Pre-authorised card payment captured - funds collected
markOrderAsPaid($orderId);
break;
case 'expired':
// The transaction expired / did not complete
// Restore product availability and inform the customer
markOrderAsCanceled($orderId);
break;
}
Do not update the order status to paid based on the customer redirect to url_success. The only reliable sources of successful payment information are IPN and a request to the dpay API.