POST
/collection/v1/initiateInitiate Payment
Create payment collection requests via UPI or intent.
Last updated: 2026-02-21
Initiate Payment
Overview
Creates a new UPI payment intent for collecting payments from customers. This endpoint generates payment links and UPI intent URLs that can be shared with customers for payment collection.
Quick Reference
| Attribute | Details |
|---|---|
| Method | POST |
| URL | https://merchant.paywize.in/api/collection/v1/initiate/ |
| Authentication | Bearer token required |
| Content-Type | application/json |
| Encryption | AES-256-CBC required |
| Rate Limit | 100 requests/minute |
Endpoint
Authentication Required: Bearer token
Authentication
This endpoint requires a valid JWT Bearer token. Learn how to generate tokens: Authentication Guide →
Request Headers
Content-Type: application/json
Authorization: Bearer <jwt_token>
Request Body
The request body must contain encrypted data using AES-256-CBC encryption:
{
"payload": "0oA+t8GGuDZ0FrEbhM9bZ2pxTDZasdasdasasdjqwuhenqwj^7y="
}
Learn about encryption: Encryption Guide →
Required Fields (Before Encryption)
| Field | Required | Type | Description |
|---|---|---|---|
| senderId | Yes | String | Unique ID for each merchant (Max 36 characters) |
| txnType | Yes | String | Always "INTENT" |
| vpa | Yes | String | Merchant VPA |
| channel | Yes | String | "FINO" or "NSDL" |
| requestAmount | Yes | String | Payment amount (2 decimals) |
| callbackUrl | Yes | String | Merchant URL to receive status updates |
| remarks | No | String | 0-20 alphanumeric characters, no special characters allowed |
Sample Request (Before Encryption)
{
"senderId": "TXN123456",
"txnType": "INTENT",
"vpa": "merchant@paywize",
"channel": "FINO",
"requestAmount": "100.50",
"remarks": "Payment123",
"callbackUrl": "https://webhook.site/c567b1af-f4fe-4729-9211-7e251d80b864"
}
Response
Success Response (200 OK)
{
"respCode": 2000,
"respMessage": "Payment link generated",
"data": "0oA+t8GGuDZ0FrEbhM9bZ2pxTDZTaHRWRW1tQnN0dWUxVC92Yi9WQW9SSFdlTk56Ri9EYmVWTmVGNTF1R3FVSnFRVWJUaFpqbTk4RTZrandTa25keGNJen"
}
Decrypted Response Data
{
"senderId": "SENDERID000345",
"txnId": "CFCE140825000009",
"intentUrl": "upi://pay?pa=merchant.primepe@nsdl&orgid=181046&purpose=00&catagory=&sign=",
"paymentUrl": "https://merchant.paywize.in/api/collection/v1/payment/payment/bede3921eb1df6b6e",
"status": "INITIATED",
"statusMessage": "Payment link has been generated",
"createdAt": "2025-08-16T07:46:45.277Z",
"updatedAt": "2025-08-16T07:46:45.277Z"
}
Response Fields
| Field | Description |
|---|---|
| txnId | Unique transaction ID provided by Paywize |
| intentUrl | UPI intent URL for direct payment |
| paymentUrl | Web payment page URL |
| status | Current transaction status |
| statusMessage | Detailed status description |
| createdAt | Transaction creation timestamp |
| updatedAt | Last update timestamp |
Error Responses
Success Response
| Code | Message |
|---|---|
2000 | Payment link generated |
Client Error Responses
| Code | Message | Description |
|---|---|---|
4001 | Invalid request format | Request data format is incorrect |
4003 | Invalid senderId | SenderId format is incorrect |
4004 | Missing or invalid amount format | Amount is missing or invalid |
4005 | Missing or invalid txnType | txnType is missing or invalid |
4006 | Missing or invalid Callback URL | Callback URL is missing or invalid |
4007 | VPA not Registered | The provided VPA is not registered |
4010 | Transaction amount above maximum limit | Amount exceeds maximum allowed |
4011 | Transaction amount below minimum limit | Amount is below minimum required |
4012 | SenderId already exists | Duplicate senderId |
4013 | Daily limit Reached | Daily transaction limit exceeded |
4014 | Decryption failed. Please check the encryption | Encryption/decryption error |
4015 | Commercials are not yet configured and activated or channel/vpa do not match | Configuration issue |
4016 | No active settlement account found | Settlement account not configured |
| Code | Message | Description |
|---|---|---|
4008 | Unauthorized – invalid or expired token | JWT token is invalid, expired, or missing |
Server Error Responses
| Code | Message | Description |
|---|---|---|
5000 | Internal Server Error | Unexpected server error occurred |
Implementation Examples
JavaScript
import crypto from 'crypto';
// Encryption function
function encryptMerchantData(data, key, iv) {
if (typeof data === 'object') {
data = JSON.stringify(data);
}
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
const encrypted = Buffer.concat([cipher.update(data, 'utf8'), cipher.final()]);
return encrypted.toString('base64');
}
// Decryption function
function decryptMerchantData(data, key, iv) {
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
const decrypted = Buffer.concat([
decipher.update(Buffer.from(data, 'base64')),
decipher.final()
]);
return decrypted.toString('utf8');
}
async function initiatePayment(token, apiKey, secretKey) {
const paymentData = {
senderId: "TXN123456",
txnType: "INTENT",
vpa: "merchant@paywize",
channel: "FINO",
requestAmount: "100.50",
remarks: "Payment123",
callbackUrl: "https://your-webhook-url.com/callback"
};
// Encrypt the payment data
const encryptedPayload = encryptMerchantData(paymentData, apiKey, secretKey);
const response = await fetch('https://merchant.paywize.in/api/collection/v1/initiate/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
payload: encryptedPayload
})
});
const result = await response.json();
if (result.respCode === 2000) {
// Decrypt the response data
const decryptedData = decryptMerchantData(result.data, apiKey, secretKey);
return JSON.parse(decryptedData);
} else {
throw new Error(`API Error ${result.respCode}: ${result.respMessage}`);
}
}
// Usage
try {
const paymentResult = await initiatePayment(jwtToken, apiKey, secretKey);
console.log('Payment initiated:', paymentResult);
console.log('Payment URL:', paymentResult.paymentUrl);
console.log('UPI Intent:', paymentResult.intentUrl);
} catch (error) {
console.error('Payment initiation failed:', error.message);
}
Python
import requests
import json
from encryption_utils import encrypt_merchant_data, decrypt_merchant_data
def initiate_payment(token, api_key, secret_key):
payment_data = {
"senderId": "TXN123456",
"txnType": "INTENT",
"vpa": "merchant@paywize",
"channel": "FINO",
"requestAmount": "100.50",
"remarks": "Payment123",
"callbackUrl": "https://your-webhook-url.com/callback"
}
# Encrypt the payment data
encrypted_payload = encrypt_merchant_data(
json.dumps(payment_data),
api_key,
secret_key
)
response = requests.post(
'https://merchant.paywize.in/api/collection/v1/initiate/',
headers={
'Content-Type': 'application/json',
'Authorization': f'Bearer {token}'
},
json={'payload': encrypted_payload}
)
result = response.json()
if result['respCode'] == 2000:
# Decrypt the response data
decrypted_data = decrypt_merchant_data(result['data'], api_key, secret_key)
return json.loads(decrypted_data)
else:
raise Exception(f"API Error {result['respCode']}: {result['respMessage']}")
# Usage
try:
payment_result = initiate_payment(jwt_token, api_key, secret_key)
print('Payment initiated:', payment_result)
print('Payment URL:', payment_result['paymentUrl'])
print('UPI Intent:', payment_result['intentUrl'])
except Exception as error:
print('Payment initiation failed:', str(error))
PHP
<?php
require_once 'PaywizeEncryption.php';
function initiatePayment($token, $apiKey, $secretKey) {
$paymentData = [
'senderId' => 'TXN123456',
'txnType' => 'INTENT',
'vpa' => 'merchant@paywize',
'channel' => 'FINO',
'requestAmount' => '100.50',
'remarks' => 'Payment123',
'callbackUrl' => 'https://your-webhook-url.com/callback'
];
// Encrypt the payment data
$encryptedPayload = PaywizeEncryption::encryptMerchantData($paymentData, $apiKey, $secretKey);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://merchant.paywize.in/api/collection/v1/initiate/');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['payload' => $encryptedPayload]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $token
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
if ($result['respCode'] == 2000) {
// Decrypt the response data
$decryptedData = PaywizeEncryption::decryptMerchantData($result['data'], $apiKey, $secretKey);
return json_decode($decryptedData, true);
} else {
throw new Exception("API Error {$result['respCode']}: {$result['respMessage']}");
}
}
// Usage
try {
$paymentResult = initiatePayment($jwtToken, $apiKey, $secretKey);
echo "Payment initiated: " . json_encode($paymentResult) . "\n";
echo "Payment URL: " . $paymentResult['paymentUrl'] . "\n";
echo "UPI Intent: " . $paymentResult['intentUrl'] . "\n";
} catch (Exception $error) {
echo "Payment initiation failed: " . $error->getMessage() . "\n";
}
?>
Best Practices
- Unique SenderId: Always use unique senderIds to avoid duplicates
- Amount Format: Use string format with 2 decimal places (e.g., "100.50")
- Callback URL: Ensure your webhook endpoint is accessible and responds within 30 seconds
- Error Handling: Always implement proper error handling for API responses
- Token Management: Cache tokens and refresh before expiry
- Logging: Log transaction details for debugging but never log sensitive data