Debit Card EMI - Native OTP Flow
The steps involved in debit card integration with native OTP flow:
Step 1: Check Pre-EMI Eligibility
Before initiating a payment request for a customer, it is necessary to check their eligibility using the Get Checkout Details API. For more information, refer to Get Checkout Details API.
Step 2: Initiate the payment request
Request parameters
Send the transaction information to PayU through a server-to-server curl request to initiate the transaction. As a result of this API call, the customer will receive the OTP. For more information, refer to Collect Payment API - Server-to-Server.
| Parameter | Description | Example |
|---|---|---|
keymandatory
|
String The merchant's unique key provided by PayU during onboarding.
|
JP***g |
txnidmandatory
|
String Transaction ID, which is a unique reference number generated by the merchant for tracking the order.
|
ashdfu72634 |
amountmandatory
|
String The payment amount for the transaction.
|
10.00 |
productinfomandatory
|
String A brief description of the product associated with the transaction.
|
iPhone |
firstnamemandatory
|
String The customer's first name.
|
Ashish |
emailmandatory
|
String The customer's email address.
|
[email protected] |
phonemandatory
|
String The customer's phone number.
|
9876543210 |
pgmandatory
|
String Payment gateway. For card payments, use the value CC.
|
CC |
bankcodemandatory
|
String Unique bank code identifying the payment option. Use respective codes (e.g., AMEX, VISA, MAST).
|
AMEX |
ccnummandatory
|
String 13-19 digit card number (e.g., 15 digits for AMEX, 13+ for other cards).
|
5123456789012346 |
ccnamemandatory
|
String The name on the card as provided by the customer.
|
Ashish Kumar |
ccvvmandatory
|
String 3-digit (for most cards) or 4-digit (for AMEX) Card Verification Value entered by the customer.
|
123 |
ccexpmonmandatory
|
String Card expiry month. Must be in two-digit MM format (e.g., 01 for January).
|
10 |
ccexpyrmandatory
|
String Card expiry year. Must be in four-digit YYYY format.
|
2024 |
hashmandatory
|
String Validated hash generated by the merchant according to the formula sha512(key|txnid|amount|productinfo|firstname|email|...|SALT).
|
eabec285... |
surlmandatory
|
String Success URL where the customer is redirected upon successful transaction.
|
https://your-success-url.com |
furlmandatory
|
String Failure URL where the customer is redirected upon payment failure.
|
https://your-failure-url.com |
s2s_device_infomandatory
|
String This parameter must have the customer agent's device. **Note**: This information is helpful when it comes to issues related to fraud detection and chargebacks. Hence, it is must to provide the correct information. |
Mozilla |
s2s_client_ipmandatory
|
String This parameter must have the source IP of the customer. **Note**: This information is helpful when it comes to issues related to fraud detection and chargebacks. Hence, it is must to provide the correct information. |
10.11.101.11 |
txn_s2s_flowmandatory
|
String This parameter must be passed with the value as 4.
|
4 |
lastnameoptional
|
String The customer's last name.
|
Kumar |
address1optional
|
String The first line of the billing address.
|
H.No-17, Block C |
address2optional
|
String The second line of the billing address.
|
Street ABC |
cityoptional
|
String The customer's city as part of the billing address.
|
Mumbai |
stateoptional
|
String The customer's state as part of the billing address.
|
Maharashtra |
countryoptional
|
String The customer's country.
|
India |
zipcodeoptional
|
String Billing address PIN/ZIP code of the customer.
|
400001 |
udf1optional
|
String User-defined field for storing transaction-specific information.
|
CustomField1 |
udf2optional
|
String User-defined field for storing transaction-specific information.
|
CustomField2 |
udf3optional
|
String User-defined field for storing transaction-specific information.
|
CustomField3 |
udf4optional
|
String User-defined field for storing transaction-specific information.
|
CustomField4 |
udf5optional
|
String User-defined field for storing transaction-specific information.
|
CustomField5 |
alt_idoptional
|
String Alternative ID (Alt ID) token for Guest Checkout transactions.
|
5123456789012346 |
additional_infooptional
|
Object JSON object containing additional card/token-related details (e.g., cryptograms, token references).
|
{"last4Digits":"2346","TAVV":"..."} |
threeDS2RequestDataoptional
|
Object JSON object containing browser information for 3DS Secure 2.0 authentication.
|
{"browserInfo":{"userAgent":"Mozilla/5.0",...}} |
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" \
-d "txnid=H6mUfE0ccAY94j" \
-d "amount=20000.00" \
-d "firstname=Ashish" \
-d "[email protected]" \
-d "phone=9876543210" \
-d "productinfo=iPhone" \
-d "pg=EMI" \
-d "bankcode=EMIA3" \
-d "surl=https://apiplayground-response.herokuapp.com/" \
-d "furl=https://apiplayground-response.herokuapp.com/" \
-d "ccnum=5123456789012346" \
-d "ccexpmon=05" \
-d "ccexpyr=2022" \
-d "ccvv=123" \
-d "ccname=" \
-d "s2s_device_info=Mozilla" \
-d "s2s_client_ip=10.11.101.11" \
-d "txn_s2s_flow=4" \
-d "hash=782057a8bb0288c858149b4805103befa22041bb3092bc45a813738b43742e31baeae92375be5286a98b44ed66c36121aba0fff6a3170339a4949bc880125d36"
/**
* PayU Credit Card EMI Payment with Native OTP Flow Integration
*
* IMPORTANT: This should only be executed server-side (e.g., in Node.js), never in the browser,
* as it contains sensitive payment information.
*/
// Form data parameters
const formData = new URLSearchParams();
formData.append('key', 'JP***g'); // Your merchant key
formData.append('txnid', 'H6mUfE0ccAY94j'); // Unique transaction ID
formData.append('amount', '20000.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', 'EMIA3'); // Bank code (Axis Bank EMI)
formData.append('surl', 'https://apiplayground-response.herokuapp.com/'); // Success URL
formData.append('furl', 'https://apiplayground-response.herokuapp.com/'); // Failure URL
// Card details - SENSITIVE DATA
formData.append('ccnum', '5123456789012346'); // Card number
formData.append('ccexpmon', '05'); // Expiry month
formData.append('ccexpyr', '2022'); // Expiry year
formData.append('ccvv', '123'); // CVV
formData.append('ccname', ''); // Cardholder name
// Native OTP flow parameters
formData.append('s2s_device_info', 'Mozilla'); // Customer's device info
formData.append('s2s_client_ip', '10.11.101.11'); // Customer's IP address
formData.append('txn_s2s_flow', '4'); // Native OTP flow identifier
// Security hash
formData.append('hash', '782057a8bb0288c858149b4805103befa22041bb3092bc45a813738b43742e31baeae92375be5286a98b44ed66c36121aba0fff6a3170339a4949bc880125d36');
// Request options
const requestOptions = {
method: 'POST',
headers: {
'accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: formData
};
// Execute the request
fetch('https://test.payu.in/_payment', 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 and handle OTP flow
// For Native OTP flow, you'll need to display OTP input to the user
// and submit it in a subsequent request
})
.catch(error => {
console.error('Error:', error);
});
import urllib.request
import urllib.parse
import json
from typing import Dict, Any
def process_emi_payment_with_native_otp() -> Dict[str, Any]:
"""
Process credit card EMI payment with Native OTP flow using PayU's S2S integration
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"
# Prepare the form data
payload = {
"key": "JP***g", # Your merchant key
"txnid": "H6mUfE0ccAY94j", # Unique transaction ID
"amount": "20000.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": "EMIA3", # Bank code (Axis Bank EMI)
"surl": "https://apiplayground-response.herokuapp.com/", # Success URL
"furl": "https://apiplayground-response.herokuapp.com/", # Failure URL
# Card details - SENSITIVE DATA
"ccnum": "5123456789012346", # Card number
"ccexpmon": "05", # Expiry month
"ccexpyr": "2022", # Expiry year
"ccvv": "123", # CVV
"ccname": "", # Cardholder name
# Native OTP flow parameters
"s2s_device_info": "Mozilla", # Customer's device info
"s2s_client_ip": "10.11.101.11", # Customer's IP address
"txn_s2s_flow": "4", # Native OTP flow identifier
# Security hash
"hash": "782057a8bb0288c858149b4805103befa22041bb3092bc45a813738b43742e31baeae92375be5286a98b44ed66c36121aba0fff6a3170339a4949bc880125d36"
}
# 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_emi_payment_with_native_otp()
print(f"Status Code: {result['status_code']}")
if 'error' in result:
print(f"Error: {result['error']}")
print(f"Response: {result['response']}")
# For Native OTP flow, you'll need to display OTP input to the user
# and submit it in a subsequent request
<?php
/**
* Process credit card EMI payment with Native OTP flow using PayU's S2S integration
*
* IMPORTANT: This is a server-side function. Never expose payment details to client-side code.
*
* @return array Response from PayU API
*/
function processEmiPaymentWithNativeOtp() {
// API endpoint
$url = "https://test.payu.in/_payment";
// Prepare the form data
$payload = [
"key" => "JP***g", // Your merchant key
"txnid" => "H6mUfE0ccAY94j", // Unique transaction ID
"amount" => "20000.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" => "EMIA3", // Bank code (Axis Bank EMI)
"surl" => "https://apiplayground-response.herokuapp.com/", // Success URL
"furl" => "https://apiplayground-response.herokuapp.com/", // Failure URL
// Card details - SENSITIVE DATA
"ccnum" => "5123456789012346", // Card number
"ccexpmon" => "05", // Expiry month
"ccexpyr" => "2022", // Expiry year
"ccvv" => "123", // CVV
"ccname" => "", // Cardholder name
// Native OTP flow parameters
"s2s_device_info" => "Mozilla", // Customer's device info
"s2s_client_ip" => "10.11.101.11", // Customer's IP address
"txn_s2s_flow" => "4", // Native OTP flow identifier
// Security hash
"hash" => "782057a8bb0288c858149b4805103befa22041bb3092bc45a813738b43742e31baeae92375be5286a98b44ed66c36121aba0fff6a3170339a4949bc880125d36"
];
// 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
];
}
// Process the response
// For Native OTP flow, you'll need to display OTP input to the user
// and submit it in a subsequent request
return [
"status_code" => $statusCode,
"response" => $response
];
}
// Example usage
$result = processEmiPaymentWithNativeOtp();
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 Credit Card EMI Payment with Native OTP Flow Integration
*
* IMPORTANT: This is a server-side implementation. Never expose payment details to client-side code.
*/
public class PayUEmiPaymentWithNativeOtpProcessor {
// API endpoint
private static final String PAYU_TEST_URL = "https://test.payu.in/_payment";
/**
* Process credit card EMI payment with Native OTP flow through PayU
* @return PaymentResponse containing status and response data
*/
public PaymentResponse processEmiPaymentWithNativeOtp() {
try {
// Initialize URL
URL url = new URL(PAYU_TEST_URL);
// Prepare form parameters
Map<String, String> params = new HashMap<>();
params.put("key", "JP***g"); // Your merchant key
params.put("txnid", "H6mUfE0ccAY94j"); // Unique transaction ID
params.put("amount", "20000.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", "EMIA3"); // Bank code (Axis Bank EMI)
params.put("surl", "https://apiplayground-response.herokuapp.com/"); // Success URL
params.put("furl", "https://apiplayground-response.herokuapp.com/"); // Failure URL
// Card details - SENSITIVE DATA
params.put("ccnum", "5123456789012346"); // Card number
params.put("ccexpmon", "05"); // Expiry month
params.put("ccexpyr", "2022"); // Expiry year
params.put("ccvv", "123"); // CVV
params.put("ccname", ""); // Cardholder name
// Native OTP flow parameters
params.put("s2s_device_info", "Mozilla"); // Customer's device info
params.put("s2s_client_ip", "10.11.101.11"); // Customer's IP address
params.put("txn_s2s_flow", "4"); // Native OTP flow identifier
// Security hash
params.put("hash", "782057a8bb0288c858149b4805103befa22041bb3092bc45a813738b43742e31baeae92375be5286a98b44ed66c36121aba0fff6a3170339a4949bc880125d36");
// 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);
}
}
// Process the response
// For Native OTP flow, you'll need to display OTP input to the user
// and submit it in a subsequent request
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) {
PayUEmiPaymentWithNativeOtpProcessor processor = new PayUEmiPaymentWithNativeOtpProcessor();
PaymentResponse result = processor.processEmiPaymentWithNativeOtp();
System.out.println("Status Code: " + result.getStatusCode());
if (result.isSuccess()) {
System.out.println("Response: " + result.getResponse());
// Here you would extract OTP page details from the response
// and display the OTP input to the user
} else {
System.out.println("Error: " + result.getError());
}
}
}
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text;
namespace PayUEmiNativeOtpIntegration
{
/// <summary>
/// PayU Credit Card EMI Payment with Native OTP Flow Processor
///
/// IMPORTANT: This is a server-side implementation. Never expose payment details to client-side code.
/// </summary>
public class PayUEmiPaymentWithNativeOtpProcessor
{
// API endpoint
private const string PayuTestUrl = "https://test.payu.in/_payment";
/// <summary>
/// Process credit card EMI payment with Native OTP flow through PayU
/// </summary>
/// <returns>PaymentResponse containing status and response data</returns>
public async Task<PaymentResponse> ProcessEmiPaymentWithNativeOtpAsync()
{
try
{
// Prepare form parameters
var formData = new Dictionary<string, string>
{
{ "key", "JP***g" }, // Your merchant key
{ "txnid", "H6mUfE0ccAY94j" }, // Unique transaction ID
{ "amount", "20000.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", "EMIA3" }, // Bank code (Axis Bank EMI)
{ "surl", "https://apiplayground-response.herokuapp.com/" }, // Success URL
{ "furl", "https://apiplayground-response.herokuapp.com/" }, // Failure URL
// Card details - SENSITIVE DATA
{ "ccnum", "5123456789012346" }, // Card number
{ "ccexpmon", "05" }, // Expiry month
{ "ccexpyr", "2022" }, // Expiry year
{ "ccvv", "123" }, // CVV
{ "ccname", "" }, // Cardholder name
// Native OTP flow parameters
{ "s2s_device_info", "Mozilla" }, // Customer's device info
{ "s2s_client_ip", "10.11.101.11" }, // Customer's IP address
{ "txn_s2s_flow", "4" }, // Native OTP flow identifier
// Security hash
{ "hash", "782057a8bb0288c858149b4805103befa22041bb3092bc45a813738b43742e31baeae92375be5286a98b44ed66c36121aba0fff6a3170339a4949bc880125d36" }
};
// 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();
// Process the response
// For Native OTP flow, you'll need to display OTP input to the user
// and submit it in a subsequent request
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 PayUEmiPaymentWithNativeOtpProcessor();
var result = await processor.ProcessEmiPaymentWithNativeOtpAsync();
Console.WriteLine($"Status Code: {result.StatusCode}");
if (result.IsSuccess)
{
Console.WriteLine($"Response: {result.Response}");
// Here you would extract OTP page details from the response
// and display the OTP input to the user
}
else
{
Console.WriteLine($"Error: {result.Error}");
}
}
}
}
Sample response
{
"metaData": {
"message": "No Error",
"referenceId": "b6035f64240b1862295bc571952cf984",
"statusCode": "E000",
"txnId": "payuTestTransaction2746829",
"unmappedStatus": "success",
"submitOtp": {
"status": "success"
}
},
"result": {
"mihpayid": "15270336226",
"mode": "CC",
"status": "success",
"key": "4wvMqy",
"txnid": "payuTestTransaction2746829",
"amount": "1.10",
"addedon": "2022-06-01 17:39:29",
"productinfo": "Product Info",
"firstname": "Postman",
"lastname": "",
"address1": "",
"address2": "",
"city": "",
"state": "",
"country": "",
"zipcode": "",
"email": "[email protected]",
"phone": "9988776655",
"udf1": "",
"udf2": "",
"udf3": "",
"udf4": "",
"udf5": "",
"udf6": "",
"udf7": "",
"udf8": "",
"udf9": "",
"udf10": "",
"card_token": "",
"card_no": "XXXXXXXXXXXX8006",
"field0": "",
"field1": "6540854745166970506094",
"field2": "947167",
"field3": "1.10",
"field4": "15270336226",
"field5": "100",
"field6": "",
"field7": "AUTHPOSITIVE",
"field8": "",
"field9": "Transaction is Successful",
"payment_source": "payuPureS2SAuth",
"PG_TYPE": "DC-PG",
"error": "E000",
"error_Message": "No Error",
"cardToken": "",
"net_amount_debit": "1.1",
"discount": "0.00",
"offer_key": "",
"offer_availed": "",
"unmappedstatus": "captured",
"hash": "cdc409dfd15a842b8d15d6627d0027619882ed800773fa413cef491ae8ff2ef0cdfa654680ba4c8f3567313c6a6b00b94cb3bb5e16bad21d26be01216a69af41",
"bank_ref_no": "6540854745166970506094",
"bank_ref_num": "6540854745166970506094",
"bankcode": "CC",
"surl": "",
"curl": "",
"furl": "",
"card_hash": "fdb59253e36daf8b3969525ae3799ccb4bb41993a5d2fcaf22737ec3ac8b90ab"
}
}Step 3: Submit the OTP
Once your customer enters the OTP on the payment page (postUrl/acsTemplate), pass the OTP using the Submit OTP API. For more information, refer to Submit OTP API.
Sample Response
- Success scenario
{
"metaData": {
"txnId": "43242dfsdf",
"referenceId": "348adsdas7d9ad798as7d87dsad87a9s",
"txnStatus": "Enrolled",
"unmappedStatus": "pending",
"statusCode": "",
"message": "",
"submitOtp": {
"status": "success"
}
},
"result": {
"mihpayid": "412345678912343542",
"mode": "DC",
"status": "success",
"key": "hUmBue",
"txnid": "0b33346ret72c1d18e878b",
"amount": "10.00",
"addedon": "2019-12-09 11:42:41",
"productinfo": "ProductInfo",
"firstname": "Payu-Admin",
"lastname": "",
"address1": "",
"address2": "",
"city": "",
"state": "",
"country": "",
"zipcode": "",
"email": "[email protected]",
"phone": "1234567890",
"unmappedstatus": "captured",
"hash": "04792dd6264c1dad0d4621..."
}
}- Failure scenario
{
"metaData": {
"txnId": "43242dfsdf",
"referenceId": "348adsdas7d9ad798as7d87dsad87a9s",
"txnStatus": "Enrolled",
"unmappedStatus": "pending",
"statusCode": null,
"message": null,
"submitOtp": {
"status": "failed",
"attemptsLeft": 2
}
},
"result": {}
}Resend OTP
If the customer enters the incorrect OTP or an expired OTP, use Resend OTP API to handle the Resend OTP request made by a customer.
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.
👉 For more details, refer to Webhooks for Payments.
Updated 9 days ago
