POST
/payout/v1/initiateInitiate Payout
Initiate instant payouts via IMPS or NEFT using Paywize API.
Last updated: 2026-02-21
Initiate Payout
Overview
Initiate a payout transaction to transfer money to a beneficiary bank account. Supports IMPS, NEFT, and RTGS transfer modes with real-time status tracking.
Quick Reference
| Attribute | Details |
|---|---|
| Method | POST |
| URL | https://merchant.paywize.in/api/payout/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 |
|---|---|---|---|
| sender_id | Yes | String | Unique ID for each merchant (Max 36 characters) |
| wallet_id | Yes | String | Unique ID for each merchant. Example: PAYWIZE12345679 / 8109039352 |
| amount | Yes | Number | The amount in rupees. Provide up to two decimals for paise. Example: 5.00 |
| payment_mode | Yes | String | The payment mode. Accepted values: IMPS, NEFT and RTGS |
| beneficiary_name | Yes | String | The Name of the beneficiary. Max 40 characters long. Example: John Doe |
| beneficiary_ifsc | Yes | String | The IFSC code of the beneficiary. Must be 11 characters long. Example: SBIN0000300 |
| beneficiary_acc_number | Yes | String | The account number of the beneficiary. Example: 00001234567890 |
| remarks | Yes | String | The remarks for the payout. Example: vendor (maximum 10 characters) |
| callback_url | Yes | String | Webhook URL for status notifications |
Sample Request (Before Encryption)
{
"sender_id": "unique_transaction_id",
"wallet_id": "PAYWIZE12345679",
"payment_mode": "IMPS",
"beneficiary": {
"beneficiary_name": "Jane Doe",
"beneficiary_ifsc": "HDFC0123456",
"beneficiary_acc_number": "123456789012"
},
"amount":"1000.00",
"remarks": "Payment",
"callback_url": "https://your-website.com/webhook/payout"
}
Response
Success Response (200 OK)
{
"resp_code": 2000,
"resp_message": "Payout request created successfully",
"data": "U2FsdGVkX1+XYZ789......encrypted_response_here"
}
Decrypted Response Data
{
"transaction_id": "TXN123456",
"sender_id": "PAYOUT123456",
"wallet_id": "PAYWIZE12345679",
"amount": "100.00",
"payment_mode": "IMPS",
"remarks": "Vendorpay",
"status": "INITIATED",
"status_message": "Payment initiated",
"beneficiary": {
"beneficiary_name": "Jane Doe",
"beneficiary_acc_number": "123456789012",
"beneficiary_ifsc": "HDFC0123456"
},
"timestamps": {
"created_at": "2025-11-05T12:30:15Z",
"updated_at": "2025-11-05T12:30:15Z"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| transaction_id | String | Paywize generated unique transaction ID |
| sender_id | String | Merchant provided unique sender ID |
| wallet_id | String | Merchant wallet ID |
| amount | String | Transfer amount |
| payment_mode | String | Payment mode used (IMPS, NEFT, RTGS) |
| remarks | String | Transfer remarks/description |
| status | String | Current transaction status (INITIATED, PROCESSING, SUCCESS, FAILED, REFUNDED) |
| status_message | String | Descriptive message about the current status |
| beneficiary | Object | Beneficiary information object |
| beneficiary.beneficiary_name | String | Beneficiary account holder name |
| beneficiary.beneficiary_acc_number | String | Beneficiary account number |
| beneficiary.beneficiary_ifsc | String | Beneficiary bank IFSC code |
| timestamps | Object | Transaction timestamp information |
| timestamps.created_at | String | Transaction creation timestamp (ISO 8601 format) |
| timestamps.updated_at | String | Last update timestamp (ISO 8601 format) |
Error Responses
Success Response
| Code | Message |
|---|---|
2000 | Payout request created successfully |
Client Error Responses
| Code | Message | Description |
|---|---|---|
4000 | Bad Request, Please provide payload in the request | Missing payload in request body |
4000 | Insufficient Balance in the wallet | Wallet balance is insufficient for this transaction |
4024 | RTGS payment mode is not supported for this wallet_id. Please choose a valid payment method | RTGS Service not enabled |
4025 | RTGS transactions can only be processed for amounts of ₹2,00,000 | Minimun supported amount for RTGS is ₹2,00,000 |
| Code | Message | Description |
|---|---|---|
4001 | Unauthorized - Invalid or expired token | JWT token is invalid, expired, or missing |
| Code | Message | Description |
|---|---|---|
4003 | No commercial configuration found for this merchant/payment mode | Payment mode not configured for merchant |
4003 | Transaction limit exceeded. Please try with a lower amount | Amount exceeds daily/transaction limits |
| Code | Message | Description |
|---|---|---|
4023 | Missing or Invalid Wallet ID | Provided wallet_id is invalid or not found |
| Code | Message | Field |
|---|---|---|
4002 | The amount is required | amount |
4002 | payment mode is required | payment_mode |
4002 | The wallet id is required | wallet_id |
4002 | The beneficiary ifsc is required | beneficiary_ifsc |
4002 | The beneficiary account number is required | beneficiary_acc_number |
4002 | The beneficiary name is required | beneficiary_name |
4002 | The remarks must be a string | remarks |
4002 | The sender ID must be a string | sender_id |
4002 | The sender ID must not exceed 38 characters | sender_id |
4002 | Invalid or Duplicate Sender ID | sender_id |
4003 | Transaction amount below the minimum limit | amount |
4013 | Daily Limit reached | amount |
Server Error Responses
| Code | Message | Description |
|---|---|---|
5000 | Internal Server Error | Unexpected server error occurred |
Transfer Mode Limits
| Mode | Min Amount | Max Amount | Processing Time |
|---|---|---|---|
| IMPS | ₹1 | ₹5,00,000 | Instant |
| NEFT | ₹1 | ₹10,00,000 | 30 min - 2 hours |
| RTGS | ₹2,00,000 | ₹10,00,00,000 | 30 min - 2 hours |
Implementation Examples
JavaScript
import crypto from 'crypto';
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');
}
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 initiatePayout(token, apiKey, secretKey) {
const payoutData = {
sender_id: "unique_transaction_id",
wallet_id: "PAYWIZE12345679",
payment_mode: "IMPS",
beneficiary_name: "John Doe",
beneficiary_acc_number: "123456789012",
beneficiary_ifsc: "HDFC0001234",
amount: 1000,
remarks: "Payment",
callback_url: "https://your-website.com/webhook/payout"
};
const encryptedPayload = encryptMerchantData(payoutData, apiKey, secretKey);
const response = await fetch('https://merchant.paywize.in/api/payout/v1/initiate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
payload: encryptedPayload
})
});
const result = await response.json();
if (result.resp_code === 2000) {
const decryptedData = decryptMerchantData(result.data, apiKey, secretKey);
return JSON.parse(decryptedData);
} else {
throw new Error(`API Error ${result.resp_code}: ${result.resp_message}`);
}
}
// Usage
try {
const payoutResult = await initiatePayout(jwtToken, apiKey, secretKey);
console.log('Payout initiated:', payoutResult);
console.log('Transaction ID:', payoutResult.transaction_id);
console.log('Sender ID:', payoutResult.sender_id);
} catch (error) {
console.error('Payout initiation failed:', error.message);
}
Python
import requests
import json
from encryption_utils import encrypt_merchant_data, decrypt_merchant_data
def initiate_payout(token, api_key, secret_key):
payout_data = {
"sender_id": "unique_transaction_id",
"wallet_id": "PAYWIZE12345679",
"payment_mode": "IMPS",
"beneficiary": {
"beneficiary_name": "Jane Doe",
"beneficiary_ifsc": "HDFC0123456",
"beneficiary_acc_number": "123456789012"
},
"amount": "1000.00",
"remarks": "Payment",
"callback_url": "https://your-website.com/webhook/payout"
}
encrypted_payload = encrypt_merchant_data(
json.dumps(payout_data),
api_key,
secret_key
)
response = requests.post(
'https://merchant.paywize.in/api/payout/v1/initiate',
headers={
'Content-Type': 'application/json',
'Authorization': f'Bearer {token}'
},
json={'payload': encrypted_payload}
)
result = response.json()
if result['resp_code'] == 2000:
decrypted_data = decrypt_merchant_data(result['data'], api_key, secret_key)
return json.loads(decrypted_data)
else:
raise Exception(f"API Error {result['resp_code']}: {result['resp_message']}")
# Usage
try:
payout_result = initiate_payout(jwt_token, api_key, secret_key)
print('Payout initiated:', payout_result)
print('Transaction ID:', payout_result['transaction_id'])
print('Sender ID:', payout_result['sender_id'])
except Exception as error:
print('Payout initiation failed:', str(error))
PHP
<?php
require_once 'PaywizeEncryption.php';
function initiatePayout($token, $apiKey, $secretKey) {
$payoutData = [
'sender_id' => 'unique_transaction_id',
'wallet_id' => 'PAYWIZE12345679',
'payment_mode' => 'IMPS',
'beneficiary_name' => 'John Doe',
'beneficiary_acc_number' => '123456789012',
'beneficiary_ifsc' => 'HDFC0001234',
'amount' => 1000,
'remarks' => 'Payment',
'callback_url' => 'https://your-website.com/webhook/payout'
];
$encryptedPayload = PaywizeEncryption::encryptMerchantData($payoutData, $apiKey, $secretKey);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://merchant.paywize.in/api/payout/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['resp_code'] == 2000) {
$decryptedData = PaywizeEncryption::decryptMerchantData($result['data'], $apiKey, $secretKey);
return json_decode($decryptedData, true);
} else {
throw new Exception("API Error {$result['resp_code']}: {$result['resp_message']}");
}
}
// Usage
try {
$payoutResult = initiatePayout($jwtToken, $apiKey, $secretKey);
echo "Payout initiated: " . json_encode($payoutResult) . "\n";
echo "Transaction ID: " . $payoutResult['transaction_id'] . "\n";
echo "Status: " . $payoutResult['status'] . "\n";
} catch (Exception $error) {
echo "Payout initiation failed: " . $error->getMessage() . "\n";
}
?>
Best Practices
- Unique Reference IDs: Always use unique sender_id to avoid duplicates
- Amount Format: Use numeric format for amount field
- Beneficiary Verification: Verify beneficiary details before initiating payouts
- Transfer Mode Selection: Choose appropriate transfer mode based on amount and urgency
- Callback URL: Ensure webhook endpoint is accessible and responds within 30 seconds
- Error Handling: Implement proper error handling for all response codes
- Balance Check: Check wallet balance before initiating large payouts
- Rate Limiting: Respect API rate limits and implement exponential backoff