Initiate UPI payments with Third-Party Validation (TPV) to validate beneficiary account details during payment processing. This is useful for compliance scenarios where beneficiary verification is required.
Endpoint
HTTP Method: POST
Environment URLs:
| Environment | URL |
|---|---|
| Test | https://test-partnerapilayer.payu.in/apilayer/partner/payments |
| Production | https://api.payu.in/partner/payments |
Request Headers
Authorization: Bearer <FINAL_ACCESS_TOKEN>
Content-Type: application/json
Notes:
You must generate the token using the Reseller Client Credentials Token API before to be posted in header in the above APIs. For more information, refer to Reseller Client Credentials Token API
If you are old partner merchant or reseller, you must a set of APIs to generate the token that must be used in above APIs, so you must use the final access token obtained from [Step 3] Exchange Authorization Code API.
For more information, refer to Token Generation Flow used for Partner Payments.
Request Parameters
Mandatory Parameters
| Parameter | Type & Description | Example |
|---|---|---|
txnid | string — Unique transaction ID generated by partner | 28471834809170982 |
amount | string — Transaction amount | 518.02 |
productinfo | string — Product description | TPV Payment |
phone | string — Customer phone number (10 digits) | 919820988398 |
merchant_id | integer — PayU merchant ID | 8739528 |
reseller_id | string — Partner/reseller UUID | 11ee-0e7e-5403fde2-9523-0a696b110fde |
txn_s2s_flow | string — Must be "4" for UPI Intent S2S with TPV | 4 |
s2s_client_ip | string — Customer IP address (mandatory when txn_s2s_flow=4) | 157.240.22.9 |
s2s_device_info | string — Device user-agent (mandatory when txn_s2s_flow=4) | Mozilla/5.0 (iPhone) AppleWebKit/602.4.6 |
beneficiarydetail | string — JSON string containing beneficiary account details | {"ifscCode":"ICIC0001234","accountNumber":"123456789012","accountHolderName":"Test User"} |
hash | string — SHA-512 hash: merchant_id|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5||||||client_secret | (computed hash value) |
Optional Parameters
| Parameter | Type & Description | Example |
|---|---|---|
firstname | string — Customer first name | John |
email | string — Customer email address | [email protected] |
udf1 - udf5 | string — User-defined fields | |
encrypted_data | string — Alternative to beneficiarydetail (encrypted payload) | (encrypted string) |
Beneficiary Detail Schema
The beneficiarydetail parameter must be a JSON string containing:
{
"ifscCode": "ICIC0001234",
"accountNumber": "123456789012",
"accountHolderName": "Test User"
}| Field | Type | Description | Example |
|---|---|---|---|
ifscCode | string | 11-character IFSC code of beneficiary bank | ICIC0001234 |
accountNumber | string | Beneficiary account number | 123456789012 |
accountHolderName | string | Name as per bank account | Test User |
⚠️ Info Gap: The exact field validations and constraints for
beneficiarydetailshould be confirmed with the PayU integration team.
Hash Generation Formula
Compute SHA-512 hash using this exact formula:
merchant_id|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5||||||client_secret
Sample Request
curl --location 'https://test-partnerapilayer.payu.in/apilayer/partner/payments' \
--header 'Authorization: Bearer 039e0d1d70f467f946e2d73bd43868df856cfaa352ea54591a76bfc4a08d3487' \
--header 'Content-Type: application/json' \
--data '{
"txnid": "28471834809170982",
"amount": "518.02",
"productinfo": "TPV Payment",
"firstname": "",
"email": "",
"phone": "919820988398",
"merchant_id": 8739528,
"reseller_id": "11ee-0e7e-5403fde2-9523-0a696b110fde",
"udf1": "",
"udf2": "1370625260",
"udf3": "r-hway-TPV-REFERENCE",
"udf4": "",
"udf5": "whatsapp",
"txn_s2s_flow": "4",
"s2s_client_ip": "157.240.22.9",
"s2s_device_info": "Mozilla/5.0 (iPhone) AppleWebKit/602.4.6",
"beneficiarydetail": "{\"ifscCode\":\"ICIC0001234\",\"accountNumber\":\"123456789012\",\"accountHolderName\":\"Test User\"}",
"hash": "COMPUTED_HASH_VALUE"
}'import requests
import hashlib
import json
def generate_upi_tpv_payment():
url = "https://test-partnerapilayer.payu.in/apilayer/partner/payments"
# Prepare beneficiary details
beneficiary = {
"ifscCode": "ICIC0001234",
"accountNumber": "123456789012",
"accountHolderName": "Test User"
}
beneficiary_json = json.dumps(beneficiary)
# Compute hash (beneficiarydetail is NOT in hash)
hash_string = "8739528|28471834809170982|518.02|TPV Payment|||1370625260|r-hway-TPV-REFERENCE||whatsapp||||||YOUR_CLIENT_SECRET"
payment_hash = hashlib.sha512(hash_string.encode('utf-8')).hexdigest()
headers = {
"Authorization": "Bearer 039e0d1d70f467f946e2d73bd43868df856cfaa352ea54591a76bfc4a08d3487",
"Content-Type": "application/json"
}
payload = {
"txnid": "28471834809170982",
"amount": "518.02",
"productinfo": "TPV Payment",
"phone": "919820988398",
"merchant_id": 8739528,
"reseller_id": "11ee-0e7e-5403fde2-9523-0a696b110fde",
"udf2": "1370625260",
"udf3": "r-hway-TPV-REFERENCE",
"udf5": "whatsapp",
"txn_s2s_flow": "4",
"s2s_client_ip": "157.240.22.9",
"s2s_device_info": "Mozilla/5.0 (iPhone) AppleWebKit/602.4.6",
"beneficiarydetail": beneficiary_json,
"hash": payment_hash
}
response = requests.post(url, headers=headers, json=payload)
return response.json()<?php
$url = "https://test-partnerapilayer.payu.in/apilayer/partner/payments";
// Prepare beneficiary details
$beneficiary = [
"ifscCode" => "ICIC0001234",
"accountNumber" => "123456789012",
"accountHolderName" => "Test User"
];
$beneficiaryJson = json_encode($beneficiary);
// Compute hash
$hashString = "8739528|28471834809170982|518.02|TPV Payment|||1370625260|r-hway-TPV-REFERENCE||whatsapp||||||YOUR_CLIENT_SECRET";
$paymentHash = hash('sha512', $hashString);
$payload = [
"txnid" => "28471834809170982",
"amount" => "518.02",
"productinfo" => "TPV Payment",
"phone" => "919820988398",
"merchant_id" => 8739528,
"reseller_id" => "11ee-0e7e-5403fde2-9523-0a696b110fde",
"udf2" => "1370625260",
"udf3" => "r-hway-TPV-REFERENCE",
"udf5" => "whatsapp",
"txn_s2s_flow" => "4",
"s2s_client_ip" => "157.240.22.9",
"s2s_device_info" => "Mozilla/5.0 (iPhone) AppleWebKit/602.4.6",
"beneficiarydetail" => $beneficiaryJson,
"hash" => $paymentHash
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer 039e0d1d70f467f946e2d73bd43868df856cfaa352ea54591a76bfc4a08d3487",
"Content-Type: application/json"
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>Note: In the cURL example, the JSON string
beneficiarydetailhas escaped quotes (\") to be valid within the outer JSON payload.
Sample Response
The response structure for UPI TPV is identical to UPI Intent S2S:
{
"metaData": {
"message": null,
"referenceId": "7a3060b7462bd2ce6d025c9997220e01",
"statusCode": null,
"txnId": "28471834809170982",
"txnStatus": "pending",
"unmappedStatus": "pending"
},
"result": {
"paymentId": "30478359672",
"merchantName": "HathwayCableAndDatacomLimited",
"merchantVpa": "hathway.payu@indus",
"amount": "518.02",
"intentURIData": "pa=hathway.payu@indus&pn=HATHWAY...&tr=30478359672&tid=PPPL304...&am=518.02&cu=INR&tn=UPIIntent",
"acsTemplate": "PGh0bWw+PGhlYWQ+...",
"otpPostUrl": "https://secure.payu.in/ResponseHandler.php"
}
}Response Parameters
Same as UPI Intent S2S response.
TPV Validation Flow
- Customer initiates payment with TPV
- Partner sends request with
beneficiarydetail - PayU sets
bankcode=INTTPVandapi_version=6internally - Customer completes payment in UPI app
- PayU validates that the account number in UPI app matches
beneficiarydetail.accountNumber - If match: Payment proceeds to success
- If mismatch: Payment is declined with validation error
Using encrypted_data (Alternative)
Instead of beneficiarydetail, you can send encrypted beneficiary details:
{
"txnid": "28471834809170982",
"amount": "518.02",
"productinfo": "TPV Payment",
"phone": "919820988398",
"merchant_id": 8739528,
"reseller_id": "11ee-0e7e-5403fde2-9523-0a696b110fde",
"txn_s2s_flow": "4",
"s2s_client_ip": "157.240.22.9",
"s2s_device_info": "Mozilla/5.0 (iPhone)...",
"encrypted_data": "BASE64_ENCRYPTED_STRING_HERE",
"hash": "COMPUTED_HASH_VALUE"
}⚠️ Info Gap: The encryption method, key management, and exact format for
encrypted_datashould be confirmed with the PayU integration team.
Error Codes
| HTTP Status | Error Message | Description | Resolution |
|---|---|---|---|
| 400 | Invalid hash | Hash validation failed | Verify hash formula and client_secret |
| 401 | Auth token is not valid | Access token expired or invalid | Regenerate OAuth token |
| 400 | Invalid beneficiarydetail format | Malformed JSON in beneficiarydetail | Validate JSON structure before sending |
| 400 | Beneficiary account mismatch | Account number doesn't match UPI account | Ensure customer uses correct account |
| 400 | IFSC code invalid | Provided IFSC code doesn't exist | Validate IFSC against RBI master list |
Testing UPI TPV
Test Beneficiary Details
⚠️ Info Gap: Test IFSC codes and account numbers for UAT should be provided by PayU. Consult your integration team for valid test data.
Sample Test Data (to be confirmed):
{
"ifscCode": "ICIC0001234",
"accountNumber": "123456789012",
"accountHolderName": "Test User"
}Next Steps
After initiating UPI TPV payment:
- Extract
result.intentURIDatafrom the response - Invoke customer's UPI app
- Customer completes payment (PayU validates beneficiary account)
- Wait for webhook callback from PayU
- Verify payment using POST /partner/verifyPayment
Webhook Indicators for TPV:
mode: "UPI"bankcode: "INTTPV" (automatically set by PayU)
