Skip to main content
POST/collection/v1/initiate

Initiate 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

AttributeDetails
MethodPOST
URLhttps://merchant.paywize.in/api/collection/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
senderIdYesStringUnique ID for each merchant (Max 36 characters)
txnTypeYesStringAlways "INTENT"
vpaYesStringMerchant VPA
channelYesString"FINO" or "NSDL"
requestAmountYesStringPayment amount (2 decimals)
callbackUrlYesStringMerchant URL to receive status updates
remarksNoString0-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

FieldDescription
txnIdUnique transaction ID provided by Paywize
intentUrlUPI intent URL for direct payment
paymentUrlWeb payment page URL
statusCurrent transaction status
statusMessageDetailed status description
createdAtTransaction creation timestamp
updatedAtLast update timestamp

Error Responses

Success Response

CodeMessage
2000Payment link generated

Client Error Responses

CodeMessageDescription
4001Invalid request formatRequest data format is incorrect
4003Invalid senderIdSenderId format is incorrect
4004Missing or invalid amount formatAmount is missing or invalid
4005Missing or invalid txnTypetxnType is missing or invalid
4006Missing or invalid Callback URLCallback URL is missing or invalid
4007VPA not RegisteredThe provided VPA is not registered
4010Transaction amount above maximum limitAmount exceeds maximum allowed
4011Transaction amount below minimum limitAmount is below minimum required
4012SenderId already existsDuplicate senderId
4013Daily limit ReachedDaily transaction limit exceeded
4014Decryption failed. Please check the encryptionEncryption/decryption error
4015Commercials are not yet configured and activated or channel/vpa do not matchConfiguration issue
4016No active settlement account foundSettlement account not configured
CodeMessageDescription
4008Unauthorized – invalid or expired tokenJWT token is invalid, expired, or missing

Server Error Responses

CodeMessageDescription
5000Internal Server ErrorUnexpected 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

  1. Unique SenderId: Always use unique senderIds to avoid duplicates
  2. Amount Format: Use string format with 2 decimal places (e.g., "100.50")
  3. Callback URL: Ensure your webhook endpoint is accessible and responds within 30 seconds
  4. Error Handling: Always implement proper error handling for API responses
  5. Token Management: Cache tokens and refresh before expiry
  6. Logging: Log transaction details for debugging but never log sensitive data

Next Steps