LazyPay Pay-in-3 - Merchant Hosted Checkout
Start by using the Get Checkout Details API (get_checkout_details) to fetch the eligible payment options available for the customer. This will include the payInParts param in the response if they are eligible. The response will indicate whether the customer is an Pre approved (Existing to Bank or ETB) customer or Not Pre-approved (New to Bank or NTB customer. Make sure to do this before processing the transaction through the Collect Payment API (/_payment) as this will help to check customer's eligibility before making payments call.
If the customer is eligible, proceed with the merchant-hosted collect flow and verify the transaction outcome.
Customer Journey
-
Customer selects "Pay-in-3" option and enters mobile number
-
Seamless merchant calls Get Checkout Details API with amount and mobile number
-
System checks customer eligibility for Pay-in-3
-
System returns complete repayment schedule will be returned.
You need to show the repayment schedule to the customer, so that they can initiate payment.
For pre-approved customers
- Get Checkout Details API returns:
is_eligible: true- Down payment amount (pay now amount customer pays during transaction)
- 2nd installment amount and date
- 3rd installment amount and date
- Processing fee and GST (if applicable)
For non pre-approved (NTB) customers
- Get Checkout Details API returns eligibility check but does not return tenures for Pay-in-3
- Merchant collects additional PI (Personal Information) details from customer:
- Name
- PAN
- Pincode
- Gender
- Consent for bureau pull
- Merchant calls Get EMI Checkout Details API with collected PI details
- System performs bureau pull and returns:
- Tenures if customer is eligible
- Not eligible status if customer fails eligibility check
- Eligible customer clicks "Proceed" on merchant website
- Merchant calls
_paymentAPI with selected pay mode, that is, Pay-in-3, bankcode: LZYPI3
Handle Guest Checkout Transaction: You can handle Guest Checkout transactions for EMI and BNPL integrations where applicable. For more information, refer to Cards Integration > Handling Guest Checkout Transactions.
Steps to integrate
Call Get Checkout Details with the right EMI filters and interpret the GCD response (including LAZYPI3) before payment initiation.
Start the payment process using the merchant-hosted collect flow
Handle and process the response received from PayU after payment initiation
Confirm the payment status and ensure successful transaction completion
Step 1: Check LazyPay Pay in 3 Eligibility
Step 1a. Check Customer Eligibility (Pay-in-3)
After you collect the Customer's mobile number and the amount , call GCD with the following request parameters. If Eligible, You will get the complete pay in 3 repayment schedule. The sample request and ETB sample response is as follows:
| Environment | URL |
|---|---|
| Production | https://info.payu.in/merchant/postservice?form=2 |
| Test | https://test.payu.in/merchant/postservice?form=2 |
Request Parameters
| Parameter | Description | Example |
|---|---|---|
key |
|
JP***g |
command |
|
get_checkout_details |
var1 |
|
{"requestId":"abc123","transactionDetails":{"amount":500}} |
hash |
|
{{info_hash}} |
var1 JSON Fields Description
var1 JSON Fields Description
| Parameter | Description | Example |
|---|---|---|
requestId |
| |
transactionDetails |
| |
transactionDetails.source |
| null |
transactionDetails.amount |
| |
transactionDetails.pre_authorize |
| null |
transactionDetails.additional_charges |
| null |
useCase |
| |
useCase.checkNTBCustomerEligibility |
| true |
useCase.checkCustomerEligibility |
| true |
useCase.returnUserLimit |
| true |
customerDetails |
| |
customerDetails.mobile |
| |
filters |
| |
filters.paymentOptions |
| |
filters.paymentOptions.emi |
| |
filters.paymentOptions.emi.dc |
| "all" |
filters.paymentOptions.emi.cardless |
| "all" |
filters.paymentOptions.emi.payInParts |
| "all" |
Sample request
curl --location 'https://info.payu.in/merchant/postservice?form=2' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'key=JP***g' \
--data-urlencode 'command=get_checkout_details' \
--data-urlencode 'var1={"requestId":"9078698a15d746feadcffbdaf979a198","transactionDetails":{"source":null,"amount":16721,"pre_authorize":null,"additional_charges":null},"useCase":{"checkNTBCustomerEligibility":true,"checkCustomerEligibility":true,"returnUserLimit":true},"customerDetails":{"mobile":"9910522063"},"filters":{"paymentOptions":{"emi":{"dc":"all","cardless":"all"}}}}' \
--data-urlencode 'hash={{info_hash}}'import requests
url = "https://info.payu.in/merchant/postservice?form=2"
headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
data = {
"key": "JP***g",
"command": "get_checkout_details",
"var1": '{"requestId":"9078698a15d746feadcffbdaf979a198","transactionDetails":{"source":null,"amount":16721,"pre_authorize":null,"additional_charges":null},"useCase":{"checkNTBCustomerEligibility":true,"checkCustomerEligibility":true,"returnUserLimit":true},"customerDetails":{"mobile":"9910522063"},"filters":{"paymentOptions":{"emi":{"dc":"all","cardless":"all"}}}}',
"hash": "{{info_hash}}"
}
try:
response = requests.post(url, headers=headers, data=data)
print("Status Code:", response.status_code)
print("Response:", response.text)
except requests.exceptions.RequestException as e:
print("Error:", e)using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var client = new HttpClient();
var formData = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("key", "JP***g"),
new KeyValuePair<string, string>("command", "get_checkout_details"),
new KeyValuePair<string, string>("var1", "{\"requestId\":\"9078698a15d746feadcffbdaf979a198\",\"transactionDetails\":{\"source\":null,\"amount\":16721,\"pre_authorize\":null,\"additional_charges\":null},\"useCase\":{\"checkNTBCustomerEligibility\":true,\"checkCustomerEligibility\":true,\"returnUserLimit\":true},\"customerDetails\":{\"mobile\":\"9910522063\"},\"filters\":{\"paymentOptions\":{\"emi\":{\"dc\":\"all\",\"cardless\":\"all\"}}}}"),
new KeyValuePair<string, string>("hash", "{{info_hash}}")
};
var content = new FormUrlEncodedContent(formData);
try
{
var response = await client.PostAsync("https://info.payu.in/merchant/postservice?form=2", content);
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine("Status Code: " + response.StatusCode);
Console.WriteLine("Response: " + responseBody);
}
catch (HttpRequestException e)
{
Console.WriteLine("Error: " + e.Message);
}
}
}async function getCheckoutDetails() {
const url = "https://info.payu.in/merchant/postservice?form=2";
const formData = new URLSearchParams();
formData.append("key", "JP***g");
formData.append("command", "get_checkout_details");
formData.append("var1", JSON.stringify({
requestId: "9078698a15d746feadcffbdaf979a198",
transactionDetails: {
source: null,
amount: 16721,
pre_authorize: null,
additional_charges: null
},
useCase: {
checkNTBCustomerEligibility: true,
checkCustomerEligibility: true,
returnUserLimit: true
},
customerDetails: {
mobile: "9910522063"
},
filters: {
paymentOptions: {
emi: {
dc: "all",
cardless: "all"
}
}
}
}));
formData.append("hash", "{{info_hash}}");
try {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: formData.toString()
});
const data = await response.text();
console.log("Status Code:", response.status);
console.log("Response:", data);
} catch (error) {
console.error("Error:", error);
}
}
getCheckoutDetails();import java.io.*;
import java.net.*;
public class GetCheckoutDetails {
public static void main(String[] args) {
try {
URL url = new URL("https://info.payu.in/merchant/postservice?form=2");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setDoOutput(true);
String var1 = URLEncoder.encode(
"{"requestId":"9078698a15d746feadcffbdaf979a198","transactionDetails":{"source":null,"amount":16721,"pre_authorize":null,"additional_charges":null},"useCase":{"checkNTBCustomerEligibility":true,"checkCustomerEligibility":true,"returnUserLimit":true},"customerDetails":{"mobile":"9910522063"},"filters":{"paymentOptions":{"emi":{"dc":"all","cardless":"all"}}}}",
"UTF-8"
);
String formData = "key=" + URLEncoder.encode("JP***g", "UTF-8")
+ "&command=" + URLEncoder.encode("get_checkout_details", "UTF-8")
+ "&var1=" + var1
+ "&hash=" + URLEncoder.encode("{{info_hash}}", "UTF-8");
try (OutputStream os = conn.getOutputStream()) {
os.write(formData.getBytes("UTF-8"));
}
int statusCode = conn.getResponseCode();
System.out.println("Status Code: " + statusCode);
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
System.out.println("Response: " + response.toString());
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}<?php
$url = "https://info.payu.in/merchant/postservice?form=2";
$postFields = http_build_query([
"key" => "JP***g",
"command" => "get_checkout_details",
"var1" => json_encode([
"requestId" => "9078698a15d746feadcffbdaf979a198",
"transactionDetails" => [
"source" => null,
"amount" => 16721,
"pre_authorize" => null,
"additional_charges" => null
],
"useCase" => [
"checkNTBCustomerEligibility" => true,
"checkCustomerEligibility" => true,
"returnUserLimit" => true
],
"customerDetails" => [
"mobile" => "9910522063"
],
"filters" => [
"paymentOptions" => [
"emi" => [
"dc" => "all",
"cardless" => "all"
]
]
]
]),
"hash" => "{{info_hash}}"
]);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postFields,
CURLOPT_HTTPHEADER => [
"Content-Type: application/x-www-form-urlencoded"
]
]);
$response = curl_exec($ch);
if (curl_error($ch)) {
echo "Error: " . curl_error($ch);
} else {
echo "Status Code: " . curl_getinfo($ch, CURLINFO_HTTP_CODE) . "\n";
echo "Response: " . $response . "\n";
}
curl_close($ch);
?>Sample response
The response will provide complete repayment schedule will be returned. You must display this schedule to your customer.
ETB
Scenario: GCD response when the customer is ETB .
{
"httpCode": "200",
"message": "",
"status": 1,
"data": {
"details": {
"paymentOption": {
"emi": {
"all": {
"cardless": {
...
...
...
}
},
"payInParts": {
"LAZYPI3": {
"tenure": "3",
"processingFee": 94.4,
"processingFeeGst": 14.4,
"maximumEligibleLimit": 120000.0,
"eligibility": {
"status": true
},
"repaymentSchedule": [
{
"amount": 4000.0,
"serialNo": 0,
"dueDate": "2026-06-10"
},
{
"amount": 4000.0,
"serialNo": 1,
"dueDate": "2026-08-01"
},
{
"amount": 4000.0,
"serialNo": 2,
"dueDate": "2026-09-01"
}
]
}
}
}
}
}
}
}GCD response — customer is NTB
{
"httpCode": "200",
"message": "",
"status": 1,
"data": {
"details": {
"paymentOption": {
"emi": {
"all": {
"cardless": {
"all": {
"IDFCCL": {
"tenureOptions": {
"IDFCCL12": {
"tenure": 12,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
},
"IDFCCL03": {
"tenure": 3,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
},
"IDFCCL06": {
"tenure": 6,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
},
"IDFCCL09": {
"tenure": 9,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
}
},
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "Customer not eligible for EMI"
}
},
"SMPI3": {
"tenureOptions": {
"SMPI03": {
"tenure": 3,
"maximumAmount": null,
"eligibility": {
"status": true
}
}
},
"maximumAmount": null,
"eligibility": {
"status": true
}
},
"ZESTMON": {
"tenureOptions": {
"ZEST09": {
"tenure": 9,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
},
"ZEST06": {
"tenure": 6,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
},
"ZEST03": {
"tenure": 3,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
},
"ZESTMON": {
"tenure": 0,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
},
"ZEST12": {
"tenure": 12,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
}
},
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "Customer not eligible for EMI"
}
},
"ICICCL": {
"tenureOptions": {
"ICICCL12": {
"tenure": 12,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
},
"ICICCL03": {
"tenure": 3,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
},
"ICICCL06": {
"tenure": 6,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
},
"ICICCL09": {
"tenure": 9,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
}
},
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "Customer not eligible for EMI"
}
},
"HMECDT": {
"tenureOptions": {
"HMECDT03": {
"tenure": 3,
"maximumAmount": null,
"eligibility": {
"status": true
},
"maximumEligibleLimit": 12000.0
},
"HMECDT12": {
"tenure": 12,
"maximumAmount": null,
"eligibility": {
"status": true
},
"maximumEligibleLimit": 12000.0
},
"HMECDT18": {
"tenure": 18,
"maximumAmount": null,
"eligibility": {
"status": true
},
"maximumEligibleLimit": 12000.0
},
"HMECDT06": {
"tenure": 6,
"maximumAmount": null,
"eligibility": {
"status": true
},
"maximumEligibleLimit": 12000.0
},
"HMECDT09": {
"tenure": 9,
"maximumAmount": null,
"eligibility": {
"status": true
},
"maximumEligibleLimit": 12000.0
}
},
"maximumAmount": null,
"eligibility": {
"status": true
}
},
"LPEMI": {
"tenureOptions": {
"LPEMI12": {
"tenure": 12,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
},
"LPEMI": {
"tenure": 0,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
},
"LPEMI09": {
"tenure": 9,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "Minimum required amount is 15000"
}
},
"LPEMI03": {
"tenure": 3,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
},
"LPEMI06": {
"tenure": 6,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
}
},
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "Customer not eligible for EMI"
}
},
"HDFC_CL": {
"tenureOptions": {
"HDFCCL09": {
"tenure": 9,
"maximumAmount": null,
"eligibility": {
"status": true
}
},
"HDFCCL18": {
"tenure": 18,
"maximumAmount": null,
"eligibility": {
"status": true
}
},
"HDFCCL06": {
"tenure": 6,
"maximumAmount": null,
"eligibility": {
"status": true
}
},
"HDFCCL03": {
"tenure": 3,
"maximumAmount": null,
"eligibility": {
"status": true
}
},
"HDFCCL12": {
"tenure": 12,
"maximumAmount": null,
"eligibility": {
"status": true
}
}
},
"maximumAmount": null,
"eligibility": {
"status": true
}
}
},
"hasEligible": true
}
},
"ntb": {
"payInParts": {
"all": {
"LAZYPI3": {
"maximumAmount": null,
"eligibility": {
"status": true
}
}
},
"hasEligible": true
},
"cardless": {
"all": {},
"hasEligible": false
}
}
}
}
}
}
}GCD response — customer is not eligible
{
"httpCode": "200",
"message": "",
"status": 1,
"data": {
"details": {
"paymentOption": {
"emi": {
"all": {
"cardless": {
"all": {
"IDFCCL": {
"tenureOptions": {
"IDFCCL12": {
"tenure": 12,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
},
"IDFCCL03": {
"tenure": 3,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
},
"IDFCCL06": {
"tenure": 6,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
},
"IDFCCL09": {
"tenure": 9,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
}
},
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "Customer not eligible for EMI"
}
},
"SMPI3": {
"tenureOptions": {
"SMPI03": {
"tenure": 3,
"maximumAmount": null,
"eligibility": {
"status": true
}
}
},
"maximumAmount": null,
"eligibility": {
"status": true
}
},
"ZESTMON": {
"tenureOptions": {
"ZEST09": {
"tenure": 9,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
},
"ZEST06": {
"tenure": 6,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
},
"ZEST03": {
"tenure": 3,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
},
"ZESTMON": {
"tenure": 0,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
},
"ZEST12": {
"tenure": 12,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
}
},
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "Customer not eligible for EMI"
}
},
"ICICCL": {
"tenureOptions": {
"ICICCL12": {
"tenure": 12,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
},
"ICICCL03": {
"tenure": 3,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
},
"ICICCL06": {
"tenure": 6,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
},
"ICICCL09": {
"tenure": 9,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "API Time Out"
}
}
},
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "Customer not eligible for EMI"
}
},
"HMECDT": {
"tenureOptions": {
"HMECDT03": {
"tenure": 3,
"maximumAmount": null,
"eligibility": {
"status": true
},
"maximumEligibleLimit": 12000.0
},
"HMECDT12": {
"tenure": 12,
"maximumAmount": null,
"eligibility": {
"status": true
},
"maximumEligibleLimit": 12000.0
},
"HMECDT18": {
"tenure": 18,
"maximumAmount": null,
"eligibility": {
"status": true
},
"maximumEligibleLimit": 12000.0
},
"HMECDT06": {
"tenure": 6,
"maximumAmount": null,
"eligibility": {
"status": true
},
"maximumEligibleLimit": 12000.0
},
"HMECDT09": {
"tenure": 9,
"maximumAmount": null,
"eligibility": {
"status": true
},
"maximumEligibleLimit": 12000.0
}
},
"maximumAmount": null,
"eligibility": {
"status": true
}
},
"LPEMI": {
"tenureOptions": {
"LPEMI12": {
"tenure": 12,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
},
"LPEMI": {
"tenure": 0,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
},
"LPEMI09": {
"tenure": 9,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "Minimum required amount is 15000"
}
},
"LPEMI03": {
"tenure": 3,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
},
"LPEMI06": {
"tenure": 6,
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
}
},
"maximumAmount": null,
"eligibility": {
"status": false,
"reason": "Customer not eligible for EMI"
}
},
"HDFC_CL": {
"tenureOptions": {
"HDFCCL09": {
"tenure": 9,
"maximumAmount": null,
"eligibility": {
"status": true
}
},
"HDFCCL18": {
"tenure": 18,
"maximumAmount": null,
"eligibility": {
"status": true
}
},
"HDFCCL06": {
"tenure": 6,
"maximumAmount": null,
"eligibility": {
"status": true
}
},
"HDFCCL03": {
"tenure": 3,
"maximumAmount": null,
"eligibility": {
"status": true
}
},
"HDFCCL12": {
"tenure": 12,
"maximumAmount": null,
"eligibility": {
"status": true
}
}
},
"maximumAmount": null,
"eligibility": {
"status": true
}
}
},
"hasEligible": true
}
},
"payInParts": {
"LAZYPI3": {
"tenure": "3",
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
}
}
}
}
}
}
}Step 1b: Check Main Eligibility for NTB Customer
If Get Checkout Details shows the customer is New to the Bank (NTB) for LazyPay Pay-in-3, you must obtain full eligibility using Get EMI Checkout Details (GECD). Collect the required personal information (PI) from the customer and include it in the GECD request to check main eligibility. When the customer is eligible, the response includes the down payment, 2nd and 3rd installment amounts and dates, and any applicable fees (similar to the pre-approved path).
Sample request
curl --location 'https://pp94info.payu.in/info/linkAndPay/get_emi_checkout_details' \
--header 'x-credential-username: x0i6r2' \
--header 'Content-Type: application/json' \
--header 'authorization: {{authorization}}' \
--header 'date: {{date}}' \
--data '{
"bankCode": "LAZYPI3",
"phone": "8178959206",
"amount": "10000.00",
"pg": "EMI",
"checkCustomerEligibilityWithDetails": true,
"customerDetails": {
"panNumber": "KMEPS9053J",
"dob": "14-12-1996",
"zipcode": "411014",
"firstName": "Shray",
"lastName": "Suri",
"bureauPullConsent": "false",
"gender": "Male",
"income": "100000",
"employeeType": "Salaried"
}
}'import requests
import json
url = "https://pp94info.payu.in/info/linkAndPay/get_emi_checkout_details"
headers = {
"x-credential-username": "x0i6r2",
"Content-Type": "application/json",
"authorization": "{{authorization}}",
"date": "{{date}}"
}
payload = {
"bankCode": "LAZYPI3",
"phone": "8178959206",
"amount": "10000.00",
"pg": "EMI",
"checkCustomerEligibilityWithDetails": True,
"customerDetails": {
"panNumber": "KMEPS9053J",
"dob": "14-12-1996",
"zipcode": "411014",
"firstName": "Shray",
"lastName": "Suri",
"bureauPullConsent": "false",
"gender": "Male",
"income": "100000",
"employeeType": "Salaried"
}
}
try:
response = requests.post(url, headers=headers, data=json.dumps(payload))
print("Status Code:", response.status_code)
print("Response:", response.text)
except requests.exceptions.RequestException as e:
print("Error:", e)using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-credential-username", "x0i6r2");
client.DefaultRequestHeaders.Add("authorization", "{{authorization}}");
client.DefaultRequestHeaders.Add("date", "{{date}}");
var jsonBody = @"{
""bankCode"": ""LAZYPI3"",
""phone"": ""8178959206"",
""amount"": ""10000.00"",
""pg"": ""EMI"",
""checkCustomerEligibilityWithDetails"": true,
""customerDetails"": {
""panNumber"": ""KMEPS9053J"",
""dob"": ""14-12-1996"",
""zipcode"": ""411014"",
""firstName"": ""Shray"",
""lastName"": ""Suri"",
""bureauPullConsent"": ""false"",
""gender"": ""Male"",
""income"": ""100000"",
""employeeType"": ""Salaried""
}
}";
var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
try
{
var response = await client.PostAsync("https://pp94info.payu.in/info/linkAndPay/get_emi_checkout_details", content);
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine("Status Code: " + response.StatusCode);
Console.WriteLine("Response: " + responseBody);
}
catch (HttpRequestException e)
{
Console.WriteLine("Error: " + e.Message);
}
}
}async function getEmiCheckoutDetails() {
const url = "https://pp94info.payu.in/info/linkAndPay/get_emi_checkout_details";
const payload = {
bankCode: "LAZYPI3",
phone: "8178959206",
amount: "10000.00",
pg: "EMI",
checkCustomerEligibilityWithDetails: true,
customerDetails: {
panNumber: "KMEPS9053J",
dob: "14-12-1996",
zipcode: "411014",
firstName: "Shray",
lastName: "Suri",
bureauPullConsent: "false",
gender: "Male",
income: "100000",
employeeType: "Salaried"
}
};
try {
const response = await fetch(url, {
method: "POST",
headers: {
"x-credential-username": "x0i6r2",
"Content-Type": "application/json",
"authorization": "{{authorization}}",
"date": "{{date}}"
},
body: JSON.stringify(payload)
});
const data = await response.text();
console.log("Status Code:", response.status);
console.log("Response:", data);
} catch (error) {
console.error("Error:", error);
}
}
getEmiCheckoutDetails();import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
public class GetEmiCheckoutDetails {
public static void main(String[] args) {
try {
URL url = new URL("https://pp94info.payu.in/info/linkAndPay/get_emi_checkout_details");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("x-credential-username", "x0i6r2");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("authorization", "{{authorization}}");
conn.setRequestProperty("date", "{{date}}");
conn.setDoOutput(true);
String jsonBody = "{"
+ ""bankCode": "LAZYPI3","
+ ""phone": "8178959206","
+ ""amount": "10000.00","
+ ""pg": "EMI","
+ ""checkCustomerEligibilityWithDetails": true,"
+ ""customerDetails": {"
+ ""panNumber": "KMEPS9053J","
+ ""dob": "14-12-1996","
+ ""zipcode": "411014","
+ ""firstName": "Shray","
+ ""lastName": "Suri","
+ ""bureauPullConsent": "false","
+ ""gender": "Male","
+ ""income": "100000","
+ ""employeeType": "Salaried""
+ "}"
+ "}";
try (OutputStream os = conn.getOutputStream()) {
os.write(jsonBody.getBytes(StandardCharsets.UTF_8));
}
int statusCode = conn.getResponseCode();
System.out.println("Status Code: " + statusCode);
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
System.out.println("Response: " + response.toString());
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}<?php
$url = "https://pp94info.payu.in/info/linkAndPay/get_emi_checkout_details";
$payload = json_encode([
"bankCode" => "LAZYPI3",
"phone" => "8178959206",
"amount" => "10000.00",
"pg" => "EMI",
"checkCustomerEligibilityWithDetails" => true,
"customerDetails" => [
"panNumber" => "KMEPS9053J",
"dob" => "14-12-1996",
"zipcode" => "411014",
"firstName" => "Shray",
"lastName" => "Suri",
"bureauPullConsent" => "false",
"gender" => "Male",
"income" => "100000",
"employeeType" => "Salaried"
]
]);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
"x-credential-username: x0i6r2",
"Content-Type: application/json",
"authorization: {{authorization}}",
"date: {{date}}"
]
]);
$response = curl_exec($ch);
if (curl_error($ch)) {
echo "Error: " . curl_error($ch);
} else {
echo "Status Code: " . curl_getinfo($ch, CURLINFO_HTTP_CODE) . "\n";
echo "Response: " . $response . "\n";
}
curl_close($ch);
?>Sample response
Success scenario
Response when registration got success
{
"httpCode": "200",
"message": "",
"status": 1,
"data": {
"emi": {
"ntb": {
"payInParts": {
"LAZYPI3": {
"tenure": "3",
"minimumAmount": 3000.0,
"maximumAmount": 180000.0,
"interestRate": 0,
"processingFee": 78.67,
"processingFeeGst": 12.0,
"maximumEligibleLimit": 51000.0,
"eligibility": {
"status": true
},
"repaymentSchedule": [
{
"amount": 3333.33,
"serialNo": 0,
"dueDate": "2026-06-10"
},
{
"amount": 3333.0,
"serialNo": 1,
"dueDate": "2026-08-01"
},
{
"amount": 3333.67,
"serialNo": 2,
"dueDate": "2026-09-01"
}
]
}
}
}
}
}
}
Failure scenario
When registration got failed:
{
"httpCode": "200",
"message": "",
"status": 1,
"data": {
"emi": {
"ntb": {
"payInParts": {
"LAZYPI3": {
"eligibility": {
"status": false,
"reason": "This mobile number is not eligible. Please change the mobile number."
}
}
}
}
}
}
}Step 2: Initiate the payment
Post the following additional parameters for using the Cardless EMI. Check the response when you try enter the values in API Reference. For complete list of parameters, refer to Collect Payment API - EMI for the complete list parameters with Try It experience.
Request Parameters
Request parameters
| Parameter | Description | Example |
|---|---|---|
key mandatory |
String Merchant key provided by PayU during onboarding. |
JP****g |
txnid mandatory |
String The transaction ID is a reference number for a specific order that is generated by the merchant. |
|
amount mandatory |
String The payment amount for the transaction. |
|
productinfo mandatory |
String A brief description of the product. |
|
firstname mandatory |
String The first name of the customer. |
Ashish |
email mandatory |
String The email address of the customer. |
[email protected] |
phone mandatory |
String The phone number of the customer. |
|
pg mandatory |
String It defines the payment category that the merchant wants the customer to see by default on the PayU's payment page. In this integration, "EMI" must be specified. |
EMI |
bankcode mandatory |
String Post this parameter with the values as LZYPI3. |
LZYPI3 |
ccnum mandatory only for Bajaj Finserv |
String Use 13-19 digit card number for credit/debit cards (15 digits for AMEX, 13-19 for Maestro) and validate with LUHN algorithm. Refer to Card Number Formats and display error message on invalid input. |
5123456789012346 |
ccname optional |
String This parameter must contain the name on card – as entered by the customer for the transaction. |
Ashish Kumar |
ccvv optional |
String Use 3-digit CVV number for credit/debit cards and 4-digit security code (4DBC/CID) for AMEX cards. Validate with BIN API. |
123 |
ccexpmon optional |
String This parameter must contain the card's expiry month – as entered by the user for the transaction. It must always be in 2 digits or in MM format. For months 1-9, this parameter must be appended with 0 – like 01, 02…09. For months 10-12, this parameter must not be appended – It should be 10,11 and 12 respectively. |
10 |
ccexpyr optional |
String This parameter must contain the card's expiry year – as entered by the customer for the transaction. It must be of four digits. |
2021 |
furl mandatory |
String The success URL, which is the page PayU will redirect to if the transaction is successful. |
|
surl mandatory |
String The Failure URL, which is the page PayU will redirect to if the transaction is failed. |
|
hash mandatory |
String It is the hash calculated by the merchant. The hash calculation logic is: sha512(key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5||||||SALT) |
|
address1 optional |
String The first line of the billing address. For Fraud Detection: This information is helpful when it comes to issues related to fraud detection and chargebacks. Hence, it is must to provide the correct information. |
|
address2 optional |
String The second line of the billing address. |
|
city optional |
String The city where your customer resides as part of the billing address. |
|
state optional |
String The state where your customer resides as part of the billing address. |
|
country optional |
String The country where your customer resides. |
|
zipcode optional |
String Billing address zip code is mandatory for the cardless EMI option. Character Limit-20 |
|
udf1 optional |
String User-defined fields (udf) are used to store any information corresponding to a particular transaction. You can use up to five udfs in the post designated as udf1, udf2, udf3, udf4, udf5. |
|
udf2 optional |
String User-defined fields (udf) are used to store any information corresponding to a particular transaction. You can use up to five udfs in the post designated as udf1, udf2, udf3, udf4, udf5. |
|
udf3 optional |
String User-defined fields (udf) are used to store any information corresponding to a particular transaction. |
|
udf4 optional |
String User-defined fields (udf) are used to store any information corresponding to a particular transaction. |
|
udf5 optional |
String User-defined fields (udf) are used to store any information corresponding to a particular transaction. |
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.
Sample request
Sample request
curl -X POST "https://test.payu.in/_payment" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded" -d"key=JP***g&txnid=EaE4ZO3vU4iPsp&amount=10.00&firstname=Ashish&[email protected]&phone=9876543210&productinfo=iPhone&pg=EMI&bankcode=LZYPI3&surl=https://apiplayground-response.herokuapp.com/&furl=https://apiplayground-response.herokuapp.com/&ccnum=1234&ccexpmon=05&ccexpyr=2022&ccvv=123&ccname=undefined&store_card_token=1234 4567 2456 3566&storecard_token_type=1&additional_info={“last4Digits”: “1234”, “tavv”: “ABCDEFGH”,”trid”:”1234567890”, “tokenRefNo”:”abcde123456”}&hash=fc3206829a6b4f8e300aeefb8f91add568b83dc90d01383a8e16553cc9600a3aefd4be2e370d32f0315ef1b9f28740515a9556b55abfefa7b54b434f894c9304"/**
* PayU Cardless EMI Payment Integration using Fetch API
*
* IMPORTANT: This should only be executed server-side (e.g., in Node.js), never in the browser,
* as it contains sensitive payment information.
*/
// Payment endpoint
const url = 'https://test.payu.in/_payment';
// Additional info as a JSON object
const additionalInfo = {
"last4Digits": "1234",
"tavv": "ABCDEFGH",
"trid": "1234567890",
"tokenRefNo": "abcde123456"
};
// Form data parameters
const formData = new URLSearchParams();
formData.append('key', 'JP***g'); // Your merchant key
formData.append('txnid', 'EaE4ZO3vU4iPsp'); // Unique transaction ID
formData.append('amount', '10.00'); // Payment amount
formData.append('firstname', 'Ashish'); // Customer's name
formData.append('email', '[email protected]'); // Customer's email
formData.append('phone', '9876543210'); // Customer's phone
formData.append('productinfo', 'iPhone'); // Product information
formData.append('pg', 'EMI'); // Payment gateway (EMI)
formData.append('bankcode', 'EMI03'); // Bank code (Cardless EMI provider)
formData.append('surl', 'https://apiplayground-response.herokuapp.com/'); // Success URL
formData.append('furl', 'https://apiplayground-response.herokuapp.com/'); // Failure URL
// Token and card details
formData.append('ccnum', '1234'); // Limited card details for verification
formData.append('ccexpmon', '05'); // Expiry month
formData.append('ccexpyr', '2022'); // Expiry year
formData.append('ccvv', '123'); // CVV
formData.append('ccname', 'undefined'); // Cardholder name
formData.append('store_card_token', '1234 4567 2456 3566'); // Tokenized card
formData.append('storecard_token_type', '1'); // Token type
formData.append('additional_info', JSON.stringify(additionalInfo)); // Tokenization details
// Security hash
formData.append('hash', 'fc3206829a6b4f8e300aeefb8f91add568b83dc90d01383a8e16553cc9600a3aefd4be2e370d32f0315ef1b9f28740515a9556b55abfefa7b54b434f894c9304');
// Request options
const requestOptions = {
method: 'POST',
headers: {
'accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: formData
};
// Execute the request
fetch(url, requestOptions)
.then(response => {
console.log('Status Code:', response.status);
return response.text(); // or response.json() if you're sure it returns JSON
})
.then(data => {
console.log('Response:', data);
// Process payment response here
})
.catch(error => {
console.error('Error:', error);
});
import urllib.request
import urllib.parse
import json
from typing import Dict, Any
def process_cardless_emi_payment() -> Dict[str, Any]:
"""
Process cardless EMI payment using PayU's Merchant Hosted Checkout
IMPORTANT: This is a server-side function. Never expose payment details to client-side code.
Returns:
Dictionary with response from PayU API
"""
# API endpoint
url = "https://test.payu.in/_payment"
# Additional info as a dictionary
additional_info = {
"last4Digits": "1234",
"tavv": "ABCDEFGH",
"trid": "1234567890",
"tokenRefNo": "abcde123456"
}
# Prepare the form data
payload = {
"key": "JP***g", # Your merchant key
"txnid": "EaE4ZO3vU4iPsp", # Unique transaction ID
"amount": "10.00", # Payment amount
"firstname": "Ashish", # Customer's name
"email": "[email protected]", # Customer's email
"phone": "9876543210", # Customer's phone
"productinfo": "iPhone", # Product information
"pg": "EMI", # Payment gateway (EMI)
"bankcode": "EMI03", # Bank code (Cardless EMI provider)
"surl": "https://apiplayground-response.herokuapp.com/", # Success URL
"furl": "https://apiplayground-response.herokuapp.com/", # Failure URL
# Token and card details
"ccnum": "1234", # Limited card details for verification
"ccexpmon": "05", # Expiry month
"ccexpyr": "2022", # Expiry year
"ccvv": "123", # CVV
"ccname": "undefined", # Cardholder name
"store_card_token": "1234 4567 2456 3566", # Tokenized card
"storecard_token_type": "1", # Token type
"additional_info": json.dumps(additional_info), # Tokenization details
# Security hash
"hash": "fc3206829a6b4f8e300aeefb8f91add568b83dc90d01383a8e16553cc9600a3aefd4be2e370d32f0315ef1b9f28740515a9556b55abfefa7b54b434f894c9304"
}
# Convert dictionary to URL-encoded form data
data = urllib.parse.urlencode(payload).encode('utf-8')
# Set headers
headers = {
"accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded"
}
# Create a request object
req = urllib.request.Request(url, data=data, headers=headers, method="POST")
try:
# Send the request and get the response
with urllib.request.urlopen(req) as response:
response_data = response.read().decode('utf-8')
# Process and return response
return {
"status_code": response.getcode(),
"response": response_data
}
except urllib.error.HTTPError as e:
# Handle HTTP errors
error_data = e.read().decode('utf-8')
return {
"status_code": e.code,
"error": e.reason,
"response": error_data
}
except Exception as e:
# Handle other exceptions
return {
"status_code": 500,
"error": str(e),
"response": "An error occurred during payment processing"
}
# Example usage
if __name__ == "__main__":
result = process_cardless_emi_payment()
print(f"Status Code: {result['status_code']}")
if 'error' in result:
print(f"Error: {result['error']}")
print(f"Response: {result['response']}")
<?php
/**
* Process cardless EMI payment using PayU's Merchant Hosted Checkout
*
* IMPORTANT: This is a server-side function. Never expose payment details to client-side code.
*
* @return array Response from PayU API
*/
function processCardlessEmiPayment() {
// API endpoint
$url = "https://test.payu.in/_payment";
// Additional info as an array
$additionalInfo = [
"last4Digits" => "1234",
"tavv" => "ABCDEFGH",
"trid" => "1234567890",
"tokenRefNo" => "abcde123456"
];
// Prepare the form data
$payload = [
"key" => "JP***g", // Your merchant key
"txnid" => "EaE4ZO3vU4iPsp", // Unique transaction ID
"amount" => "10.00", // Payment amount
"firstname" => "Ashish", // Customer's name
"email" => "[email protected]", // Customer's email
"phone" => "9876543210", // Customer's phone
"productinfo" => "iPhone", // Product information
"pg" => "EMI", // Payment gateway (EMI)
"bankcode" => "EMI03", // Bank code (Cardless EMI provider)
"surl" => "https://apiplayground-response.herokuapp.com/", // Success URL
"furl" => "https://apiplayground-response.herokuapp.com/", // Failure URL
// Token and card details
"ccnum" => "1234", // Limited card details for verification
"ccexpmon" => "05", // Expiry month
"ccexpyr" => "2022", // Expiry year
"ccvv" => "123", // CVV
"ccname" => "undefined", // Cardholder name
"store_card_token" => "1234 4567 2456 3566", // Tokenized card
"storecard_token_type" => "1", // Token type
"additional_info" => json_encode($additionalInfo), // Tokenization details
// Security hash
"hash" => "fc3206829a6b4f8e300aeefb8f91add568b83dc90d01383a8e16553cc9600a3aefd4be2e370d32f0315ef1b9f28740515a9556b55abfefa7b54b434f894c9304"
];
// Initialize cURL session
$ch = curl_init($url);
// Set cURL options
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"accept: application/json",
"Content-Type: application/x-www-form-urlencoded"
]);
// For additional security in production
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
// Execute the request
$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
$errno = curl_errno($ch);
// Close cURL session
curl_close($ch);
// Handle response
if ($errno) {
return [
"status_code" => 500,
"error" => $error,
"response" => "cURL Error: " . $error
];
}
return [
"status_code" => $statusCode,
"response" => $response
];
}
// Example usage
$result = processCardlessEmiPayment();
echo "Status Code: " . $result["status_code"] . "\n";
if (isset($result["error"])) {
echo "Error: " . $result["error"] . "\n";
}
echo "Response: " . $result["response"] . "\n";
?>
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;
/**
* PayU Cardless EMI Payment Processor for Merchant Hosted Checkout
*
* IMPORTANT: This is a server-side implementation. Never expose payment details to client-side code.
*/
public class PayUCardlessEmiPaymentProcessor {
// API endpoint
private static final String PAYU_TEST_URL = "https://test.payu.in/_payment";
/**
* Process cardless EMI payment through PayU
* @return PaymentResponse containing status and response data
*/
public PaymentResponse processCardlessEmiPayment() {
try {
// Initialize URL
URL url = new URL(PAYU_TEST_URL);
// Additional info JSON
String additionalInfo = "{"
+ "\"last4Digits\": \"1234\","
+ "\"tavv\": \"ABCDEFGH\","
+ "\"trid\": \"1234567890\","
+ "\"tokenRefNo\": \"abcde123456\""
+ "}";
// Prepare form parameters
Map<String, String> params = new HashMap<>();
params.put("key", "JP***g"); // Your merchant key
params.put("txnid", "EaE4ZO3vU4iPsp"); // Unique transaction ID
params.put("amount", "10.00"); // Payment amount
params.put("firstname", "Ashish"); // Customer's name
params.put("email", "[email protected]"); // Customer's email
params.put("phone", "9876543210"); // Customer's phone
params.put("productinfo", "iPhone"); // Product information
params.put("pg", "EMI"); // Payment gateway (EMI)
params.put("bankcode", "EMI03"); // Bank code (Cardless EMI provider)
params.put("surl", "https://apiplayground-response.herokuapp.com/"); // Success URL
params.put("furl", "https://apiplayground-response.herokuapp.com/"); // Failure URL
// Token and card details
params.put("ccnum", "1234"); // Limited card details for verification
params.put("ccexpmon", "05"); // Expiry month
params.put("ccexpyr", "2022"); // Expiry year
params.put("ccvv", "123"); // CVV
params.put("ccname", "undefined"); // Cardholder name
params.put("store_card_token", "1234 4567 2456 3566"); // Tokenized card
params.put("storecard_token_type", "1"); // Token type
params.put("additional_info", additionalInfo); // Tokenization details
// Security hash
params.put("hash", "fc3206829a6b4f8e300aeefb8f91add568b83dc90d01383a8e16553cc9600a3aefd4be2e370d32f0315ef1b9f28740515a9556b55abfefa7b54b434f894c9304");
// Convert parameters to URL-encoded form data
StringJoiner formData = new StringJoiner("&");
for (Map.Entry<String, String> entry : params.entrySet()) {
formData.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" +
URLEncoder.encode(entry.getValue(), "UTF-8"));
}
byte[] postData = formData.toString().getBytes(StandardCharsets.UTF_8);
// Configure connection
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("accept", "application/json");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(postData.length));
conn.setDoOutput(true);
conn.setConnectTimeout(5000);
conn.setReadTimeout(15000);
// Send request
try (DataOutputStream dos = new DataOutputStream(conn.getOutputStream())) {
dos.write(postData);
dos.flush();
}
// Get response
int responseCode = conn.getResponseCode();
// Read response data
StringBuilder response = new StringBuilder();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(
responseCode >= 400 ? conn.getErrorStream() : conn.getInputStream(),
StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
}
return new PaymentResponse(responseCode, response.toString(), null);
} catch (IOException e) {
// Handle exception
return new PaymentResponse(500, null, "Error: " + e.getMessage());
}
}
/**
* Payment response wrapper class
*/
public static class PaymentResponse {
private final int statusCode;
private final String response;
private final String error;
public PaymentResponse(int statusCode, String response, String error) {
this.statusCode = statusCode;
this.response = response;
this.error = error;
}
public int getStatusCode() {
return statusCode;
}
public String getResponse() {
return response;
}
public String getError() {
return error;
}
public boolean isSuccess() {
return statusCode >= 200 && statusCode < 300;
}
}
// Example usage
public static void main(String[] args) {
PayUCardlessEmiPaymentProcessor processor = new PayUCardlessEmiPaymentProcessor();
PaymentResponse result = processor.processCardlessEmiPayment();
System.out.println("Status Code: " + result.getStatusCode());
if (result.isSuccess()) {
System.out.println("Response: " + result.getResponse());
} else {
System.out.println("Error: " + result.getError());
}
}
}
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text;
using System.Text.Json;
namespace PayUCardlessEmiIntegration
{
/// <summary>
/// PayU Cardless EMI Payment Processor for Merchant Hosted Checkout
///
/// IMPORTANT: This is a server-side implementation. Never expose payment details to client-side code.
/// </summary>
public class PayUCardlessEmiPaymentProcessor
{
// API endpoint
private const string PayuTestUrl = "https://test.payu.in/_payment";
/// <summary>
/// Process cardless EMI payment through PayU
/// </summary>
/// <returns>PaymentResponse containing status and response data</returns>
public async Task<PaymentResponse> ProcessCardlessEmiPaymentAsync()
{
try
{
// Create additional info object
var additionalInfo = new
{
last4Digits = "1234",
tavv = "ABCDEFGH",
trid = "1234567890",
tokenRefNo = "abcde123456"
};
// Serialize additional info to JSON
string additionalInfoJson = JsonSerializer.Serialize(additionalInfo);
// Prepare form parameters
var formData = new Dictionary<string, string>
{
{ "key", "JP***g" }, // Your merchant key
{ "txnid", "EaE4ZO3vU4iPsp" }, // Unique transaction ID
{ "amount", "10.00" }, // Payment amount
{ "firstname", "Ashish" }, // Customer's name
{ "email", "[email protected]" }, // Customer's email
{ "phone", "9876543210" }, // Customer's phone
{ "productinfo", "iPhone" }, // Product information
{ "pg", "EMI" }, // Payment gateway (EMI)
{ "bankcode", "EMI03" }, // Bank code (Cardless EMI provider)
{ "surl", "https://apiplayground-response.herokuapp.com/" }, // Success URL
{ "furl", "https://apiplayground-response.herokuapp.com/" }, // Failure URL
// Token and card details
{ "ccnum", "1234" }, // Limited card details for verification
{ "ccexpmon", "05" }, // Expiry month
{ "ccexpyr", "2022" }, // Expiry year
{ "ccvv", "123" }, // CVV
{ "ccname", "undefined" }, // Cardholder name
{ "store_card_token", "1234 4567 2456 3566" }, // Tokenized card
{ "storecard_token_type", "1" }, // Token type
{ "additional_info", additionalInfoJson }, // Tokenization details
// Security hash
{ "hash", "fc3206829a6b4f8e300aeefb8f91add568b83dc90d01383a8e16553cc9600a3aefd4be2e370d32f0315ef1b9f28740515a9556b55abfefa7b54b434f894c9304" }
};
// Create HttpClient with timeout
using (var httpClient = new HttpClient())
{
httpClient.Timeout = TimeSpan.FromSeconds(30);
// Convert form data to content
var content = new FormUrlEncodedContent(formData);
// Add headers
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
httpClient.DefaultRequestHeaders.Add("accept", "application/json");
// Send POST request
var response = await httpClient.PostAsync(PayuTestUrl, content);
// Get response content
var responseContent = await response.Content.ReadAsStringAsync();
return new PaymentResponse(
(int)response.StatusCode,
responseContent,
null
);
}
}
catch (Exception ex)
{
// Handle exception
return new PaymentResponse(
500,
null,
$"Error: {ex.Message}"
);
}
}
/// <summary>
/// Payment response wrapper class
/// </summary>
public class PaymentResponse
{
public int StatusCode { get; }
public string Response { get; }
public string Error { get; }
public PaymentResponse(int statusCode, string response, string error)
{
StatusCode = statusCode;
Response = response;
Error = error;
}
public bool IsSuccess => StatusCode >= 200 && StatusCode < 300;
}
}
// Example usage
class Program
{
static async Task Main(string[] args)
{
var processor = new PayUCardlessEmiPaymentProcessor();
var result = await processor.ProcessCardlessEmiPaymentAsync();
Console.WriteLine($"Status Code: {result.StatusCode}");
if (result.IsSuccess)
{
Console.WriteLine($"Response: {result.Response}");
}
else
{
Console.WriteLine($"Error: {result.Error}");
}
}
}
}
Step 3: Check the response from PayU
Sample response
Array
(
[mihpayid] => 403993715523602563
[status] => success
[unmappedstatus] => captured
[key] => smsplus
[txnid] => v2tWbbdUOuacK9
[amount] => 20000.00
[discount] => 0.00
[net_amount_debit] => 20000.00
[addedon] => 2021-07-27 11:14:44
[productinfo] => iPhone
[firstname] => Ashish
[lastname] =>
[address1] =>
[address2] =>
[city] =>
[state] =>
[country] =>
[zipcode] =>
[email] => [email protected]
[phone] => 1234567890
[udf1] =>
[udf2] =>
[udf3] =>
[udf4] =>
[udf5] =>
[udf6] =>
[udf7] =>
[udf8] =>
[udf9] =>
[udf10] =>
[hash] => 10f8ead10cdf5f9b7bf9046987de046d63d62d6679dded9d5da8145f459066943570eec4aa184494ae77f99a8bcd55452af3c4eff0d7a7d3ba809c97b7c73045
[field1] => 0608273386032718000015
[field2] => 986987
[field3] => 10.00
[field4] => 403993715524069222
[field5] => 100
[field6] => 02
[field7] => AUTHPOSITIVE
[field8] =>
[field9] => Transaction is Successful [payment_source] => payu
[PG_TYPE] => EMI-PG
[bank_ref_num] => 3d7cc4a4-00c8-4705-a0e7-5708d2c2bb75
[bankcode]=> EMIA3
[error] => E000
[error_Message] => No Error
[name_on_card] => payu
[cardnum] =>XXXXXXXXXXXX1234
)Step 4: Verify 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 months ago
