Payment Lifecycle
Each payment in the PayU system has a lifecycle, which is comprised of stages related to key events such as acceptance, settlement, and cancellation. PayU provides you with a mechanism that notifies your system of all changes to the payment status.
Overview
In PayU's management panel, you can easily customize auto-receive/automatic collection settings for each payment method. This lets you optimize the payment process and provide a seamless experience to your customers.
The auto-receive feature is enabled by default, and the standard payment sequence is as follows:
- Every successfully authorized payment for an order is automatically captured.
- The buyer's account is charged with the order amount.
- The shop balance is incremented by the order amount.
- PayU calculates its commission for the order.
If the auto-receive is turned off, you should capture each order using a PUT method or cancel using DELETE method.
If no such action is taken the order is auto-canceled. Automatic cancellation occurs after a number of days indicated for the payment method.
Status | Description |
---|---|
PENDING | Payment is currently being processed. |
WAITING_FOR_CONFIRMATION | PayU is currently waiting for the merchant system to receive (capture) the payment. This status is set if auto-receive is disabled on the merchant system. |
COMPLETED | Payment has been accepted. PayU will pay out the funds shortly. |
CANCELED | Payment has been cancelled and the buyer has not been charged (no money was taken from buyer's account). |
Notifications are sent immediately after a payment status changes. If the notification is not received by the Shop application, it will be sent again in accordance with the table below:
Attempt | Time |
---|---|
1 | immediately |
2 | 1 minute |
3 | 2 minutes |
4 | 5 minutes |
5 | 10 minutes |
6 | 30 minutes |
7 | 1 hour |
8 | 2 hours |
9 | 3 hours |
10 | 6 hours |
11 | 9 hours |
12 | 12 hours |
13 | 15 hours |
14 | 18 hours |
15 | 21 hours |
16 | 24 hours |
17 | 36 hours |
18 | 48 hours |
19 | 60 hours |
20 | 72 hours |
Notifications
To enable notifications for a particular payment, include the notifyUrl
parameter in the payment request. You can assign a unique URL to each payment, and PayU will send the notifications to those specified URLs accordingly.
Every notification is sent asynchronously. After your system receives a notification with the status COMPLETED, instruct it to ignore any further notifications.
After PayU sends a notification, it expects a response with a 200 HTTP status code. If a different status code is received, PayU will attempt to resend the notification. It's essential for your system to handle such cases where a notification might be sent multiple times with the same status.
To establish a secure and trusted communication channel between PayU and your shop, it's crucial to verify the signature value present in the OpenPayu-Signature
header for every notification received from PayU servers.
The verification process ensures that the notification indeed originates from PayU and has not been tampered with during transit. For more information see the Verification of Notifications Signature section.
Notifications are sent for orders in the following statuses: PENDING, WAITING_FOR_CONFIRMATION, COMPLETED, CANCELED.
Notifications are sent in JSON format using POST method.
For more information about parameters, refer to the For details on authentication methods and parameters, please refer to Authorize section in the PayU API reference.
If you filter IP addresses, remember to allow IPs used by PayU to send the notifications:
PRODUCTION
185.68.12.10, 185.68.12.11, 185.68.12.12, 185.68.12.26, 185.68.12.27, 185.68.12.28
SANDBOX
185.68.14.10, 185.68.14.11, 185.68.14.12, 185.68.14.26, `185.68.14.27, 185.68.14.28
Notification Examples
The following sample notifications are all examples of notifications sent by PayU to a merchant.
PayU-Processing-Time: 1000 // for selected statuses
Content-Type: application/json;charset=UTF-8
User-Agent: Jakarta Commons-HttpClient/3.1
Content-Length: 100
Authorization: Basic MTIzNDU2Nzg6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=
OpenPayu-Signature: sender=checkout;signature=d47d8a771d558c29285887febddd9327;algorithm=MD5;content=DOCUMENT
X-OpenPayU-Signature: sender=checkout;signature=d47d8a771d558c29285887febddd9327;algorithm=MD5;content=DOCUMENT
PayU-Processing-Time
shows time spent at PayU side for processing given request till first notification try. Some notifications are intentionally suspended, because merchant can receive only limited number of notification in parallel (throttling). Then, the throttling time is excluded fromPayU-Processing-Time
. Moreover, this parameter does not include time spent at bank or card organization side.
The PayU-Processing-Time
parameter in the notification from PayU indicates the duration taken by PayU to process the specific request until the first notification attempt is made. However, this parameter does not account for the time spent at the bank or card organization's side. Additionally, some notifications may intentionally be suspended due to throttling. Throttling limits the number of notifications that you can receive in parallel to prevent overwhelming your system. In such cases, the throttling time is excluded from the PayU-Processing-Time
parameter.
- Completed order
- Cancelled order
{
"order": {
"orderId": "LDLW5N7MF4140324GUEST000P01",
"extOrderId": "Order id in your shop",
"orderCreateDate": "2012-12-31T12:00:00",
"notifyUrl": "http://tempuri.org/notify",
"customerIp": "127.0.0.1",
"merchantPosId": "{POS ID (pos_id)}",
"description": "My order description",
"currencyCode": "PLN",
"totalAmount": "200",
"buyer": {
"email": "john.doe@example.org",
"phone": "111111111",
"firstName": "John",
"lastName": "Doe",
"language": "en"
},
"payMethod": {
"type": "PBL" //or "CARD_TOKEN", "INSTALLMENTS"
},
"products": [
{
"name": "Product 1",
"unitPrice": "200",
"quantity": "1"
}
],
"status": "COMPLETED"
},
"localReceiptDateTime": "2016-03-02T12:58:14.828+01:00",
"properties": [
{
"name": "PAYMENT_ID",
"value": "151471228"
}
]
}
{
"order": {
"orderId": "LDLW5N7MF4140324GUEST000P01",
"extOrderId": "Order id in your shop",
"orderCreateDate": "2012-12-31T12:00:00",
"notifyUrl": "http://tempuri.org/notify",
"customerIp": "127.0.0.1",
"merchantPosId": "{POS ID (pos_id)}",
"description": "My order description",
"currencyCode": "PLN",
"totalAmount": "200",
"products": [
{
"name": "Product 1",
"unitPrice": "200",
"quantity": "1"
}
],
"status": "CANCELED"
}
}
localReceiptDateTime
is only present for the status completed.
"PAYMENT_ID" is the payment identifier, displayed on transaction statements as Trans ID and within the transaction search option in the management panel.
payMethod.type
specifies payment method used in the order. PBL stands for online or standard transfer, CARD_TOKEN is a card payment (incl. Masterpass and Visa Checkout), and INSTALLMENTS means a payment via PayU|Installments solution.
Verification of Notifications Signature
The provided example demonstrates how to verify the correctness of the notification signature received from a PayU server. Here's a step-by-step explanation of the process:
OpenPayu-Signature:
sender=checkout;
signature=c33a38d89fb60f873c039fcec3a14743;
algorithm=MD5;
content=DOCUMENT
To verify the correctness of notification signature, do as follows:
- Retrieve the
OpenPayU-Signature header
from the notification received from PayU. - Extract the
signature
value from the header. The signature value will be stored in a variable, let's say incoming_signature.
string incoming_signature = signature_header[signature]
- Verify the type of hashing function used to generate the signature. In this example, it's specified as md5.
- Concatenate the body of the incoming notification (e.g., JSONnotification) with the value of the
second key
.
string concatenated = JSONnotification + second_key;
- Apply the hashing function (e.g., MD5) to the concatenated string to obtain the expected signature value. Store this value in a variable (e.g.,
expected_signature
).
string expected_signature = md5(concatenated);
- Compare the
expected_signature
with theincoming_signature
. If they match, the signature is correct and the verification is successful. If they don't match, the signature is incorrect.
if(expected_signature == incoming_signature){
return true; //signature is correct
}else{
return 'Wrong signature' // signature is incorrect
}