Create and manage payees
Map your recipient records to ZytePe payee identifiers.
Register a recipient
Create payee registers the recipient in your merchant payee vault. The source uses payee and beneficiary for the same integration concept. Preserve your own reference in external_ref and store data.id from the response.
Choose recipient details
Bank-mode payouts use bank_account_no and routing_id; UPI payouts use vpa. The create request uses vpa, while response examples contain vpa_address. Preserve those names instead of normalizing request and response shapes.
Find existing recipients
List payees provides limit and offset query parameters. Match your beneficiary records before creating duplicates; the source disallows registering the same bank account twice for a merchant.
Verify before payout
Follow bank and UPI verification for the intended method. Protect returned account and contact details as personal data; do not expose complete payee lists in a browser or logs.
Request example
Choose Node.js, Python, PHP, Ruby, Java or cURL. Run signed requests on your backend. PHP, Ruby and Java include signing directly. Java requires JDK 17 or newer.
Signing helpers: Node.js · Python. cURL shows the request shape; generate its signature first.
import { signedHeaders } from './signing.mjs';
const path = `/api/v1/payees/external/create`;
const query = '';
const payload = {
"legal_name": "Aditi Traders",
"email_address": "ops@example.com",
"phone_number": "9876543210",
"bank_account_no": "123456789012",
"routing_id": "HDFC0001234",
"bank_name": "HDFC Bank",
"vpa": "aditi.traders@okhdfcbank",
"category": "business",
"external_ref": "BENEFICIARY-42"
};
const body = JSON.stringify(payload);
const headers = signedHeaders({
method: 'POST', path, query, body,
keyId: process.env.ZYTEPE_API_KEY_ID,
secret: process.env.ZYTEPE_API_SECRET,
});
headers['Content-Type'] = 'application/json';
const url = 'https://api.zytepe.com' + path + (query ? '?' + query : '');
const response = await fetch(url, { method: 'POST', headers, body });
if (!response.ok) throw new Error('Request failed: HTTP ' + response.status);
const result = await response.json();
// Store the returned identifiers securely. Do not log customer data.import json, os
from urllib.parse import quote
from urllib.request import Request, urlopen
from zytepe_signing import signed_headers
path = f'/api/v1/payees/external/create'
query = ''
payload = json.loads('''{
"legal_name": "Aditi Traders",
"email_address": "ops@example.com",
"phone_number": "9876543210",
"bank_account_no": "123456789012",
"routing_id": "HDFC0001234",
"bank_name": "HDFC Bank",
"vpa": "aditi.traders@okhdfcbank",
"category": "business",
"external_ref": "BENEFICIARY-42"
}''')
body = json.dumps(payload, separators=(',', ':'), ensure_ascii=False)
headers = signed_headers(
method='POST', path=path, query=query, body=body,
key_id=os.environ['ZYTEPE_API_KEY_ID'],
secret=os.environ['ZYTEPE_API_SECRET'],
)
headers['Content-Type'] = 'application/json'
url = 'https://api.zytepe.com' + path + ('?' + query if query else '')
request = Request(url, method='POST', headers=headers, data=body.encode('utf-8'))
with urlopen(request, timeout=30) as response:
result = json.load(response)
# Store identifiers securely; handle HTTPError/URLError in your application.<?php
// PHP 8+ with the cURL extension. Run on your server.
function envRequired(string $name): string {
$value = getenv($name);
if ($value === false || $value === '') throw new RuntimeException('Set ' . $name);
return $value;
}
$path = '/api/v1/payees/external/create';
$query = '';
$body = <<<'JSON'
{
"legal_name": "Aditi Traders",
"email_address": "ops@example.com",
"phone_number": "9876543210",
"bank_account_no": "123456789012",
"routing_id": "HDFC0001234",
"bank_name": "HDFC Bank",
"vpa": "aditi.traders@okhdfcbank",
"category": "business",
"external_ref": "BENEFICIARY-42"
}
JSON;
$headers = [];
$key = envRequired('ZYTEPE_API_KEY_ID');
$secret = envRequired('ZYTEPE_API_SECRET');
$timestamp = (string) time();
$nonce = bin2hex(random_bytes(16));
$canonical = implode("\n", ['POST', $path, $query, $timestamp, $nonce, hash('sha256', $body)]);
$signature = hash_hmac('sha256', $canonical, $secret);
$headers = ["X-API-KEY-ID: $key", "X-API-TIMESTAMP: $timestamp", "X-API-NONCE: $nonce", "X-API-SIGNATURE: $signature"];
$headers[] = 'Content-Type: application/json';
$url = 'https://api.zytepe.com' . $path . ($query !== '' ? '?' . $query : '');
$ch = curl_init($url);
curl_setopt_array($ch, [CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => $headers,
CURLOPT_TIMEOUT => 30, CURLOPT_POSTFIELDS => $body]);
$response = curl_exec($ch);
if ($response === false) throw new RuntimeException(curl_error($ch));
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) throw new RuntimeException('HTTP ' . $status);
$result = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
// Store returned identifiers securely. Recover uncertain payments before retrying.require 'net/http'
require 'uri'
require 'json'
require 'openssl'
require 'securerandom'
path = '/api/v1/payees/external/create'
query = ''
body = <<~'JSON'.chomp
{
"legal_name": "Aditi Traders",
"email_address": "ops@example.com",
"phone_number": "9876543210",
"bank_account_no": "123456789012",
"routing_id": "HDFC0001234",
"bank_name": "HDFC Bank",
"vpa": "aditi.traders@okhdfcbank",
"category": "business",
"external_ref": "BENEFICIARY-42"
}
JSON
headers = {}
key = ENV.fetch('ZYTEPE_API_KEY_ID')
secret = ENV.fetch('ZYTEPE_API_SECRET')
timestamp = Time.now.to_i.to_s
nonce = SecureRandom.hex(16)
canonical = ['POST', path, query, timestamp, nonce, OpenSSL::Digest::SHA256.hexdigest(body)].join("\n")
signature = OpenSSL::HMAC.hexdigest('SHA256', secret, canonical)
headers = { 'X-API-KEY-ID' => key, 'X-API-TIMESTAMP' => timestamp,
'X-API-NONCE' => nonce, 'X-API-SIGNATURE' => signature }
headers['Content-Type'] = 'application/json'
uri = URI('https://api.zytepe.com' + path + (query.empty? ? '' : '?' + query))
request = Net::HTTP::Post.new(uri, headers)
request.body = body
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true, open_timeout: 10, read_timeout: 30) do |http|
http.request(request)
end
raise 'HTTP ' + response.code unless response.is_a?(Net::HTTPSuccess)
result = JSON.parse(response.body)
# Store returned identifiers securely. Recover uncertain payments before retrying.// Java 17+. Save as ZytePeExample.java and run on your server.
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.security.MessageDigest;
import java.util.HexFormat;
import java.util.UUID;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class ZytePeExample {
private static String env(String name) {
String value = System.getenv(name);
if (value == null || value.isBlank()) throw new IllegalArgumentException("Set " + name);
return value;
}
public static void main(String[] args) throws Exception {
String path = "/api/v1/payees/external/create";
String query = "";
String body = """
{
"legal_name": "Aditi Traders",
"email_address": "ops@example.com",
"phone_number": "9876543210",
"bank_account_no": "123456789012",
"routing_id": "HDFC0001234",
"bank_name": "HDFC Bank",
"vpa": "aditi.traders@okhdfcbank",
"category": "business",
"external_ref": "BENEFICIARY-42"
}
""".stripTrailing();
var request = HttpRequest.newBuilder(URI.create(
"https://api.zytepe.com" + path + (query.isEmpty() ? "" : "?" + query)))
.timeout(Duration.ofSeconds(30));
String key = env("ZYTEPE_API_KEY_ID");
String secret = env("ZYTEPE_API_SECRET");
String timestamp = Long.toString(Instant.now().getEpochSecond());
String nonce = UUID.randomUUID().toString().replace("-", "");
String bodyHash = HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256")
.digest(body.getBytes(StandardCharsets.UTF_8)));
String canonical = String.join("\n", "POST", path, query, timestamp, nonce, bodyHash);
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
String signature = HexFormat.of().formatHex(mac.doFinal(canonical.getBytes(StandardCharsets.UTF_8)));
request.header("X-API-KEY-ID", key).header("X-API-TIMESTAMP", timestamp)
.header("X-API-NONCE", nonce).header("X-API-SIGNATURE", signature);
request.header("Content-Type", "application/json");
request.method("POST", HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8));
var client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
var response = client.send(request.build(), HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
if (response.statusCode() < 200 || response.statusCode() >= 300)
throw new IllegalStateException("HTTP " + response.statusCode());
String result = response.body(); // Parse JSON using your application's JSON library.
// Store identifiers securely. Recover uncertain payments before retrying.
}
}curl --request POST \
--url 'https://api.zytepe.com/api/v1/payees/external/create' \
--header 'X-API-KEY-ID: <key-id>' \
--header 'X-API-TIMESTAMP: <unix-seconds>' \
--header 'X-API-NONCE: <fresh-nonce>' \
--header 'X-API-SIGNATURE: <signature>' \
--header 'Content-Type: application/json' \
--data-binary @request.jsonRequest fields
Optional fields can be omitted. Conditional fields depend on the payment method. Labels reflect the reviewed API schemas and handler checks.
legal_nameRequiredRecipient legal name.
email_addressOptionalRecipient email.
phone_numberOptionalRecipient contact number.
bank_nameOptionalBank display name.
categoryOptionalDefaults to individual.
external_refOptionalYour beneficiary reference.
bank_account_noConditionalRequired for bank-mode payouts; optional when creating a UPI-only payee.
routing_idConditionalRequired with bank details for bank-mode payouts.
vpaConditionalRequired for UPI payouts; optional for bank-only recipients.
Request body
{
"legal_name": "Aditi Traders",
"email_address": "ops@example.com",
"phone_number": "9876543210",
"bank_account_no": "123456789012",
"routing_id": "HDFC0001234",
"bank_name": "HDFC Bank",
"vpa": "aditi.traders@okhdfcbank",
"category": "business",
"external_ref": "BENEFICIARY-42"
}Example response
{
"success": true,
"message": "Payee created.",
"data": {
"id": "d965aa45-1952-4749-aa52-2bed21470ffd",
"legal_name": "Aditi Traders",
"email_address": "ops@example.com",
"phone_number": "9876543210",
"bank_account_no": "123456789012",
"routing_id": "HDFC0001234",
"vpa_address": "aditi.traders@okhdfcbank",
"status": "active",
"compliance_status": "pending",
"created_at": "2026-05-03T10:30:00Z"
}
}