The PayU v2 Payment API enables merchants to process payments through a hosted checkout flow where customers are redirected to PayU's payment page to complete the transaction.
Note: This documentation covers the non-seamless (hosted checkout) integration. For seamless payment flows where payment details are collected on your checkout page, refer to Collect Payment API - Merchant Hosted & S2S.
Environment
| Test Environment | https://apitest.payu.in/v2/payments |
| Production Environment | https://api.payu.in/v2/payments |
Request header
| Parameter | Description |
|---|---|
| date | The current date and time. For example, format of the date is Wed, 28 Jun 2023 11:25:19 GMT. |
| authorization | The actual HMAC signature generated using the specified algorithm (sha512) and includes the hashed data. For more information, refer to authorization fields description. |
authorization fields description
| Field | Description |
|---|---|
| username | Represents the username or identifier for the client or merchant, for example smsplus. |
| algorithm | Use SHA512 algorithm for hashing and send this as header value. |
| headers | Specifies which headers have been used in generating the hash, for example date. |
| signature | The HMAC signature generated using the specified algorithm. For more information, refer to hashing algorithm. |
hashing algorithm
You must hash the request parameters using the following hash logic:
Hash logic: sha512(`<Body data>` + '|' + date + '|' + merchant_secret)
Where <Body data> contains the request body posted with the request.
Sample header code
var merchant_key = '<YOUR_TEST_KEY>';
var merchant_secret = 'YOUR_TEST_SALT';
// date
var date = new Date();
date = date.toUTCString();
// authorization
var authorization = getAuthHeader(date);
function getAuthHeader(date) {
var AUTH_TYPE = 'sha512';
var data = isEmpty(request['data']) ? "" : request['data'];
var hash_string = data + '|' + date + '|' + merchant_secret;
var hash = CryptoJS.SHA512(hash_string).toString(CryptoJS.enc.Hex);
return `hmac username="${merchant_key}", algorithm="${AUTH_TYPE}", headers="date", signature="${hash}"`;
}Request parameters
All the parameters are mandatory.
| Parameter | Description | Example |
|---|---|---|
| accountId | Merchant key provided by PayU. Type: String. Character limit: 50 | MERCHANT123 |
| currency | Transaction currency code (e.g. INR). Type: String. Character limit: 3 | INR |
| txnId | Unique transaction ID generated by merchant. Type: String. Character limit: 50 | TXN_20261005_001 |
| order | Order details containing product info and pricing. Type: Object. See order object. | |
| billingDetails | Customer billing information. Type: Object. See billingDetails object. | |
| callBackActions | Redirection callback URLs. Type: Object. See callBackActions object. | |
| additionalInfo | Flow and routing configuration. Type: Object. See additionalInfo object. |
order Object
| Parameter | Description | Example |
|---|---|---|
productInfomandatory | Product details. Type: String | Product details |
orderedItemoptional | Details about the items ordered. Type: Array of Objects | |
userDefinedFieldsoptional | Custom fields for additional information. Type: Object. Fields: udf1, udf2, udf3, udf4, udf5, udf6, udf7, udf8, udf9, udf10. | |
paymentChargeSpecificationmandatory | Includes amount and charges. Type: Object. For more information, refer to paymentChargeSpecification object fields description |
paymentChargeSpecification object fields description
| Parameter | Description | Example |
|---|---|---|
pricemandatory | The transaction amount. Type: Number | 1000 |
netAmountDebitoptional | Net amount to be debited. Type: Number | 1000 |
taxSpecificationoptional | Tax details of the product/order. Type: Object | |
convenienceFeeoptional | Fees format. Type: String | CC:12 |
offersoptional | Offers applied or available for the payment. Type: Object |
userDefinedFields object fields description
| Field | Description |
|---|---|
| udf1 | User defined field. |
| udf2 | User defined field. |
| udf3 | User defined field. |
| udf4 | User defined field. |
| udf5 | User defined field. |
| udf6 | User defined field. |
| udf7 | User defined field. |
| udf8 | User defined field. |
| udf9 | User defined field. |
| udf10 | User defined field. |
billingDetails Object
| Parameter | Description | Example |
|---|---|---|
firstNamemandatory |
First name of the billing contact. | Ashish |
lastNameoptional |
Last name of the billing contact. | Kumar |
address1mandatory |
Primary billing address. | 123 Main Street |
address2optional |
Secondary billing address. | Apt 4B |
phoneoptional |
Phone number of the billing contact. | 9123456789 |
emailmandatory |
Email address of the billing contact. | [email protected] |
cityoptional |
City of the billing address. | Bharatpur |
stateoptional |
State of the billing address. | Rajasthan |
countryoptional |
Country of the billing address. | India |
zipCodeoptional |
Postal/Zip code of the billing address. | 321028 |
callBackActions Object
| Parameter | Description | Example |
|---|---|---|
successActionmandatory |
URL to be called on payment success. | https://example.com/success |
failureActionmandatory |
URL to be called on payment failure. | https://example.com/failure |
cancelActionmandatory |
URL to be called if user cancels the payment. | https://example.com/cancel |
codActionoptional |
URL for Cash on Delivery (COD) action. | https://example.com/cod |
additionalInfo Object
| Parameter | Description | Example |
|---|---|---|
txnFlowmandatory |
Specifies hosted checkout mode. Must be set to "nonseamless". |
nonseamless |
createOrderoptional |
Flag to create and store order details in PayU order management (true / false). |
true |
orderIdoptional |
Merchant order identifier, recommended when createOrder is set to true. |
ORDER_98765 |
enforcePaymethodoptional |
Filters the payment options presented on the PayU hosted checkout page (e.g., "CC,NB,UPI"). |
CC,NB,UPI |
Sample Request
Plugin for Development Environment:PayU provides plugin for VS Code and IntelliJ IDEA development environment for faster integration. For more information, refer to Plugins for Development Environment.
curl -X POST 'https://apitest.payu.in/v2/payments' \
-H 'date: Mon, 05 Oct 2026 10:00:00 GMT' \
-H 'authorization: hmac username="<YOUR_TEST_KEY>", algorithm="sha512", headers="date", signature="<SIGNATURE>"' \
-H 'content-type: application/json' \
-d '{
"accountId": "<YOUR_TEST_KEY>",
"txnId": "TXN_20261005_001",
"currency": "INR",
"order": {
"productInfo": "iPhone 13",
"paymentChargeSpecification": {
"price": 25000.00,
"convenienceFee": "CC:12,AMEX:19"
},
"userDefinedFields": {
"udf1": "value1",
"udf2": "value2"
}
},
"billingDetails": {
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"phone": "9876543210",
"address1": "123 Main Street",
"city": "New Delhi",
"state": "Delhi",
"country": "India",
"zipCode": "110001"
},
"callBackActions": {
"successAction": "<redacted URL>",
"failureAction": "<redacted URL>",
"cancelAction": "<redacted URL>"
},
"additionalInfo": {
"txnFlow": "nonseamless",
"createOrder": true,
"orderId": "ORDER_98765",
"enforcePaymethod": "CC,NB,UPI"
}
}'import requests
import json
url = "https://apitest.payu.in/v2/payments"
headers = {
"date": "Mon, 05 Oct 2026 10:00:00 GMT",
"authorization": 'hmac username="<YOUR_TEST_KEY>", algorithm="sha512", headers="date", signature="<SIGNATURE>"',
"content-type": "application/json"
}
payload = {
"accountId": "<YOUR_TEST_KEY>",
"txnId": "TXN_20261005_001",
"currency": "INR",
"order": {
"productInfo": "iPhone 13",
"paymentChargeSpecification": {
"price": 25000.00
},
"userDefinedFields": {
"udf1": "value1",
"udf2": "value2"
}
},
"billingDetails": {
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"phone": "9876543210",
"address1": "123 Main Street",
"city": "New Delhi",
"state": "Delhi",
"country": "India",
"zipCode": "110001"
},
"callBackActions": {
"successAction": "<redacted URL>",
"failureAction": "<redacted URL>",
"cancelAction": "<redacted URL>"
},
"additionalInfo": {
"txnFlow": "nonseamless",
"createOrder": True
}
}
response = requests.post(url, headers=headers, json=payload)
print(response.json())<?php
$url = "https://apitest.payu.in/v2/payments";
$payload = json_encode([
"accountId" => "<YOUR_TEST_KEY>",
"txnId" => "TXN_20261005_001",
"currency" => "INR",
"order" => [
"productInfo" => "iPhone 13",
"paymentChargeSpecification" => [
"price" => 25000.00
]
],
"billingDetails" => [
"firstName" => "John",
"lastName" => "Doe",
"email" => "[email protected]",
"phone" => "9876543210",
"address1" => "123 Main Street",
"city" => "New Delhi",
"state" => "Delhi",
"country" => "India",
"zipCode" => "110001"
],
"callBackActions" => [
"successAction" => "<redacted URL>",
"failureAction" => "<redacted URL>",
"cancelAction" => "<redacted URL>"
],
"additionalInfo" => [
"txnFlow" => "nonseamless",
"createOrder" => true
]
]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"date: Mon, 05 Oct 2026 10:00:00 GMT",
"authorization: hmac username=\"<YOUR_TEST_KEY>\", algorithm=\"sha512\", headers=\"date\", signature=\"<SIGNATURE>\"",
"content-type: application/json"
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class PayUHostedRequest {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String payload = """
{
"accountId": "<YOUR_TEST_KEY>",
"txnId": "TXN_20261005_001",
"currency": "INR",
"order": {
"productInfo": "iPhone 13",
"paymentChargeSpecification": {
"price": 25000.00
}
},
"billingDetails": {
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"phone": "9876543210",
"address1": "123 Main Street",
"city": "New Delhi",
"state": "Delhi",
"country": "India",
"zipCode": "110001"
},
"callBackActions": {
"successAction": "<redacted URL>",
"failureAction": "<redacted URL>",
"cancelAction": "<redacted URL>"
},
"additionalInfo": {
"txnFlow": "nonseamless",
"createOrder": true
}
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://apitest.payu.in/v2/payments"))
.header("date", "Mon, 05 Oct 2026 10:00:00 GMT")
.header("authorization", "hmac username=\"<YOUR_TEST_KEY>\", algorithm=\"sha512\", headers=\"date\", signature=\"<SIGNATURE>\"")
.header("content-type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}const url = "https://apitest.payu.in/v2/payments";
const payload = {
accountId: "<YOUR_TEST_KEY>",
txnId: "TXN_20261005_001",
currency: "INR",
order: {
productInfo: "iPhone 13",
paymentChargeSpecification: {
price: 25000.00
}
},
billingDetails: {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
phone: "9876543210",
address1: "123 Main Street",
city: "New Delhi",
state: "Delhi",
country: "India",
zipCode: "110001"
},
callBackActions: {
successAction: "<redacted URL>",
failureAction: "<redacted URL>",
cancelAction: "<redacted URL>"
},
additionalInfo: {
txnFlow: "nonseamless",
createOrder: true
}
};
fetch(url, {
method: "POST",
headers: {
"date": "Mon, 05 Oct 2026 10:00:00 GMT",
"authorization": 'hmac username="<YOUR_TEST_KEY>", algorithm="sha512", headers="date", signature="<SIGNATURE>"',
"content-type": "application/json"
},
body: JSON.stringify(payload)
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error("Error:", err));Response parameters
| Parameter | Description |
|---|---|
| message | This parameter contains the status message of the transaction. |
| status | This parameter returns the status of web service call. The status can be any of the following: `0` - If web service call failed. `1` - If web service call succeeded. |
| result | This parameter contains the payment status details in a JSON format including payment ID of the transaction. For more detailes, refer to the result JSON Object fields description table (next accordion) |
Sample Response
Upon a successful initiation call, PayU responds with status: "PENDING" and returns a checkoutUrl to redirect the customer:
{
"status": "PENDING",
"result": {
"checkoutUrl": "<redacted URL>"
},
"txnId": "TXN_20261005_001",
"orderId": "ORDER_98765",
"message": "Transaction initiated successfully"
}Verify Payment
ImportantAfter the customer completes payment on PayU's hosted checkout page, you must call the Verify Payment API using your
txnIdto determine the authoritative payment status before fulfilling the order.
Error Codes
| Code | HTTP Status | Description | Resolution |
|---|---|---|---|
INVALID_AMOUNT | 400 | Invalid or missing price | Verify paymentChargeSpecification.price is a valid positive number |
INVALID_CURRENCY | 400 | Unsupported currency code | Set currency: "INR" |
AUTHENTICATION_FAILED | 401 | Invalid HMAC signature or key | Check date header and signature calculation |
DUPLICATE_REFERENCE | 409 | txnId has already been used | Send a new unique txnId |
PAYMENT_DECLINED | 422 | Payment declined | Ask customer to retry with another method |
Next Steps
- Redirect Customer to Checkout:
- Redirect the customer to the
result.checkoutUrlreturned by PayU to render the responsive, hosted payment page.
- Redirect the customer to the
- Handle Return URLs:
- Intercept the browser redirect at your
callBackActions.successActionorfailureActionURLs when the customer finishes their payment.
- Intercept the browser redirect at your
- Verify Payment Integrity:
- Validate the response hash and confirm the final state with the Verify Payment API.
- Order Tracking:
- If
additionalInfo.createOrderwas enabled, correlate the PayUorderIdwith your internal shopping cart for post-order fulfillment.(https://docs.payu.in/v2/reference/v2_verify_payment_api/).
- If
