Merchant Hosted Integration - Wealth Tech Payment
This section explains how to implement the _payment API for Wealth Tech merchants using Merchant Hosted Checkout integration. The _payment includes the *more_info parameter contains various fields including the Wealth Tech object (wtParams).
Note: Currently, PayU supports Net Banking and Card payment modes for Wealth Tech payments.
Step 1: Initiate the Payment to PayU
Environment
POST https://test.payu.in/_payment
Content-Type: application/x-www-form-urlencodedRequest Parameters
| Parameter | Description | Example |
|---|---|---|
keymandatory | String This parameter is the unique merchant key provided by PayU for your merchant account. For more information, refer to Generate Merchant Key and Salt. | 8488225 |
txnidmandatory | Varchar This parameter is known as Transaction ID (or OrderID). It is the order reference number generated at your (Merchant's) end. It is an identifier which you(merchant) would use to track a particular order. If a transaction using a particular transaction ID has already been successful at PayU, the usage of same Transaction ID again would fail. Hence, it is essential that you post us a unique transaction ID for every new transaction (Please make sure that the transaction ID being sent to us hasn't been successful earlier. In case of this duplication, the customer would get an error of 'duplicate Order ID'). | fd3e847h2 |
amountmandatory | float This parameter should contain the payment amount of the particular transaction. Note: Type-cast the amount to float type | 10 |
productinfomandatory | Varchar This parameter should contain a brief product description. It should be a string describing the product (The description type is entirely your choice). | T-shirt |
firstnamemandatory | Varchar This parameter must contain the first name of the customer. | Ankit |
emailmandatory | Varchar This parameter must contain the email of the customer | [email protected] |
phonemandatory | Integer Merchant needs to take the customer's GPay registered phone number and pass in this field. This field will be used for further mapping the customer VPA and initiate a collect request. | 9876543210 |
pgmandatory | String This parameter contains the payment method to be enabled to collect payment from your customer. For Net Banking, use NB and DC or CC for cards. | NB |
bankcodemandatory | String Each payment option is identified with a unique bank code at PayU. The merchant must post this parameter with the corresponding payment option's bank code value in it. For the list of bankcodes: * Net Banking: refer to Net Banking Codes * Cards: refer to Card Type Codes and Supported Banks for Cards. | AXIB |
surlmandatory | String The "surl" field is the success URL, which is the page PayU will redirect to if the transaction is successful. The merchant can handle the response at this URL after the customer is redirected there. | https://apiplayground-response.herokuapp.com/ |
furlmandatory | String The "furl" field is the Failure URL, which is the page PayU will redirect to if the transaction is failed. The merchant can handle the response at this URL after the customer is redirected there. | https://apiplayground-response.herokuapp.com/ |
api_version mandatory | API version must be posted as 21 | 21 |
hashmandatory | String The hash calculated by the merchant using the key and salt provided by PayU. The format for calculating the hash: sha512(key\|txnid\|amount\|productinfo\|firstname\|email\|udf1\|udf2\|udf3\|udf4\|udf5\|\|\|\|\|\|SALT) For more information, refer to Generate Hash. | a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0 |
| more_info mandatory for Wealth Tech | JSON This parameter contains various fields including the Wealth Tech object (wtParams). For more information on wtParams object field, refer to Wealth Tech object (wtParams) fields Description. | Refer to Wealth Tech object (wtParams) fields Description |
lastnameoptional | String The last name of the customer. | Sharma |
address1optional | String The first line of the billing address. | 123 Main Street |
address2optional | String The second line of the billing address. | Apartment 4B |
cityoptional | String The city where your customer resides as part of the billing address. | Mumbai |
stateoptional | String The state where your customer resides as part of the billing address. | Maharashtra |
countryoptional | String The country where your customer resides. | India |
zipcodeoptional | String Billing address zip code is mandatory for the cardless EMI option. | 400001 |
udf1mandatory for Cross-Border Payments | String This parameter has been made for you to keep any information corresponding to the transaction. Note: This parameter must contain buyer's PAN number for Cross-Border Payments. | ABCDE1234F |
udf2optional | string This parameter has been made for you to keep any information corresponding to the transaction. | Additional Info 1 |
udf3mandatory for Cross-Border Payments | String This parameter has been made for you to keep any information corresponding to the transaction. | GSTIN123456 |
udf4optional | String This parameter has been made for you to keep any information corresponding to the transaction. | Additional Info 2 |
udf5optional | String This parameter has been made for you to keep any information corresponding to the transaction. | Additional Info 3 |
additional_chargesoptional | String Collect additional charges for the transaction. For example, platform fee | 10.00 |
Wealth Tech Object (wtParams) Fields
Wealth Tech object wtparams fields description
Sample JSON Structure:
"more_info": {
"wtParams": [
{
"type": "mutual_fund",
"plan": "GD",
"amount": "50000",
"option": "G",
"scheme": "LT",
"receipt": "77407",
"mf_member_id": "123445",
"mf_user_id": "77407",
"mf_partner": "cams",
"mf_investment_type": "L",
"mf_amc_code": "UTB"
}
]
}Wealth Tech object (wtParams) fields Description
Sample JSON
"more_info": {
"wtParams": [
{
"type": "mutual_fund",
"plan": "GD",
"amount": "50000",
"option": "G",
"scheme": "LT",
"receipt": "77407",
"mf_member_id": "123445",
"mf_user_id": "77407",
"mf_partner": "cams",
"mf_investment_type": "L",
"mf_amc_code": "UTB"
}
]
}Fields description
These parameters are included within the more_info field as a JSON array under the fiedl wtParams:
Parameter | Description | Example |
|---|---|---|
type |
|
|
amount |
|
|
receipt |
|
|
mf_member_id |
|
|
mf_user_id |
|
|
mf_partner |
|
|
mf_investment_type |
|
|
plan |
|
|
folio
|
|
|
option |
|
|
scheme |
|
|
mf_amc_code |
|
|
Validation Rules
Mandatory Field Validations
- type: Must always be
"mutual_fund" - amount: Must match the overall order amount and be in paise
- receipt: Must be unique across transactions
- mf_member_id: Must be numeric with length between 5-20 characters
- mf_user_id: Maximum 10 characters allowed
- mf_partner: Must be one of:
"cams","kfin","bse","nse" - mf_investment_type: Only
"L"(Lump Sum) or"S"(SIP) allowed
Optional Field Validations
- mf_amc_code: Maximum 5 characters
- receipt: Maximum 25 characters for SIP registration ID
Hash Calculation
Concatenate fields in this exact sequence, then SHA-512:
key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5|SALT- Use empty strings for missing udf*.
- Compute on your server and include the lowercase hex digest as hash.
For more information, refer to Generate Hash.
Sample Code for Hashing
Concatenate fields in this exact sequence, then SHA-512:
key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5|SALT- Use empty strings for missing udf*.
- Compute on your server and include the lowercase hex digest as hash.
For more information, refer to Generate Hash.
Sample Code for Hashing
<?php
function generateHash($params, $salt) {
// Extract parameters or use empty string if not provided
$key = $params['key'];
$txnid = $params['txnid'];
$amount = $params['amount'];
$productinfo = $params['productinfo'];
$firstname = $params['firstname'];
$email = $params['email'];
$udf1 = isset($params['udf1']) ? $params['udf1'] : '';
$udf2 = isset($params['udf2']) ? $params['udf2'] : '';
$udf3 = isset($params['udf3']) ? $params['udf3'] : '';
$udf4 = isset($params['udf4']) ? $params['udf4'] : '';
$udf5 = isset($params['udf5']) ? $params['udf5'] : '';
// Construct hash string with exact parameter sequence
$hashString = $key . '|' . $txnid . '|' . $amount . '|' . $productinfo . '|' .
$firstname . '|' . $email . '|' . $udf1 . '|' . $udf2 . '|' .
$udf3 . '|' . $udf4 . '|' . $udf5 . '||||||' . $salt;
// Generate hash and convert to lowercase
return strtolower(hash('sha512', $hashString));
}
// Example usage
$params = [
'key' => 'yourKey',
'txnid' => 'yourTxnId',
'amount' => 'yourAmount',
'productinfo' => 'yourProductInfo',
'firstname' => 'yourFirstName',
'email' => 'yourEmail',
'udf1' => 'optional_value1'
// udf2, udf3, udf4, udf5 not provided - will be empty strings
];
$salt = 'yourSalt';
$hash = generateHash($params, $salt);
echo 'Generated Hash: ' . $hash;
?>
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
public class ImprovedHashGenerator {
public static String generateHash(Map<String, String> params, String salt) {
// Extract parameters or use empty string if not provided
String key = params.get("key");
String txnid = params.get("txnid");
String amount = params.get("amount");
String productinfo = params.get("productinfo");
String firstname = params.get("firstname");
String email = params.get("email");
String udf1 = params.getOrDefault("udf1", "");
String udf2 = params.getOrDefault("udf2", "");
String udf3 = params.getOrDefault("udf3", "");
String udf4 = params.getOrDefault("udf4", "");
String udf5 = params.getOrDefault("udf5", "");
// Construct hash string with exact parameter sequence
String hashString = key + "|" + txnid + "|" + amount + "|" + productinfo + "|" +
firstname + "|" + email + "|" + udf1 + "|" + udf2 + "|" +
udf3 + "|" + udf4 + "|" + udf5 + "||||||" + salt;
return sha512(hashString);
}
private static String sha512(String input) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-512");
byte[] hashBytes = md.digest(input.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : hashBytes) {
sb.append(String.format("%02x", b));
}
return sb.toString().toLowerCase();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
// Example usage with parameters map
Map<String, String> params = new HashMap<>();
params.put("key", "yourKey");
params.put("txnid", "yourTxnId");
params.put("amount", "yourAmount");
params.put("productinfo", "yourProductInfo");
params.put("firstname", "yourFirstName");
params.put("email", "yourEmail");
params.put("udf1", "optional_value1");
// udf2, udf3, udf4, udf5 not provided - will be empty strings
String salt = "yourSalt";
String hash = generateHash(params, salt);
System.out.println("Generated Hash: " + hash);
}
}
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
public class ImprovedHashGenerator
{
public static string GenerateHash(Dictionary<string, string> parameters, string salt)
{
// Extract parameters or use empty string if not provided
string key = parameters["key"];
string txnid = parameters["txnid"];
string amount = parameters["amount"];
string productinfo = parameters["productinfo"];
string firstname = parameters["firstname"];
string email = parameters["email"];
// Get UDF values if present, otherwise use empty string
string udf1 = parameters.ContainsKey("udf1") ? parameters["udf1"] : "";
string udf2 = parameters.ContainsKey("udf2") ? parameters["udf2"] : "";
string udf3 = parameters.ContainsKey("udf3") ? parameters["udf3"] : "";
string udf4 = parameters.ContainsKey("udf4") ? parameters["udf4"] : "";
string udf5 = parameters.ContainsKey("udf5") ? parameters["udf5"] : "";
// Construct hash string with exact parameter sequence
string hashString = $"{key}|{txnid}|{amount}|{productinfo}|{firstname}|{email}|{udf1}|{udf2}|{udf3}|{udf4}|{udf5}||||||{salt}";
return Sha512(hashString);
}
private static string Sha512(string input)
{
using (SHA512 sha512 = SHA512.Create())
{
byte[] bytes = sha512.ComputeHash(Encoding.UTF8.GetBytes(input));
StringBuilder sb = new StringBuilder();
foreach (byte b in bytes)
{
sb.Append(b.ToString("x2"));
}
return sb.ToString().ToLower();
}
}
public static void Main(string[] args)
{
// Example usage with parameters dictionary
Dictionary<string, string> parameters = new Dictionary<string, string>
{
["key"] = "yourKey",
["txnid"] = "yourTxnId",
["amount"] = "yourAmount",
["productinfo"] = "yourProductInfo",
["firstname"] = "yourFirstName",
["email"] = "yourEmail",
["udf1"] = "optional_value1"
// udf2, udf3, udf4, udf5 not provided - will be empty strings
};
string salt = "yourSalt";
string hash = GenerateHash(parameters, salt);
Console.WriteLine("Generated Hash: " + hash);
}
}import hashlib
def generate_hash(params, salt):
# Extract parameters or use empty string if not provided
key = params['key']
txnid = params['txnid']
amount = params['amount']
productinfo = params['productinfo']
firstname = params['firstname']
email = params['email']
udf1 = params.get('udf1', '')
udf2 = params.get('udf2', '')
udf3 = params.get('udf3', '')
udf4 = params.get('udf4', '')
udf5 = params.get('udf5', '')
# Construct hash string with exact parameter sequence
hash_string = f"{key}|{txnid}|{amount}|{productinfo}|{firstname}|{email}|{udf1}|{udf2}|{udf3}|{udf4}|{udf5}||||||{salt}"
# Generate SHA-512 hash
return hashlib.sha512(hash_string.encode('utf-8')).hexdigest()
# Example usage
params = {
'key': 'yourKey',
'txnid': 'yourTxnId',
'amount': 'yourAmount',
'productinfo': 'yourProductInfo',
'firstname': 'yourFirstName',
'email': 'yourEmail',
'udf1': 'optional_value1'
# udf2, udf3, udf4, udf5 not provided - will default to empty strings
}
salt = 'yourSalt'
hash_value = generate_hash(params, salt)
print("Generated Hash:", hash_value)
const crypto = require('crypto');
function generateHash(params, salt) {
// Extract parameters or use empty string if not provided
const key = params.key;
const txnid = params.txnid;
const amount = params.amount;
const productinfo = params.productinfo;
const firstname = params.firstname;
const email = params.email;
const udf1 = params.udf1 || '';
const udf2 = params.udf2 || '';
const udf3 = params.udf3 || '';
const udf4 = params.udf4 || '';
const udf5 = params.udf5 || '';
// Construct hash string with exact parameter sequence
const hashString = `${key}|${txnid}|${amount}|${productinfo}|${firstname}|${email}|${udf1}|${udf2}|${udf3}|${udf4}|${udf5}||||||${salt}`;
// Generate SHA-512 hash
return crypto.createHash('sha512').update(hashString).digest('hex');
}
// Example usage
const params = {
key: 'yourKey',
txnid: 'yourTxnId',
amount: 'yourAmount',
productinfo: 'yourProductInfo',
firstname: 'yourFirstName',
email: 'yourEmail',
udf1: 'optional_value1'
// udf2, udf3, udf4, udf5 not provided - will default to empty strings
};
const salt = 'yourSalt';
const hash = generateHash(params, salt);
console.log("Generated Hash:", hash);
Sample Request
curl -i 'https://test.payu.in/_payment' \
-H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
-H 'content-type: application/x-www-form-urlencoded' \
--data-urlencode 'key=KOEfPI' \
--data-urlencode 'txnid=7f41f520f71b' \
--data-urlencode 'amount=50000' \
--data-urlencode 'productinfo=Mutual Fund' \
--data-urlencode 'firstname=John' \
--data-urlencode '[email protected]' \
--data-urlencode 'phone=9876543210' \
--data-urlencode 'pg=NB' \
--data-urlencode 'bankcode=AXIB' \
--data-urlencode 'surl=https://apiplayground-response.herokuapp.com/' \
--data-urlencode 'furl=https://apiplayground-response.herokuapp.com/' \
--data-urlencode 'api_version=21' \
--data-urlencode 'hash=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0' \
--data-urlencode 'more_info={"wtParams":[{"type":"mutual_fund","plan":"GD","amount":"50000","option":"G","scheme":"LT","receipt":"77407","mf_member_id":"123445","mf_user_id":"77407","mf_partner":"cams","mf_investment_type":"L","mf_amc_code":"UTB"}]}'Step 2: Check Response from PayU
Success Response
{
"status": 1,
"message": "Transaction Processed successfully",
"details": {
"transactionid": "48101c0c-5265-4c2a-b6d0-e6e73d42809e",
"authpayuid": "999990000005920",
"amount": "50000.00",
"txnid": "7f41f520f71b",
"status": "success",
"firstname": "John",
"email": "[email protected]",
"phone": "9876543210",
"productinfo": "Mutual Fund",
"hash": "reverse_hash_value",
"key": "KOEfPI"
}
}Failure Response
{
"status": 0,
"message": "Invalid Parameter: mf_partner must be less than or equal to 4 characters."
}Response Parameters
| Parameter | Description |
|---|---|
| status | 1 for success, 0 for failure |
| message | Transaction status message |
| transactionid | PayU transaction ID |
| authpayuid | PayU authorization ID |
| amount | Transaction amount |
| txnid | Merchant transaction ID |
| hash | Response hash for verification |
Hash Verification
Verify response using reverse hash calculation:
sha512(SALT|status||||||udf5|udf4|udf3|udf2|udf1|email|firstname|productinfo|amount|txnid|key)Step 3: Verify the Payment
Upon receiving the response, we recommend 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 6 days ago
