UPI Collection with S2S Integration
In UPI Collect, the sequence of APIs is called to follow for redirection less experience.
Before you begin:Register for an account with PayU before you start integration. For more information, refer to Register for a Merchant Account.
Important UPI Integration Changes as per NPCI Mandate on UPI Collect Disablement: For Android and Desktop web, UPI Collect flow has limitations. Consider migrating to UPI Intent S2S for better user experience.
Steps to integrate
Validate the Virtual Payment Address (VPA) before initiating the UPI transaction
Initiate the UPI payment request to PayU with required parameters
Monitor and check the status of the UPI transaction in real-time
Handle and process the server-to-server callback response from PayU
Verify the payment status and ensure transaction completion
Workflow

Step 1: Validate VPA
After the customer enters VPA on your website, call this API to validate. For a sample request or response, refer to Validate VPA.
Step 2: Initiate the payment to PayU
Environment
| Test Environment | https://test.payu.in/_payment |
| Production Environment | https://secure.payu.in/_payment |
Postman Collection: Download the S2S > UPI Integration Postman Collection from: https://www.postman.com/integratewithpayu-849372/payu-integration-s-workspace/folder/5t0c6pe/upi-s2s-integration
Mandatory Parameters
| Parameter | Description |
|---|---|
| key | String Merchant key provided by PayU during onboarding. |
| txnid | String The transaction ID is a reference number for a specific order that is 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. |
| surl | String The success URL, which is the page PayU will redirect to if the transaction is successful. |
| furl | String The failure URL, which is the page PayU will redirect to if the transaction fails. |
| hash | String SHA-512(key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5||||||Salt) |
| pg | String For UPI Collection, use UPI. |
| bankcode | String For UPI Collection, use UPI. |
| vpa | String The Virtual Payment Address of the customer. |
| txn_s2s_flow | String Value is 1 for UPI Collection. |
| s2s_client_ip | String The IP address of the client device. |
| s2s_device_info | String Device information/user-agent string of the client. |
Optional Parameters
| Parameter | Description |
|---|---|
| api_version | String The API version for this API. |
| address1 | String The first line of the billing address. |
| 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 option. Character Limit: 20. |
| udf1–udf5 | String User-defined fields used to store any information corresponding to a particular transaction. |
| notifyurl | String The URL where PayU sends the server-to-server callback response. |
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=UPI' \
--data-urlencode 'bankcode=UPI' \
--data-urlencode 'vpa=test@okhdfcbank' \
--data-urlencode 'surl=https://apiplayground-response.herokuapp.com/' \
--data-urlencode 'furl=https://apiplayground-response.herokuapp.com/' \
--data-urlencode 'txn_s2s_flow=1' \
--data-urlencode 's2s_client_ip=10.200.12.12' \
--data-urlencode 's2s_device_info=Mozilla/5.0' \
--data-urlencode 'hash=YOUR_HASH_VALUE'import requests
url = "https://test.payu.in/_payment"
headers = {"Content-Type": "application/x-www-form-urlencoded"}
data = {
"key": "YOUR_MERCHANT_KEY", "txnid": "TXN_12345", "amount": "10.00",
"productinfo": "iPhone", "firstname": "Ashish", "email": "[email protected]",
"phone": "9876543210", "pg": "UPI", "bankcode": "UPI",
"vpa": "test@okhdfcbank",
"surl": "https://apiplayground-response.herokuapp.com/",
"furl": "https://apiplayground-response.herokuapp.com/",
"txn_s2s_flow": "1", "s2s_client_ip": "10.200.12.12",
"s2s_device_info": "Mozilla/5.0", "hash": "YOUR_HASH_VALUE"
}
response = requests.post(url, headers=headers, data=data)
print(response.status_code)
print(response.text)<?php
$url = "https://test.payu.in/_payment";
$data = http_build_query([
"key"=>"YOUR_MERCHANT_KEY","txnid"=>"TXN_12345","amount"=>"10.00",
"productinfo"=>"iPhone","firstname"=>"Ashish","email"=>"[email protected]",
"phone"=>"9876543210","pg"=>"UPI","bankcode"=>"UPI","vpa"=>"test@okhdfcbank",
"surl"=>"https://apiplayground-response.herokuapp.com/",
"furl"=>"https://apiplayground-response.herokuapp.com/",
"txn_s2s_flow"=>"1","s2s_client_ip"=>"10.200.12.12",
"s2s_device_info"=>"Mozilla/5.0","hash"=>"YOUR_HASH_VALUE"
]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/x-www-form-urlencoded"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
echo "Status: ".curl_getinfo($ch,CURLINFO_HTTP_CODE)."\n";
echo $response;
curl_close($ch);
?>import java.net.URI; import java.net.URLEncoder; import java.net.http.*;
import java.nio.charset.StandardCharsets; import java.util.*;
public class UpiCollectionS2S {
public static void main(String[] args) throws Exception {
Map<String,String> p = new LinkedHashMap<>();
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","UPI"); p.put("bankcode","UPI");
p.put("vpa","test@okhdfcbank");
p.put("surl","https://apiplayground-response.herokuapp.com/");
p.put("furl","https://apiplayground-response.herokuapp.com/");
p.put("txn_s2s_flow","1"); p.put("s2s_client_ip","10.200.12.12");
p.put("s2s_device_info","Mozilla/5.0"); p.put("hash","YOUR_HASH_VALUE");
StringJoiner sj = new StringJoiner("&");
for (Map.Entry<String,String> e : p.entrySet())
sj.add(URLEncoder.encode(e.getKey(),StandardCharsets.UTF_8)+"="+URLEncoder.encode(e.getValue(),StandardCharsets.UTF_8));
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = 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<String> resp = client.send(req,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 UpiCollectionS2S {
static async Task Main() {
using var client = new HttpClient();
var data = 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","UPI"},{"bankcode","UPI"},{"vpa","test@okhdfcbank"},
{"surl","https://apiplayground-response.herokuapp.com/"},
{"furl","https://apiplayground-response.herokuapp.com/"},
{"txn_s2s_flow","1"},{"s2s_client_ip","10.200.12.12"},
{"s2s_device_info","Mozilla/5.0"},{"hash","YOUR_HASH_VALUE"}
});
var response = await client.PostAsync("https://test.payu.in/_payment", data);
Console.WriteLine("Status: "+(int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}Step 3: Check UPI Transaction Status
After initiating the payment, check the transaction status. For more information, refer to UPI Collection API Reference.
Step 4: Check the S2S Callback Response
S2S Callback Details
The server to server response would be sent by PayU on a pre-set URL, which has to be provided by the merchant.
Step 5: 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 9 days ago
