Testing and Troubleshooting Partner Integration
This guide provides comprehensive testing procedures, common error resolutions, debugging techniques, and test data for all Partner Payments integration methods: Hosted Checkout, UPI Intent, and UPI TPV.
Testing Overview by Integration Method
Before diving into specific tests, understand which testing steps apply to your integration:
| Test Category | Hosted Checkout | UPI Intent | UPI TPV |
|---|---|---|---|
| OAuth Token Generation | ✅ | ✅ | ✅ |
| Hash Generation | ✅ | ✅ | ✅ (beneficiarydetail excluded) |
| S2S Flow Parameters | ❌ | ✅ (mandatory) | ✅ (mandatory) |
| Beneficiary Validation | ❌ | ❌ | ✅ (mandatory) |
| Redirect URL Handling | ✅ (surl/furl/curl) | ⚠️ (optional) | ⚠️ (optional) |
| intentURIData Validation | ❌ | ✅ | ✅ |
| Webhook Verification | ✅ | ✅ | ✅ (bankcode=INTTPV) |
| Payment Verification API | ✅ | ✅ | ✅ |
Step 1: Pre-Integration Validation
1.1 Verify OAuth Credentials
Test: Generate access token using the 3-step flow as in Get Access Token - Partner Integration
Expected Result:
-
Received the auth_code on the redirect URI
-
Validate this auth_code using the Validate Auth Code and Client API.
You will receive an accesss_token.
-
Use the access token in the Partner Payment APIs.
Validation Checklist:
- All three OAuth steps complete successfully
- Final access token contains all required scopes
- Token expiry time (
expires_in) is typically 3600 seconds - Token is cached and reused until expiry
Common Failures: See Error: Auth token is not valid below
Step 2: Test Each Integration Method
2.1 Hosted Checkout Testing
2.1.1: Initiate Hosted Checkout Payment
Endpoint: POST https://test-partnerapilayer.payu.in/payment
Test Payload:
{
"merchant_id": "8739528",
"reseller_id": "your-partner-uuid",
"txnid": "HC_TEST_001",
"amount": "100.00",
"productinfo": "Test Product",
"firstname": "Test",
"email": "[email protected]",
"phone": "9876543210",
"surl": "https://yoursite.com/success",
"furl": "https://yoursite.com/failure",
"curl": "https://yoursite.com/cancel",
"hash": "<computed_hash>"
}Expected Response:
{
"status": "success",
"redirectUri": "https://test.payu.in/checkout?token=abc123xyz...",
"txnid": "HC_TEST_001"
}Validation Checklist:
- API returns
200 OKstatus - Response contains
redirectUri -
txnidin response matches request - No
errorormessagefields in response
2.1.2: Complete Payment on Hosted Page
Test Steps:
- Open the
redirectUriin a browser - Hosted checkout page loads with merchant branding
- Select payment method (Card / UPI / Net Banking / Wallet)
For Card Payment (Test Cards):
| Card Number | Expiry | CVV | Name | Expected Result |
|---|---|---|---|---|
| 5123456789012346 | 05/2026 | 123 | Test User | Success |
| 4012001037141112 | 12/2025 | 123 | Test User | Success |
| 6011111111111117 | 06/2027 | 999 | Test User | Failure |
For UPI Payment (Test UPI IDs):
success@payu— Successfailure@payu— Failure
Validation Checklist:
- Hosted page displays correctly
- Payment method selection works
- Test payment completes
- Customer is redirected to
surl(success) orfurl(failure)
2.1.3: Verify Redirect URL Parameters
When customer is redirected to your surl/furl, PayU appends transaction details as POST parameters.
Expected Parameters:
mihpayid=<PayU_Transaction_ID>
txnid=HC_TEST_001
status=success
amount=100.00
productinfo=Test Product
firstname=Test
[email protected]
hash=<response_hash>
...
Validation Checklist:
- All expected parameters are present
-
txnidmatches original request -
mihpayid(PayU transaction ID) is present -
statusissuccessorfailure - Response hash verification passes (see Webhook Hash Verification)
2.2 UPI Intent Testing
2.2.1: Initiate UPI Intent Payment
Endpoint: POST https://test-partnerapilayer.payu.in/payment
Test Payload:
{
"merchant_id": "8739528",
"reseller_id": "your-partner-uuid",
"txnid": "UPI_INTENT_001",
"amount": "250.00",
"productinfo": "UPI Test",
"firstname": "Customer",
"email": "[email protected]",
"phone": "9123456789",
"txn_s2s_flow": "4",
"s2s_client_ip": "192.168.1.100",
"s2s_device_info": "Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36",
"hash": "<computed_hash>"
}Expected Response:
{
"status": "success",
"txnid": "UPI_INTENT_001",
"intentURIData": "upi://pay?pa=payu@icici&pn=PayU&tr=UPI_INTENT_001&am=250.00&cu=INR&tn=Payment..."
}Validation Checklist:
- API returns
200 OKstatus - Response contains
intentURIData -
intentURIDatastarts withupi://pay? - Transaction amount and ID are present in URI
- No error messages in response
2.2.2: Invoke UPI App
Test Steps (Android/iOS):
-
Parse intentURIData: Extract the UPI deep link from API response
-
Launch UPI App:
- Android: Use
IntentwithACTION_VIEWandintentURIDataas URI - iOS: Use
UIApplication.shared.open()with the UPI URI
- Android: Use
-
Select UPI App: System prompts customer to choose UPI app (Google Pay, PhonePe, BHIM, etc.)
-
Authenticate: Customer enters UPI PIN in the app
Test UPI Apps:
- Google Pay (recommended for testing)
- PhonePe
- BHIM UPI
- Paytm
Validation Checklist:
- UPI app opens automatically
- Payment details are pre-filled (amount, merchant name, transaction ID)
- Customer can complete payment
- UPI app shows success/failure message
2.2.3: Simulate Success and Failure Transactions
Success Scenario:
- Use a test UPI account registered with PayU sandbox
- Complete payment with correct UPI PIN
- Expected webhook:
status=success,mode=UPI
Failure Scenario:
- Use an invalid UPI PIN
- OR decline payment in UPI app
- Expected webhook:
status=failure
Validation Checklist:
- Success transaction triggers success webhook
- Failure transaction triggers failure webhook
- Webhook arrives within 5–10 seconds
- Webhook contains correct
txnidandmihpayid
2.3 UPI TPV Testing
2.3.1: Initiate UPI TPV Payment
Endpoint: POST https://test-partnerapilayer.payu.in/payment
Test Payload:
{
"merchant_id": "8739528",
"reseller_id": "your-partner-uuid",
"txnid": "TPV_TEST_001",
"amount": "500.00",
"productinfo": "TPV Payment",
"firstname": "Borrower",
"email": "[email protected]",
"phone": "9988776655",
"txn_s2s_flow": "4",
"s2s_client_ip": "203.0.113.50",
"s2s_device_info": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0)",
"beneficiarydetail": "{\"ifscCode\":\"SBIN0001234\",\"accountNumber\":\"12345678901\",\"accountHolderName\":\"BORROWER NAME\"}",
"hash": "<computed_hash>"
}Expected Response:
{
"status": "success",
"txnid": "TPV_TEST_001",
"intentURIData": "upi://pay?pa=payu@icici&pn=PayU&tr=TPV_TEST_001&am=500.00...",
"bankcode": "INTTPV",
"api_version": "6"
}Validation Checklist:
- Response contains
intentURIData -
bankcodeis automatically set toINTTPV -
api_versionis6 - No errors in response
2.3.2: Test Beneficiary Account Validation
Test Scenarios:
Scenario 1: Matching Account (Success)
- Customer pays from UPI account linked to the beneficiary details provided
- Expected: Payment succeeds, webhook status =
success
Scenario 2: Mismatched Account (Failure)
- Customer pays from a different UPI account (not linked to beneficiary details)
- Expected: Payment rejected, webhook status =
failure
Test Data:
Validation Checklist:
- Matching account completes successfully
- Mismatched account is rejected
- Webhook contains
bankcode=INTTPV - Verify Payment API confirms TPV validation
2.3.3: Verify TPV-Specific Webhook Fields
Expected Webhook Fields (Success):
mihpayid=<PayU_Transaction_ID>
txnid=TPV_TEST_001
status=success
amount=500.00
bankcode=INTTPV
mode=UPI
unmappedstatus=captured
hash=<webhook_hash>
Validation Checklist:
-
bankcodeisINTTPV(confirms TPV flow) -
modeisUPI -
unmappedstatusiscaptured(for success) - All beneficiary validation passed
Step 3: Webhook Testing
3.1 Configure Partner Webhooks
Required Webhook URLs:
partner_webhook_success— Triggered on successful paymentpartner_webhook_failure— Triggered on failed paymentpartner_webhook_cancelled— Triggered when customer cancels payment
Configuration:
Contact PayU support to register your partner webhook URLs. Provide:
- Your
reseller_id(partner UUID) - HTTPS URLs for all three webhook types
- IP whitelist (if required for your firewall)
3.2 Webhook Hash Verification
All webhooks from PayU include a hash parameter for verification.
Reverse Hash Formula:
client_secret|status||||||udf5|udf4|udf3|udf2|udf1|email|firstname|productinfo|amount|txnid|merchant_id
Note: Five pipes after status, then reverse order of request parameters
Verification Steps:
- Extract parameters from webhook POST body
- Compute reverse hash using formula above
- Compare computed hash with webhook
hashparameter - Case-sensitive comparison — hashes must match exactly
Example (Python):
import hashlib
def verify_webhook_hash(webhook_data, client_secret):
hash_string = (
f"{client_secret}|{webhook_data['status']}||||||"
f"{webhook_data.get('udf5', '')}|{webhook_data.get('udf4', '')}|"
f"{webhook_data.get('udf3', '')}|{webhook_data.get('udf2', '')}|"
f"{webhook_data.get('udf1', '')}|{webhook_data['email']}|"
f"{webhook_data['firstname']}|{webhook_data['productinfo']}|"
f"{webhook_data['amount']}|{webhook_data['txnid']}|"
f"{webhook_data['merchant_id']}"
)
computed_hash = hashlib.sha512(hash_string.encode('utf-8')).hexdigest()
return computed_hash == webhook_data['hash']
# Usage
if verify_webhook_hash(webhook_data, client_secret):
# Process webhook
pass
else:
# Reject webhook
passValidation Checklist:
- Webhook arrives within 5–10 seconds of payment
- All expected fields are present (mihpayid, txnid, status, amount, hash)
- Hash verification passes
- Webhook is idempotent (handle duplicate webhooks)
3.3 Webhook Testing Checklist
For Each Integration Method:
| Test Case | Expected Result |
|---|---|
| Successful payment | partner_webhook_success called with status=success |
| Failed payment | partner_webhook_failure called with status=failure |
| Cancelled payment | partner_webhook_cancelled called with status=cancel |
| Hash verification | Computed hash matches webhook hash parameter |
| Duplicate webhook | System handles idempotently (no duplicate processing) |
| Delayed webhook | Webhook retries after timeout (if first attempt fails) |
Step 4: Payment Verification API Testing
4.1 Call Verify Payment API
Endpoint: POST https://test-partnerapilayer.payu.in/verifyPayment
Test Payload:
{
"merchant_id": "8739528",
"txnid": "TPV_TEST_001"
}Expected Response (Success):
{
"status": "success",
"mihpayid": "403993715529111111",
"txnid": "TPV_TEST_001",
"amount": "500.00",
"productinfo": "TPV Payment",
"firstname": "Borrower",
"email": "[email protected]",
"mode": "UPI",
"bankcode": "INTTPV",
"unmappedstatus": "captured",
"payment_source": "payu"
}4.2 Reconcile Webhook vs Verify API
Validation Checklist:
-
mihpayidmatches in both webhook and verify response -
txnidmatches original request -
statusandunmappedstatusare consistent -
amountmatches original request - For TPV:
bankcodeisINTTPV - No discrepancies between webhook and verify API
Reconciliation Logic:
IF webhook.status == verify_api.status
AND webhook.mihpayid == verify_api.mihpayid
AND webhook.amount == verify_api.amount
THEN
Mark transaction as confirmed
ELSE
Flag for manual review
Common Errors and Resolutions
Error: Invalid hash
Error Message:
Could not validate hash
Cause:
The payment request hash computed by your system doesn't match PayU's computed hash.
Resolution:
-
Verify the hash formula:
merchant_id|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5||||||client_secretNote: Six consecutive pipes (
||||||) betweenudf5andclient_secret -
Use client_secret, not salt — Partner Payments API requires
client_secret(from OAuth credentials) -
Check for empty fields — Empty fields should be represented as empty strings between pipes
-
Verify SHA-512 hex output — Ensure your hash is lowercase hexadecimal (128 characters)
-
For UPI TPV: Ensure
beneficiarydetailis NOT included in hash calculation
Debug Example (Java):
String hashString = merchantId + "|" + txnid + "|" + amount + "|" + productinfo + "|" +
firstname + "|" + email + "|" + udf1 + "|" + udf2 + "|" + udf3 + "|" +
udf4 + "|" + udf5 + "||||||" + clientSecret;
System.out.println("Hash String: " + hashString);
// Expected: 8739528|TXN001|518.02|Payment|||||||||||whatsapp||||||YOUR_CLIENT_SECRET
String hash = sha512Hex(hashString);
System.out.println("Computed Hash: " + hash);
System.out.println("Hash Length: " + hash.length()); // Should be 128Error: Auth token is not valid
Error Message:
Auth token is not valid
Cause:
- Access token has expired (default expiry: 3600 seconds)
- Token doesn't have the required scopes
- Token was generated for different environment (UAT vs production)
- Token is missing from the
Authorizationheader
Resolution:
-
Regenerate the token — Complete all three OAuth steps:
- Step 1: Password grant with reseller credentials
- Step 2: Request authorization code for merchant
- Step 3: Exchange code for final access token
-
Verify scopes:
scopes=create_payment_links partner_payment_links partner_payments -
Check header format:
Authorization: Bearer YOUR_ACCESS_TOKEN -
Implement token caching:
import time
class TokenCache:
def __init__(self):
self.access_token = None
self.expiry_time = 0
def get_token(self):
if time.time() >= self.expiry_time:
# Regenerate token
self.access_token = self._generate_new_token()
self.expiry_time = time.time() + 3600 # 1 hour
return self.access_tokenError: Transaction not found
Error Message:
Transaction not found / No data found for given transaction details
Cause:
Transaction has not yet been persisted in PayU's system. This can happen immediately after initiating a payment.
Resolution:
- Wait 2–3 seconds before calling Verify Payment API
- Implement retry logic with exponential backoff
- Verify txnid is correct and matches original request
Retry Logic Example (Python):
import time
import requests
def verify_payment_with_retry(merchant_id, txnid, max_retries=3):
for attempt in range(max_retries):
response = requests.post(
'https://test-partnerapilayer.payu.in/verifyPayment',
json={'merchant_id': merchant_id, 'txnid': txnid}
)
if response.status_code == 200:
data = response.json()
if data.get('status') != 'Transaction not found':
return data
# Exponential backoff: 2s, 4s, 8s
wait_time = 2 ** attempt
time.sleep(wait_time)
raise Exception(f"Transaction {txnid} not found after {max_retries} retries")Error: partner payment webhook not present/enabled
Error Message:
partner payment webhook not present/enabled for given merchant
Cause:
Partner-level webhooks are not configured in PayU's system for your reseller_id.
Resolution:
- Contact PayU Support to configure partner webhooks
- Provide the following:
- Your
reseller_id(partner UUID) - Webhook URLs (success, failure, cancel)
- Whether webhooks should be enabled globally for all your merchants
- Your
Important: Partner webhooks are configured at the partner level (reseller), not individual merchant level.
Error: s2s_client_ip or s2s_device_info is mandatory
Error Message:
s2s_client_ip and s2s_device_info are mandatory when txn_s2s_flow is 4
Cause:
UPI Intent and UPI TPV flows (txn_s2s_flow=4) require customer IP address and device information for security and fraud prevention.
Resolution:
-
Capture customer IP address:
- From HTTP headers:
X-Forwarded-FororREMOTE_ADDR - Send as string in
s2s_client_ipparameter
- From HTTP headers:
-
Capture device user-agent:
- From HTTP header:
User-Agent - Send as string in
s2s_device_infoparameter
- From HTTP header:
Example (Node.js/Express):
app.post('/initiate-payment', (req, res) => {
const clientIp = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
const deviceInfo = req.headers['user-agent'];
const paymentPayload = {
merchant_id: '8739528',
txnid: 'TXN001',
amount: '100.00',
txn_s2s_flow: '4',
s2s_client_ip: clientIp,
s2s_device_info: deviceInfo,
// ... other parameters
};
// Send to PayU API
});Error: Could not validate HMAC header
Error Message:
Could not validate HMAC header signature
Cause:
HMAC signature validation failed for QR/omnichannel payment requests.
Resolution:
-
Verify all required headers are present:
X-Payu-SignatureX-Payu-TimestampX-Payu-Nonce
-
Check timestamp — Must be within ±5 minutes of current server time
-
Confirm signing key — Use the correct HMAC secret provided by PayU
Log Patterns for Debugging
Use these grep patterns to locate relevant log entries:
Hash Validation Failures:
grep -i "hash.*invalid\|could not validate hash" app.logWebhook Send/Receive:
grep -i "webhook.*sent\|partner_webhook" app.logPayment Verification Calls:
grep -i "verifyPayment\|verify.*payment" app.logTransaction Not Found Errors:
grep -i "transaction not found\|no data found" app.logS2S Flow Errors:
grep -i "s2s_client_ip\|s2s_device_info\|txn_s2s_flow" app.logOAuth Token Issues:
grep -i "auth token.*not valid\|token.*expired\|401" app.logTest Data
UAT Credentials
Sample Transaction IDs
Use descriptive, unique transaction IDs for easy tracking:
HC_UAT_20240315_001 (Hosted Checkout)
UPI_INTENT_20240315_001 (UPI Intent)
TPV_UAT_20240315_001 (UPI TPV)
Sample Customer Data
{
"firstname": "TestUser",
"email": "[email protected]",
"phone": "9876543210"
}Sample UDF Values
{
"udf1": "session_12345",
"udf2": "app_android",
"udf3": "v2.1.0",
"udf4": "",
"udf5": ""
}Sample Beneficiary Details (UPI TPV)
{
"ifscCode": "SBIN0001234",
"accountNumber": "12345678901",
"accountHolderName": "TEST ACCOUNT HOLDER"
}End-to-End Integration Checklist
Use this checklist to validate your complete integration before going live:
OAuth Flow
- Step 1: Reseller password grant succeeds
- Step 2: Merchant authorization code obtained
- Step 3: Final access token contains all required scopes
- Token caching and refresh logic implemented
Payment Initiation
- Hash generation follows correct formula
-
client_secretused (not merchant salt) - All mandatory parameters included
- For S2S:
s2s_client_ipands2s_device_infocaptured - For TPV:
beneficiarydetailexcluded from hash
Hosted Checkout (if applicable)
-
redirectUrireturned successfully - Customer redirect to PayU works
- Hosted page loads with correct branding
- Test payments complete successfully
- Customer redirected to
surl/furlbased on outcome
UPI Intent/TPV (if applicable)
-
intentURIDatareturned in response - UPI app launches correctly on mobile device
- Payment details pre-filled in UPI app
- Customer can authenticate and complete payment
- For TPV: Account validation works (success and failure scenarios)
Webhook Handling
- Partner webhooks configured in PayU system
- Webhook URLs are HTTPS and publicly accessible
- Webhook hash verification implemented
- Idempotency handling prevents duplicate processing
- Webhook arrival time acceptable (< 10 seconds)
- For TPV:
bankcode=INTTPVvalidated
Payment Verification
- Verify Payment API called after webhook
- Response reconciled with webhook data
-
mihpayid,txnid,amount,statusmatch - Retry logic handles "transaction not found" errors
- Final payment status persisted in your system
Error Handling
- Hash validation errors logged and debugged
- Token expiry handled with automatic refresh
- Transaction not found errors retry with backoff
- Invalid webhook signatures rejected
- All errors logged with sufficient context
Reconciliation
- Daily reconciliation process in place
- Webhook vs Verify API discrepancies flagged
- Manual review process for failed/stuck transactions
- Settlement reports downloaded from PayU dashboard
Going Live Checklist
Before switching to production:
Credential Updates
- Production
client_idandclient_secretobtained - Production
merchant_idandreseller_idconfigured - Production OAuth endpoints updated in code
- Production API endpoints updated (
https://partnerapilayer.payu.in)
Final Validation
- Conduct live transaction in production (small amount)
- Verify production webhook delivery
- Confirm production Verify Payment API works
- Validate production reconciliation process
- Check production settlement in PayU dashboard
Infrastructure
- Webhook URLs whitelisted on firewall
- SSL certificates valid for all callback URLs
- Load balancing configured (if high volume expected)
- Monitoring and alerting set up for payment failures
Documentation
- API integration document updated
- Runbook created for common errors
- Contact information for PayU support documented
- Escalation process defined for critical issues
Support
For unresolved issues or technical questions, contact PayU Partner Support with:
Required Information:
- Your
reseller_id(partner UUID) - Merchant ID(s) involved
- Integration method (Hosted Checkout / UPI Intent / UPI TPV)
- Detailed error description
- Sample
txnidexhibiting the issue - Timestamp of the transaction
- Full error message and relevant logs
- Steps to reproduce (if applicable)
Support Channels:
- Partner Portal: https://partner.payu.in/support
- Email: [email protected]
- Phone: [Contact information from PayU]
Related Documentation
Updated 26 minutes ago
