Skip to main content
POST/payout/v1/initiate

Initiate 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

AttributeDetails
MethodPOST
URLhttps://merchant.paywize.in/api/payout/v1/initiate
AuthenticationBearer token required
Content-Typeapplication/json
EncryptionAES-256-CBC required
Rate Limit100 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)

FieldRequiredTypeDescription
sender_idYesStringUnique ID for each merchant (Max 36 characters)
wallet_idYesStringUnique ID for each merchant. Example: PAYWIZE12345679 / 8109039352
amountYesNumberThe amount in rupees. Provide up to two decimals for paise. Example: 5.00
payment_modeYesStringThe payment mode. Accepted values: IMPS, NEFT and RTGS
beneficiary_nameYesStringThe Name of the beneficiary. Max 40 characters long. Example: John Doe
beneficiary_ifscYesStringThe IFSC code of the beneficiary. Must be 11 characters long. Example: SBIN0000300
beneficiary_acc_numberYesStringThe account number of the beneficiary. Example: 00001234567890
remarksYesStringThe remarks for the payout. Example: vendor (maximum 10 characters)
callback_urlYesStringWebhook 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

FieldTypeDescription
transaction_idStringPaywize generated unique transaction ID
sender_idStringMerchant provided unique sender ID
wallet_idStringMerchant wallet ID
amountStringTransfer amount
payment_modeStringPayment mode used (IMPS, NEFT, RTGS)
remarksStringTransfer remarks/description
statusStringCurrent transaction status (INITIATED, PROCESSING, SUCCESS, FAILED, REFUNDED)
status_messageStringDescriptive message about the current status
beneficiaryObjectBeneficiary information object
beneficiary.beneficiary_nameStringBeneficiary account holder name
beneficiary.beneficiary_acc_numberStringBeneficiary account number
beneficiary.beneficiary_ifscStringBeneficiary bank IFSC code
timestampsObjectTransaction timestamp information
timestamps.created_atStringTransaction creation timestamp (ISO 8601 format)
timestamps.updated_atStringLast update timestamp (ISO 8601 format)

Error Responses

Success Response

CodeMessage
2000Payout request created successfully

Client Error Responses

CodeMessageDescription
4000Bad Request, Please provide payload in the requestMissing payload in request body
4000Insufficient Balance in the walletWallet balance is insufficient for this transaction
4024RTGS payment mode is not supported for this wallet_id. Please choose a valid payment methodRTGS Service not enabled
4025RTGS transactions can only be processed for amounts of ₹2,00,000Minimun supported amount for RTGS is ₹2,00,000
CodeMessageDescription
4001Unauthorized - Invalid or expired tokenJWT token is invalid, expired, or missing
CodeMessageDescription
4003No commercial configuration found for this merchant/payment modePayment mode not configured for merchant
4003Transaction limit exceeded. Please try with a lower amountAmount exceeds daily/transaction limits
CodeMessageDescription
4023Missing or Invalid Wallet IDProvided wallet_id is invalid or not found
CodeMessageField
4002The amount is requiredamount
4002payment mode is requiredpayment_mode
4002The wallet id is requiredwallet_id
4002The beneficiary ifsc is requiredbeneficiary_ifsc
4002The beneficiary account number is requiredbeneficiary_acc_number
4002The beneficiary name is requiredbeneficiary_name
4002The remarks must be a stringremarks
4002The sender ID must be a stringsender_id
4002The sender ID must not exceed 38 characterssender_id
4002Invalid or Duplicate Sender IDsender_id
4003Transaction amount below the minimum limitamount
4013Daily Limit reachedamount

Server Error Responses

CodeMessageDescription
5000Internal Server ErrorUnexpected server error occurred

Transfer Mode Limits

ModeMin AmountMax AmountProcessing Time
IMPS₹1₹5,00,000Instant
NEFT₹1₹10,00,00030 min - 2 hours
RTGS₹2,00,000₹10,00,00,00030 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

  1. Unique Reference IDs: Always use unique sender_id to avoid duplicates
  2. Amount Format: Use numeric format for amount field
  3. Beneficiary Verification: Verify beneficiary details before initiating payouts
  4. Transfer Mode Selection: Choose appropriate transfer mode based on amount and urgency
  5. Callback URL: Ensure webhook endpoint is accessible and responds within 30 seconds
  6. Error Handling: Implement proper error handling for all response codes
  7. Balance Check: Check wallet balance before initiating large payouts
  8. Rate Limiting: Respect API rate limits and implement exponential backoff

Next Steps