Classic Integration for Cards
This is server-to-server integration over the Redirect experience for cards.
Experience the end-to-end Merchant Hosted Checkout > Cards flow and instantly generate the complete code for seamless, zero-coding integration into your website.
Step 1: Initiate payment request with PayU
Environment
| Test Environment | https://test.payu.in/_payment |
| Production Environment | https://secure.payu.in/_payment |
Mandatory Parameters
| Parameter | Description |
|---|---|
| key | String Merchant key provided by PayU during onboarding. |
| txnid | String The transaction ID is a reference number generated by the merchant. |
| amount | String The payment amount for the transaction. |
| productinfo | String A brief description of the product. |
| firstname | String The first name of the customer. |
String The email address of the customer. | |
| phone | String The phone number of the customer. |
| pg | String For cards, CC will be the value. |
| bankcode | String Each payment option is identified with a unique bank code at PayU. |
| ccnum | String Use 13-19 digit card number and validate with LUHN algorithm. |
| ccname | String The name on card as entered by the customer. |
| ccvv | String Use 3-digit CVV number. Validate with BIN API. |
| ccexpmon | String Card expiry month in MM format. |
| ccexpyr | String Card expiry year in four digits. |
| furl | String The failure URL for failed transactions. |
| surl | String The success URL for successful transactions. |
| hash | String SHA-512(key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5||||||Salt) |
Optional Parameters
| Parameter | Description |
|---|---|
| address1 | String The first line of the billing address. For Fraud Detection: helpful for fraud detection and chargebacks. |
| address2 | String The second line of the billing address. |
| city | String The city where the customer resides. |
| state | String The state where the customer resides. |
| country | String The country where the customer resides. |
| zipcode | String Billing address zip code. Mandatory for cardless EMI. Character Limit: 20. |
| udf1-udf5 | String User-defined fields for storing transaction-specific data. |
Understanding Hashing and sample code
Hashing
You must hash the request parameters using the following hash logic:
sha512(key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5||||||SALT)
For more information, refer to Generate Hash.
Hashing Sample Code
<?php
function generateHash($params, $salt) {
// Extract parameters or use empty string if not provided
$key = $params['key'];
$txnid = $params['txnid'];
$amount = $params['amount'];
$productinfo = $params['productinfo'];
$firstname = $params['firstname'];
$email = $params['email'];
$udf1 = isset($params['udf1']) ? $params['udf1'] : '';
$udf2 = isset($params['udf2']) ? $params['udf2'] : '';
$udf3 = isset($params['udf3']) ? $params['udf3'] : '';
$udf4 = isset($params['udf4']) ? $params['udf4'] : '';
$udf5 = isset($params['udf5']) ? $params['udf5'] : '';
// Construct hash string with exact parameter sequence
$hashString = $key . '|' . $txnid . '|' . $amount . '|' . $productinfo . '|' .
$firstname . '|' . $email . '|' . $udf1 . '|' . $udf2 . '|' .
$udf3 . '|' . $udf4 . '|' . $udf5 . '||||||' . $salt;
// Generate hash and convert to lowercase
return strtolower(hash('sha512', $hashString));
}
// Example usage
$params = [
'key' => 'yourKey',
'txnid' => 'yourTxnId',
'amount' => 'yourAmount',
'productinfo' => 'yourProductInfo',
'firstname' => 'yourFirstName',
'email' => 'yourEmail',
'udf1' => 'optional_value1'
// udf2, udf3, udf4, udf5 not provided - will be empty strings
];
$salt = 'yourSalt';
$hash = generateHash($params, $salt);
echo 'Generated Hash: ' . $hash;
?>
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
public class ImprovedHashGenerator {
public static String generateHash(Map<String, String> params, String salt) {
// Extract parameters or use empty string if not provided
String key = params.get("key");
String txnid = params.get("txnid");
String amount = params.get("amount");
String productinfo = params.get("productinfo");
String firstname = params.get("firstname");
String email = params.get("email");
String udf1 = params.getOrDefault("udf1", "");
String udf2 = params.getOrDefault("udf2", "");
String udf3 = params.getOrDefault("udf3", "");
String udf4 = params.getOrDefault("udf4", "");
String udf5 = params.getOrDefault("udf5", "");
// Construct hash string with exact parameter sequence
String hashString = key + "|" + txnid + "|" + amount + "|" + productinfo + "|" +
firstname + "|" + email + "|" + udf1 + "|" + udf2 + "|" +
udf3 + "|" + udf4 + "|" + udf5 + "||||||" + salt;
return sha512(hashString);
}
private static String sha512(String input) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-512");
byte[] hashBytes = md.digest(input.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : hashBytes) {
sb.append(String.format("%02x", b));
}
return sb.toString().toLowerCase();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
// Example usage with parameters map
Map<String, String> params = new HashMap<>();
params.put("key", "yourKey");
params.put("txnid", "yourTxnId");
params.put("amount", "yourAmount");
params.put("productinfo", "yourProductInfo");
params.put("firstname", "yourFirstName");
params.put("email", "yourEmail");
params.put("udf1", "optional_value1");
// udf2, udf3, udf4, udf5 not provided - will be empty strings
String salt = "yourSalt";
String hash = generateHash(params, salt);
System.out.println("Generated Hash: " + hash);
}
}
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
public class ImprovedHashGenerator
{
public static string GenerateHash(Dictionary<string, string> parameters, string salt)
{
// Extract parameters or use empty string if not provided
string key = parameters["key"];
string txnid = parameters["txnid"];
string amount = parameters["amount"];
string productinfo = parameters["productinfo"];
string firstname = parameters["firstname"];
string email = parameters["email"];
// Get UDF values if present, otherwise use empty string
string udf1 = parameters.ContainsKey("udf1") ? parameters["udf1"] : "";
string udf2 = parameters.ContainsKey("udf2") ? parameters["udf2"] : "";
string udf3 = parameters.ContainsKey("udf3") ? parameters["udf3"] : "";
string udf4 = parameters.ContainsKey("udf4") ? parameters["udf4"] : "";
string udf5 = parameters.ContainsKey("udf5") ? parameters["udf5"] : "";
// Construct hash string with exact parameter sequence
string hashString = $"{key}|{txnid}|{amount}|{productinfo}|{firstname}|{email}|{udf1}|{udf2}|{udf3}|{udf4}|{udf5}||||||{salt}";
return Sha512(hashString);
}
private static string Sha512(string input)
{
using (SHA512 sha512 = SHA512.Create())
{
byte[] bytes = sha512.ComputeHash(Encoding.UTF8.GetBytes(input));
StringBuilder sb = new StringBuilder();
foreach (byte b in bytes)
{
sb.Append(b.ToString("x2"));
}
return sb.ToString().ToLower();
}
}
public static void Main(string[] args)
{
// Example usage with parameters dictionary
Dictionary<string, string> parameters = new Dictionary<string, string>
{
["key"] = "yourKey",
["txnid"] = "yourTxnId",
["amount"] = "yourAmount",
["productinfo"] = "yourProductInfo",
["firstname"] = "yourFirstName",
["email"] = "yourEmail",
["udf1"] = "optional_value1"
// udf2, udf3, udf4, udf5 not provided - will be empty strings
};
string salt = "yourSalt";
string hash = GenerateHash(parameters, salt);
Console.WriteLine("Generated Hash: " + hash);
}
}import hashlib
def generate_hash(params, salt):
# Extract parameters or use empty string if not provided
key = params['key']
txnid = params['txnid']
amount = params['amount']
productinfo = params['productinfo']
firstname = params['firstname']
email = params['email']
udf1 = params.get('udf1', '')
udf2 = params.get('udf2', '')
udf3 = params.get('udf3', '')
udf4 = params.get('udf4', '')
udf5 = params.get('udf5', '')
# Construct hash string with exact parameter sequence
hash_string = f"{key}|{txnid}|{amount}|{productinfo}|{firstname}|{email}|{udf1}|{udf2}|{udf3}|{udf4}|{udf5}||||||{salt}"
# Generate SHA-512 hash
return hashlib.sha512(hash_string.encode('utf-8')).hexdigest()
# Example usage
params = {
'key': 'yourKey',
'txnid': 'yourTxnId',
'amount': 'yourAmount',
'productinfo': 'yourProductInfo',
'firstname': 'yourFirstName',
'email': 'yourEmail',
'udf1': 'optional_value1'
# udf2, udf3, udf4, udf5 not provided - will default to empty strings
}
salt = 'yourSalt'
hash_value = generate_hash(params, salt)
print("Generated Hash:", hash_value)
const crypto = require('crypto');
function generateHash(params, salt) {
// Extract parameters or use empty string if not provided
const key = params.key;
const txnid = params.txnid;
const amount = params.amount;
const productinfo = params.productinfo;
const firstname = params.firstname;
const email = params.email;
const udf1 = params.udf1 || '';
const udf2 = params.udf2 || '';
const udf3 = params.udf3 || '';
const udf4 = params.udf4 || '';
const udf5 = params.udf5 || '';
// Construct hash string with exact parameter sequence
const hashString = `${key}|${txnid}|${amount}|${productinfo}|${firstname}|${email}|${udf1}|${udf2}|${udf3}|${udf4}|${udf5}||||||${salt}`;
// Generate SHA-512 hash
return crypto.createHash('sha512').update(hashString).digest('hex');
}
// Example usage
const params = {
key: 'yourKey',
txnid: 'yourTxnId',
amount: 'yourAmount',
productinfo: 'yourProductInfo',
firstname: 'yourFirstName',
email: 'yourEmail',
udf1: 'optional_value1'
// udf2, udf3, udf4, udf5 not provided - will default to empty strings
};
const salt = 'yourSalt';
const hash = generateHash(params, salt);
console.log("Generated Hash:", hash);
curl --location 'https://test.payu.in/_payment' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'key=YOUR_MERCHANT_KEY' \
--data-urlencode 'txnid=TXN_12345' \
--data-urlencode 'amount=10.00' \
--data-urlencode 'productinfo=iPhone' \
--data-urlencode 'firstname=Ashish' \
--data-urlencode '[email protected]' \
--data-urlencode 'phone=9876543210' \
--data-urlencode 'pg=CC' \
--data-urlencode 'bankcode=VISA' \
--data-urlencode 'ccnum=5123456789012346' \
--data-urlencode 'ccname=Ashish Kumar' \
--data-urlencode 'ccvv=123' \
--data-urlencode 'ccexpmon=10' \
--data-urlencode 'ccexpyr=2025' \
--data-urlencode 'surl=https://apiplayground-response.herokuapp.com/' \
--data-urlencode 'furl=https://apiplayground-response.herokuapp.com/' \
--data-urlencode 'hash=YOUR_HASH_VALUE'import requests
url = "https://test.payu.in/_payment"
data = {"key":"YOUR_MERCHANT_KEY","txnid":"TXN_12345","amount":"10.00","productinfo":"iPhone",
"firstname":"Ashish","email":"[email protected]","phone":"9876543210","pg":"CC","bankcode":"VISA",
"ccnum":"5123456789012346","ccname":"Ashish Kumar","ccvv":"123","ccexpmon":"10","ccexpyr":"2025",
"surl":"https://apiplayground-response.herokuapp.com/",
"furl":"https://apiplayground-response.herokuapp.com/","hash":"YOUR_HASH_VALUE"}
r = requests.post(url,headers={"Content-Type":"application/x-www-form-urlencoded"},data=data)
print(r.status_code); print(r.text)<?php
$url="https://test.payu.in/_payment";
$ch=curl_init($url); curl_setopt_array($ch,[CURLOPT_POST=>true,
CURLOPT_POSTFIELDS=>http_build_query(["key"=>"YOUR_MERCHANT_KEY","txnid"=>"TXN_12345","amount"=>"10.00",
"productinfo"=>"iPhone","firstname"=>"Ashish","email"=>"[email protected]","phone"=>"9876543210",
"pg"=>"CC","bankcode"=>"VISA","ccnum"=>"5123456789012346","ccname"=>"Ashish Kumar","ccvv"=>"123",
"ccexpmon"=>"10","ccexpyr"=>"2025","surl"=>"https://apiplayground-response.herokuapp.com/",
"furl"=>"https://apiplayground-response.herokuapp.com/","hash"=>"YOUR_HASH_VALUE"]),
CURLOPT_HTTPHEADER=>["Content-Type: application/x-www-form-urlencoded"],CURLOPT_RETURNTRANSFER=>true]);
echo curl_exec($ch); curl_close($ch);
?>import java.net.*; import java.net.http.*; import java.nio.charset.*; import java.util.*;
public class ClassicS2S { public static void main(String[] a) throws Exception {
var p=new LinkedHashMap<String,String>(); p.put("key","YOUR_MERCHANT_KEY"); p.put("txnid","TXN_12345");
p.put("amount","10.00"); p.put("productinfo","iPhone"); p.put("firstname","Ashish");
p.put("email","[email protected]"); p.put("phone","9876543210"); p.put("pg","CC"); p.put("bankcode","VISA");
p.put("ccnum","5123456789012346"); p.put("ccname","Ashish Kumar"); p.put("ccvv","123");
p.put("ccexpmon","10"); p.put("ccexpyr","2025");
p.put("surl","https://apiplayground-response.herokuapp.com/");
p.put("furl","https://apiplayground-response.herokuapp.com/"); p.put("hash","YOUR_HASH_VALUE");
var sj=new StringJoiner("&"); for(var e:p.entrySet()) sj.add(URLEncoder.encode(e.getKey(),StandardCharsets.UTF_8)+"="+URLEncoder.encode(e.getValue(),StandardCharsets.UTF_8));
var resp=HttpClient.newHttpClient().send(HttpRequest.newBuilder().uri(URI.create("https://test.payu.in/_payment"))
.header("Content-Type","application/x-www-form-urlencoded").POST(HttpRequest.BodyPublishers.ofString(sj.toString())).build(),HttpResponse.BodyHandlers.ofString());
System.out.println("Status: "+resp.statusCode()); System.out.println(resp.body()); }}using System; using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks;
class ClassicS2S { static async Task Main() { using var c=new HttpClient();
var d=new FormUrlEncodedContent(new Dictionary<string,string>{
{"key","YOUR_MERCHANT_KEY"},{"txnid","TXN_12345"},{"amount","10.00"},
{"productinfo","iPhone"},{"firstname","Ashish"},{"email","[email protected]"},
{"phone","9876543210"},{"pg","CC"},{"bankcode","VISA"},
{"ccnum","5123456789012346"},{"ccname","Ashish Kumar"},{"ccvv","123"},
{"ccexpmon","10"},{"ccexpyr","2025"},
{"surl","https://apiplayground-response.herokuapp.com/"},
{"furl","https://apiplayground-response.herokuapp.com/"},{"hash","YOUR_HASH_VALUE"}});
var r=await c.PostAsync("https://test.payu.in/_payment",d);
Console.WriteLine("Status: "+(int)r.StatusCode); Console.WriteLine(await r.Content.ReadAsStringAsync()); }}Step 2: Redirect the customer
Redirect the customer to complete authentication.
Step 3: Check response from PayU
Hash validation logic for payment response (Reverse Hashing)
While sending the response, PayU takes the exact same parameters that were sent in the request (in reverse order) to calculate the hash and returns it to you. You must verify the hash and then mark a transaction as a success or failure. This is to make sure the transaction has not tampered within the response.
The order of the parameters is similar to the following code block:
sha512(SALT|status||||||udf5|udf4|udf3|udf2|udf1|email|firstname|productinfo|amount|txnid|key)Step 4. Verify the payment
Upon receiving the response, PayU recommends you performing a reconciliation step to validate all transaction details.
You can verify your payments using either of the following methods:
Configure the webhooks to monitor the status of payments.
Webhooks enable a server to communicate with another server by sending an HTTP callback or message.
These callbacks are triggered by specific events or instances and operate at the server-to-server (S2S) level.
Know how to manage Webhooks for Payments.
Environment
| Test Environment | https://test.payu.in/merchant/postservice.php?form=2 |
| Production Environment | https://info.payu.in/merchant/postservice.php?form=2 |
Note: The hash logic for Verify Payment API is:
sha512(key|command|var1|salt) sha512
Sample request
curl --request POST
--url 'https://test.payu.in/merchant/postservice?form=2'
--header 'Content-Type: application/x-www-form-urlencoded'
--data key=JPM7Fg
--data command=verify_payment
--data var1=IhfgcZnXR4o4nB
--data hash=a0ae79fdd66c875af6e9b21c4a67f1822deb00f2df5e9f0b1948f3222f536a9bf741b24efbb1874ca0f84f76b036e6c0d641581d0100f7abe4aeed2f3264f5c9
Sample response
If credit card payment is made, the response is similar to the following:
{
"status":0,
"msg":"0 out of 1 Transactions Fetched Successfully",
"transaction_details":
{
"IhfgcZnXR4o4nB":
{
"mihpayid":"Not Found",
"status":"Not Found"
}
}
}If txnID is not found, the response is similar to the following:
{
"status":0,
"msg":"0 out of 1 Transactions Fetched Successfully",
"transaction_details":
{
"IhfgcZnXR4o4nB":
{
"mihpayid":"Not Found",
"status":"Not Found"
}
}
}Response parameters
| Parameter | Description | Example |
|---|---|---|
| status | This parameter returns the status of web service call. The status can be any of the following:
| 0 |
| msg | This parameter returns the reason string. | For example, any of the following messages are displayed:
|
| transaction_details | This parameter contains the response in a JSON format. For more information refer to JSON fields description for transaction_details parameter . | |
| request_id | PayU Request ID for a request in a Transaction. For example, a transaction can have a refund request. | 7800456 |
| bank_ref_num | This parameter returns the bank reference number. If the bank provides after a successful action. | 204519474956 |
To learn more about the possible error codes and their description, refer to Error Codes.
Updated 3 days ago
