Seamless Wallet Debit Integration
This section describes the step-by-step procedure for the workflow involving checking wallet balance, loading money via Payment Gateway, and initiating seamless debit transactions.
How It Works
The Balance Check, Load & Seamless Debit API workflow enables merchants to:
- Check Wallet Balance: Query the current available balance in a customer's wallet.
- Load Money via PG: Enable customers to add funds to their wallet through Payment Gateway.
- Seamless Debit: Initiate instant debit transactions from the wallet for purchases.
- Unified Experience: Provide a complete wallet management solution in a single integration.
This workflow is ideal for merchants who want to offer a comprehensive wallet experience with balance inquiry, top-up functionality, and instant payment capabilities.
Step 1: Check Wallet Balance
Before any wallet operation, check the current balance using the Retrieve Customer Record API.
- API Endpoint (Test):
https://apitest.payu.in/loyalty-points/v1/wallet/retrieveCustRecord - Method:
POST
Request Headers
Header authentication parameters
This API uses HMAC-SHA512 authentication on the header.
| Parameter | Description |
|---|---|
|
walletIdentifier mandatory |
String Program Type (e.g., CLW)
|
|
date mandatory |
String GMT formatted date (e.g., Thu, 17 Feb 2022 08:17:59 GMT)
|
|
Authorization mandatory |
String HMAC-SHA512-based authentication token
|
|
Content-Type mandatory |
String application/json
|
If you do not post the authentication, you will get error in response. For the list of error codes, refer to Status Codes
hmac authentication logic
hmac username="smsplus", algorithm="sha512", headers="date", signature="7ff938849aa79265a3de63fe241dfecb1c680f58c6d11e9f9ca08512afea374705eb9f8995ef6c4584e16eca2e1dc688262bb0937a36cc0f75ec22a9eea33523"Where, the fields in this example are:
- username: The merchant key of the merchant.
- algorithm: This must have the value as hmac-sha512 that is used for this API.
- headers: This must have the value as date digest.
- signature: This must contain the hmacsha512 of (signing_string, merchant_secret), where:
- signing_string: It must be in the "date: {dateValue}"format. Here, the dateValue is the same values in the fields listed in this table For example, "date: Thu, 17 Feb 2022 08:17:59 GMT"
- merchant_secret: The merchant Salt of the merchant. For more information on getting the merchant Salt, refer to Generate Merchant Key and Salt.
Request Body Parameters
| Parameter | Description | Example |
|---|---|---|
messageCode mandatory |
Integer - Numeric identifier for the API |
1930 |
clientTxnId mandatory |
String - Unique transaction ID |
BALANCE_CHK_001 |
requestDateTime mandatory |
String - Local timestamp in YYYYMMDDHHMMSS format |
20230822183015 |
customerMobile optional |
String - Customer mobile with country code (at least one customer identifier is required) |
919876543210 |
customerId optional |
String - Unique customer identifier (at least one customer identifier is required) |
CUST_001 |
emailId optional |
String - Customer email address (at least one customer identifier is required) |
[email protected] |
urn optional |
String - Unique wallet reference number (at least one customer identifier is required) |
12345678901 |
Sample Request
curl -X POST \
https://apitest.payu.in/loyalty-points/v1/wallet/retrieveCustRecord \
-H 'walletIdentifier: CLW' \
-H 'date: Thu, 17 Feb 2022 08:17:59 GMT' \
-H 'Authorization: HMAC <your_hmac_token>' \
-H 'Content-Type: application/json' \
-d '{
"messageCode": 1930,
"clientTxnId": "BALANCE_CHK_001",
"requestDateTime": "20230822183015",
"customerMobile": "919876543210"
}'import requests
import json
from datetime import datetime
url = "https://apitest.payu.in/loyalty-points/v1/wallet/retrieveCustRecord"
# Generate date header in RFC 1123 format
date_header = datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
headers = {
"walletIdentifier": "CLW",
"date": date_header,
"Authorization": "HMAC <your_hmac_token>",
"Content-Type": "application/json"
}
payload = {
"messageCode": 1930,
"clientTxnId": "BALANCE_CHK_001",
"requestDateTime": "20230822183015",
"customerMobile": "919876543210"
}
response = requests.post(url, headers=headers, json=payload)
print("Status Code:", response.status_code)
print("Response:", response.json())import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class ClosedLoopWalletRetrieveCustomer {
public static void main(String[] args) throws IOException, InterruptedException {
String url = "https://apitest.payu.in/loyalty-points/v1/wallet/retrieveCustRecord";
// Generate date header in RFC 1123 format
String dateHeader = DateTimeFormatter
.ofPattern("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.ENGLISH)
.format(ZonedDateTime.now());
String jsonPayload = """
{
"messageCode": 1930,
"clientTxnId": "BALANCE_CHK_001",
"requestDateTime": "20230822183015",
"customerMobile": "919876543210"
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("walletIdentifier", "CLW")
.header("date", dateHeader)
.header("Authorization", "HMAC <your_hmac_token>")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status Code: " + response.statusCode());
System.out.println("Response: " + response.body());
}
}<?php
$url = "https://apitest.payu.in/loyalty-points/v1/wallet/retrieveCustRecord";
// Generate date header in RFC 1123 format
$dateHeader = gmdate('D, d M Y H:i:s') . ' GMT';
$payload = array(
'messageCode' => 1930,
'clientTxnId' => 'BALANCE_CHK_001',
'requestDateTime' => '20230822183015',
'customerMobile' => '919876543210'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'walletIdentifier: CLW',
'date: ' . $dateHeader,
'Authorization: HMAC <your_hmac_token>',
'Content-Type: application/json'
));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo "Status Code: " . $httpCode . "\n";
echo "Response: " . $response . "\n";
$jsonResponse = json_decode($response, true);
print_r($jsonResponse);
?>#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;
use JSON;
use POSIX qw(strftime);
my $url = "https://apitest.payu.in/loyalty-points/v1/wallet/retrieveCustRecord";
# Generate date header in RFC 1123 format
my $date_header = strftime("%a, %d %b %Y %H:%M:%S GMT", gmtime());
my $payload = {
messageCode => 1930,
clientTxnId => "BALANCE_CHK_001",
requestDateTime => "20230822183015",
customerMobile => "919876543210"
};
my $json_payload = encode_json($payload);
my $ua = LWP::UserAgent->new;
$ua->timeout(30);
my $req = HTTP::Request->new('POST', $url);
$req->header('walletIdentifier' => 'CLW');
$req->header('date' => $date_header);
$req->header('Authorization' => 'HMAC <your_hmac_token>');
$req->header('Content-Type' => 'application/json');
$req->content($json_payload);
my $response = $ua->request($req);
if ($response->is_success) {
print "Status Code: " . $response->code . "\n";
print "Response: " . $response->decoded_content . "\n";
my $json_response = decode_json($response->decoded_content);
use Data::Dumper;
print Dumper($json_response);
} else {
print "Error: " . $response->status_line . "\n";
print "Response: " . $response->decoded_content . "\n";
}Sample Response - Success
{
"responseCode": "0000",
"responseMessage": "SUCCESS",
"customerRecord": {
"customerId": "CUST_001",
"availableBalance": "1500.00",
"walletStatus": "ACTIVE",
"urn": "12345678901",
"customerMobile": "919876543210"
}
}📘 Note: Store the available balance to determine if additional funds need to be loaded before making a purchase.
Step 2: Load Money to Wallet (if required)
If the wallet balance is insufficient, initiate a PG Load transaction to enable the customer to add funds.
- API Endpoint (Test):
https://apitest.payu.in/loyalty-points/ppi/payment/pg-load/v1 - Method:
PATCH
Request Headers
This API uses HMAC-SHA512 authentication on the header.
| Parameter | Description |
|---|---|
|
walletIdentifier mandatory |
String Program Type (e.g., CLW)
|
|
date mandatory |
String GMT formatted date (e.g., Thu, 17 Feb 2022 08:17:59 GMT)
|
|
Authorization mandatory |
String HMAC-SHA512-based authentication token
|
|
Content-Type mandatory |
String application/json
|
Request Body Parameters
| Parameter | Description | Example |
|---|---|---|
clientTxnId mandatory |
String - Unique transaction ID (alphanumeric, max 14 characters) |
Reload_V3_1234 |
requestDateTime mandatory |
String - Timestamp in YYYYMMDDHHMMSS format |
20230822183015 |
customerId optional |
String - Unique customer ID (auto-generated if not passed) |
89342546 |
customerMobile mandatory |
String - Customer mobile with country code |
919876543210 |
loadAmount mandatory |
String - Amount to be loaded (minimum 1.00) |
500.00 |
emailId optional |
String - Customer email address |
[email protected] |
firstName optional |
String - Customer first name |
John |
lastName optional |
String - Customer last name |
Doe |
successUrl mandatory |
String - URL for successful transaction redirect |
https://merchant.com/success |
failureUrl mandatory |
String - URL for failed transaction redirect |
https://merchant.com/failure |
Sample Request
curl -X PATCH \
https://apitest.payu.in/loyalty-points/ppi/payment/pg-load/v1 \
-H 'walletIdentifier: CLW' \
-H 'date: Wed, 12 Jun 2024 08:53:43 GMT' \
-H 'Authorization: HMAC <your_hmac_token>' \
-H 'Content-Type: application/json' \
-d '{
"clientTxnId": "Reload_V3_1234",
"requestDateTime": "20230822183015",
"customerMobile": "919876543210",
"loadAmount": "500.00",
"emailId": "[email protected]",
"firstName": "John",
"lastName": "Doe",
"successUrl": "https://merchant.com/success",
"failureUrl": "https://merchant.com/failure"
}'Sample Response - Success
{
"responseCode": "0000",
"responseMessage": "SUCCESS",
"paymentUrl": "https://test.payu.in/_payment",
"txnId": "TXN123456789",
"customerId": "89342546",
"urn": "12345678901"
}Step 3: Check PG Load Status
Use the PG Load Enquiry API to verify the status of the load transaction.
- API Endpoint (Test):
https://apitest.payu.in/loyalty-points/ppi/payment/pg-load-enquiry/v1 - Method:
POST
Request Headers
| Parameter | Description | Example |
|---|---|---|
walletIdentifier mandatory |
String - Program type |
CLW |
date mandatory |
String - GMT-formatted date |
Wed, 12 Jun 2024 08:53:43 GMT |
Authorization mandatory |
String - HMAC-SHA512-based authentication token |
HMAC token |
Content-Type mandatory |
String - Request content type |
application/json |
Request Body Parameters
| Parameter | Description | Example |
|---|---|---|
clientTxnId mandatory |
String - Original transaction ID from PG Load request |
Reload_V3_1234 |
requestDateTime mandatory |
String - Timestamp in YYYYMMDDHHMMSS format |
20230822183015 |
Step 4: Collect Payment - Seamless Debit Transaction
Once sufficient balance is available, initiate a seamless debit transaction using the Collect Payment API.
- API Endpoint (Test):
https://test.payu.in/_payment - API Endpoint (Production):
https://secure.payu.in/_payment - Method:
POST
Request Headers
| Parameter | Description | Example |
|---|---|---|
Content-Type mandatory |
String - Request content type |
application/x-www-form-urlencoded |
Request Body Parameters
The request body contains an encrypted parameter encdata which includes all the transaction details.
Encrypted Parameter
| Parameter | Description | Example |
|---|---|---|
encdata mandatory |
String - Encrypted request body containing all transaction parameters |
h/0YSUd9jKOQ8+2Dc3Phr4s7vxyz123... |
Decrypted Parameters (inside encdata)
| Parameter | Description | Example |
|---|---|---|
txnId mandatory |
String - Unique transaction ID generated by merchant (max 25 characters) |
56882 |
key mandatory |
String - Merchant key provided by PayU (max 50 characters) |
KPQwN8 |
productinfo mandatory |
String - Brief product description (max 100 characters) |
iPhone |
Customer_id optional |
String - Unique customer ID (max 50 characters, alternative to walleturn) |
89342546 |
walleturn optional |
String - Wallet URN from balance check (11 digits, alternative to Customer_id) |
70000000008 |
firstName mandatory |
String - Customer first name (max 60 characters) |
Sourav |
lastName optional |
String - Customer last name (max 60 characters) |
Mishra |
phone mandatory |
String - Customer phone with ISD code (max 15 digits) |
919988776655 |
email mandatory |
String - Customer email address (max 50 characters) |
[email protected] |
ws_online_response mandatory |
String - Success URL for transaction response (max 255 characters) |
https://success.url.com |
ws_failure_response mandatory |
String - Failure URL for transaction response (max 255 characters) |
https://failure.url.com |
amount mandatory |
String - Amount in paise (₹4.10 = 410) |
4100 |
pg mandatory |
String - Payment gateway type for closed-loop wallet |
CLW |
txn_s2s_flow mandatory |
String - Constant value for seamless debit |
4 |
bankcode mandatory |
String - Merchant-specific bank code |
PAY |
hash mandatory |
String - SHA512 hash for request verification |
6e640b... |
Note: Either
Customer_idorwalleturnmust be provided to identify the customer wallet.
Sample Request
curl -X POST \
https://test.payu.in/_payment \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'encdata=h/0YSUd9jKOQ8+2Dc3Phr4s7vxyz123...'Decrypted Request Body:
txnId=56882&key=KPQwN8&productinfo=iPhone&Customer_id=89342546&firstName=Sourav&lastName=Mishra&phone=919988776655&[email protected]&ws_online_response=https://success.url.com&ws_failure_response=https://failure.url.com&amount=4100&pg=CLW&txn_s2s_flow=4&bankcode=PAY&hash=6e640b...Sample Response
Success scenario
{
"mihpayid": "1735903830180094",
"mode": "CLW",
"status": "success",
"key": "KPQwN8",
"txnid": "56882",
"amount": "41.00",
"productinfo": "iPhone",
"firstname": "Sourav",
"lastname": "Mishra",
"email": "[email protected]",
"phone": "919988776655",
"hash": "abc123def456...",
"PG_TYPE": "CLW",
"bank_ref_num": "123456789"
}Failure sceanario
{
"mihpayid": "1735903830180095",
"mode": "CLW",
"status": "failure",
"key": "KPQwN8",
"txnid": "56883",
"amount": "41.00",
"productinfo": "iPhone",
"firstname": "Sourav",
"lastname": "Mishra",
"email": "[email protected]",
"phone": "919988776655",
"hash": "xyz789abc123...",
"PG_TYPE": "CLW",
"error": "Insufficient balance",
"error_Message": "Wallet balance is insufficient for this transaction"
}Updated 18 days ago
