ReddyPay
साइन इन

REDDYPAY INR API

पूरा मर्चेंट इंटीग्रेशन डॉक्यूमेंटेशन

🇮🇳 भारत (INR) www.reddypay.live v3.0
API v3.0 — लाइव

सभी एंडपॉइंट के तहत लाइव https://www.reddypay.live/api/v3. अनुरोध और जवाब का फ़ॉर्मेट, हस्ताक्षर (mchKey / mchSecret के साथ MD5 UPPERCASE) और कॉलबैक आम v3 गेटवे विनिर्देश के अनुसार हैं, इसलिए base URL, Merchant ID और कुंजियाँ बदलने के बाद मौजूदा v3 इंटीग्रेशन चलता है। हर जवाब में हमारा अपना होस्टेड पेमेंट URL होता है — आपके ग्राहक को कभी प्रोवाइडर के पेज का पता नहीं दिखता।

11%पे-इन शुल्क
6.5% + ₹10पे-आउट शुल्क
RESTJSON POST
MD5अपरकेस साइन

आपके API क्रेडेंशियल

इन्हें सुरक्षित रखें। पे-इन में API Key, पे-आउट में API Secret इस्तेमाल होता है।

Merchant ID (mchId)
YOUR_MERCHANT_ID
API Key (mchKey)पे-इन
YOUR_API_KEY
API Secret (mchSecret)पे-आउट / बैलेंस
YOUR_API_SECRET

उदाहरणों में अपना Merchant ID और keys देखने के लिए साइन इन करें। साइन इन

समर्थित भुगतान विधियां

UPIINRUPI Pay-in: tradeType INRUPI · Pay-out: payType upi
बैंक ट्रांसफ़रIMPS / NEFT Pay-out: payType bank (account number + IFSC)
USDTusdt Pay-in: tradeType usdt (TRC20) · Pay-out: payType usdt

API संदर्भ

सभी एंडपॉइंट

POSThttps://www.reddypay.live/api/v3/payin
mchKey से साइन करें
डिपॉज़िट ऑर्डर बनाएँ
Direct URL (works without URL rewriting): https://www.reddypay.live/api/v3/payin.php
Details and examples
POSThttps://www.reddypay.live/api/v3/check-order-status
mchKey से साइन करें
डिपॉज़िट ऑर्डर देखें
Direct URL (works without URL rewriting): https://www.reddypay.live/api/v3/check-order-status.php
Details and examples
POSThttps://www.reddypay.live/api/v3/payout
mchSecret से साइन करें
निकासी बनाएँ
Direct URL (works without URL rewriting): https://www.reddypay.live/api/v3/payout.php
Details and examples
POSThttps://www.reddypay.live/api/v3/check-order-status
mchSecret से साइन करें
Query a withdrawal
Direct URL (works without URL rewriting): https://www.reddypay.live/api/v3/check-order-status.php
Details and examples
POSThttps://www.reddypay.live/api/v3/check-gateway-balance
mchSecret से साइन करें
बैलेंस जाँचें
Direct URL (works without URL rewriting): https://www.reddypay.live/api/v3/check-gateway-balance.php
Details and examples

ग्लोबल नियम

  • Request method: JSON POST
  • Header: Content-Type: application/json (form-encoded bodies are accepted too)
  • Every request must include mchId (your Merchant ID) and sign
  • Pay-in and Query Pay-in are signed with mchKey (API Key). Pay-out, Query Pay-out and Balance are signed with mchSecret (API Secret)
  • Signature: MD5(sorted_params + &key=KEY).toUpperCase()
  • Amounts are strings with two decimals, e.g. "500.00". Times are ISO-8601 in IST (UTC+05:30)
  • Currency: INR (₹). USDT orders are priced in INR and paid in USDT (TRC20)

क्विक स्टार्ट

  1. ऊपर के बॉक्स से अपना Merchant ID, API Key (mchKey) और API Secret (mchSecret) कॉपी करें।
  2. Basic Information में अपना कॉलबैक URL सहेजें और “Test endpoint” दबाएँ — हम एक हस्ताक्षरित टेस्ट अनुरोध भेजते हैं।
  3. POST /payin से ऑर्डर बनाएँ और अपने ग्राहक को लौटाए गए pay_url पर भेजें।
  4. हमारे कॉलबैक की प्रतीक्षा करें (टेक्स्ट success से जवाब दें) और /check-order-status को विकल्प के रूप में इस्तेमाल करें।

आपकी सीमाएँ

पे-इन राशि₹200.00 – ₹50,000.00
पे-आउट राशि₹500.00 – ₹200,000.00
प्रति दिन पे-आउट₹200,000.00
ऑर्डर की वैधता30 मिनट

स्थिति मान

स्थितिअर्थ
pendingWaiting for the customer. A payment made after expiry is still credited, and you get the success callback.
successPaid and credited to your wallet (netAmount). Final.
failedभुगतान विफल या अस्वीकार कर दिया गया। अंतिम जब तक ग्राहक बाद में भुगतान नहीं करता।
expiredग्राहक ने समय पर भुगतान नहीं किया (डिफ़ॉल्ट रूप से 30 मिनट)।
processingPayouts only: approved, the transfer is being made.

रेट लिमिट और IP अनुमति-सूची

  • प्रति मर्चेंट और IP एड्रेस 120 अनुरोध प्रति मिनट (Retry-After हेडर के साथ HTTP 429)। बार-बार गलत हस्ताक्षर भेजने पर IP एड्रेस कुछ समय के लिए लॉक हो जाता है।
  • अगर आप Basic Information में IP allow-list सहेजते हैं, तो सिर्फ़ वही सर्वर IP API कॉल कर सकते हैं (403 ip_not_allowed)। API से पेआउट केवल allow-list के साथ उपलब्ध हैं।
  • API को हमेशा अपने सर्वर से कॉल करें, कभी ब्राउज़र या ऐप से नहीं: कुंजियाँ गुप्त रहनी चाहिए।

परीक्षण चल रहा है

अलग से कोई सैंडबॉक्स नहीं है। सबसे छोटी अनुमत राशि का असली ऑर्डर बनाकर खुद भुगतान करें, या अपना कॉलबैक URL जाँचने के लिए Basic Information में “Test endpoint” बटन इस्तेमाल करें। हमारे ऑपरेटरों के बनाए टेस्ट पेमेंट मर्चेंट को उपलब्ध नहीं हैं।

चेंजलॉग

वर्ज़नबदलाव
v3.0First release of the v3 API: /payin, /check-order-status, /payout, /check-gateway-balance. USDT (TRC20) pay-in and payout. Our hosted checkout URL in every response. Retrying signed callbacks.
v1.xLegacy payment-link API (/api/v1/create-link.php, /link-status.php) stays available and unchanged; optional currency / trade_type were added.
POSThttps://www.reddypay.live/api/v3/payinmchKey से साइन करें

डिपॉज़िट ऑर्डर बनाता है। जवाब में हमारा होस्टेड चेकआउट पता pay_url में होता है: ग्राहक को वहाँ रीडायरेक्ट करें (या नए टैब / iframe में खोलें)। ग्राहक हमारे डोमेन पर भुगतान करता है; भुगतान पुष्ट होने पर आपको कॉलबैक मिलता है।

ParameterTypeRequiredविवरण
mchIdstringहाँYour Merchant ID (also accepted as merchant_id)
mchOrderNostringहाँYour own unique order number (1–100 chars: letters, digits and _ - . : # /). Repeating it returns the same order (idempotent). Also accepted as merchant_order_no
amountstringहाँOrder amount in INR, 2 decimals, e.g. "500.00". Limits: see Overview
tradeTypestringनहींINRUPI (default) or usdt. Also accepted as trade_type
notifyUrlstringनहींURL that receives our callback. Falls back to the callback URL saved in your panel. Also accepted as callback_url
returnUrlstringनहींWhere the customer is sent after paying (also return_url)
extrastringनहींFree text (max 255 chars) echoed back in queries and callbacks
signstringहाँSignature, see the Signature tab
  • इडेम्पोटेंट: वही mchOrderNo दोबारा भेजने पर वही ऑर्डर लौटता है (“duplicate”: true के साथ)। मौजूदा mchOrderNo के लिए अलग राशि भेजने पर 409 duplicate_order मिलता है।
  • USDT: tradeType “usdt” के लिए आपके खाते में USDT चालू होना चाहिए। amount INR मान है; जवाब में usdtAmount (भुगतान करने वाली ठीक USDT राशि), rate, address और network TRC20 जुड़ते हैं — चेकआउट पेज ये ग्राहक को दिखाता है।
  • snake_case फ़ील्ड नाम भी चलते हैं: merchant_id, merchant_order_no, trade_type, callback_url, return_url। इन अनुरोधों के लिए वैकल्पिक हस्ताक्षर md5(merchant_id + amount + merchant_order_no + api_key + callback_url) भी स्वीकार है।
<?php
function rp_sign(array $p, string $key): string {
    unset($p['sign']);
    $p = array_filter($p, fn($v) => $v !== '' && $v !== null);   // empty values are not signed
    ksort($p, SORT_STRING);                                      // sort by parameter name
    $pairs = [];
    foreach ($p as $k => $v) $pairs[] = $k . '=' . $v;
    return strtoupper(md5(implode('&', $pairs) . '&key=' . $key));
}

$base = 'https://www.reddypay.live/api/v3';
$p = [
    'mchId'      => 'YOUR_MERCHANT_ID',
    'mchOrderNo' => 'ORDER-1001',                 // your unique order number
    'amount'     => '500.00',
    'tradeType'  => 'INRUPI',                     // or 'usdt'
    'notifyUrl'  => 'https://merchant.example.com/webhook/reddypay',
    'returnUrl'  => 'https://merchant.example.com/thanks',
];
$p['sign'] = rp_sign($p, 'YOUR_API_KEY');         // mchKey

$ch = curl_init("$base/payin");
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_POSTFIELDS => json_encode($p)]);
$res = json_decode(curl_exec($ch), true);
if (!empty($res['success'])) {
    header('Location: ' . $res['data']['pay_url']);   // our hosted checkout: send the customer there
} else {
    error_log($res['error'] . ': ' . $res['message']);
}
const crypto = require('crypto');
function rpSign(p, key) {
  const s = Object.keys(p)
    .filter(k => k !== 'sign' && p[k] !== '' && p[k] != null)   // empty values are not signed
    .sort()                                                      // sort by parameter name
    .map(k => `${k}=${p[k]}`).join('&');
  return crypto.createHash('md5').update(`${s}&key=${key}`).digest('hex').toUpperCase();
}

const p = {
  mchId: 'YOUR_MERCHANT_ID',
  mchOrderNo: 'ORDER-1001',                 // your unique order number
  amount: '500.00',
  tradeType: 'INRUPI',                      // or 'usdt'
  notifyUrl: 'https://merchant.example.com/webhook/reddypay',
  returnUrl: 'https://merchant.example.com/thanks',
};
p.sign = rpSign(p, 'YOUR_API_KEY');         // mchKey

const res = await fetch('https://www.reddypay.live/api/v3/payin', {
  method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(p),
}).then(r => r.json());
if (res.success) console.log('redirect the customer to', res.data.pay_url);
else console.error(res.error, res.message);
import hashlib

def rp_sign(p, key):
    s = '&'.join(f'{k}={p[k]}' for k in sorted(p)
                 if k != 'sign' and p[k] not in ('', None))      # sorted, empty values skipped
    return hashlib.md5(f'{s}&key={key}'.encode()).hexdigest().upper()

import requests

p = {
    'mchId': 'YOUR_MERCHANT_ID',
    'mchOrderNo': 'ORDER-1001',             # your unique order number
    'amount': '500.00',
    'tradeType': 'INRUPI',                  # or 'usdt'
    'notifyUrl': 'https://merchant.example.com/webhook/reddypay',
    'returnUrl': 'https://merchant.example.com/thanks',
}
p['sign'] = rp_sign(p, 'YOUR_API_KEY')      # mchKey

res = requests.post('https://www.reddypay.live/api/v3/payin', json=p, timeout=30).json()
if res.get('success'):
    print('redirect the customer to', res['data']['pay_url'])
else:
    print(res.get('error'), res.get('message'))
# sign: sorted "name=value" pairs joined with &, then &key=KEY -> MD5 -> upper case
rp_sign() { printf '%s' "$1&key=$2" | md5sum | cut -d' ' -f1 | tr 'a-f' 'A-F'; }   # macOS: md5 -q
MCH_ID='YOUR_MERCHANT_ID'; KEY='YOUR_API_KEY'            # mchKey
SIGN=$(rp_sign "amount=500.00&mchId=$MCH_ID&mchOrderNo=ORDER-1001&notifyUrl=https://merchant.example.com/webhook/reddypay&tradeType=INRUPI" "$KEY")

curl -sS -X POST 'https://www.reddypay.live/api/v3/payin' -H 'Content-Type: application/json' -d "{
  \"mchId\": \"$MCH_ID\", \"mchOrderNo\": \"ORDER-1001\", \"amount\": \"500.00\", \"tradeType\": \"INRUPI\",
  \"notifyUrl\": \"https://merchant.example.com/webhook/reddypay\", \"sign\": \"$SIGN\"
}"
रिस्पॉन्स
{
    "code": 200,
    "success": true,
    "message": "Success",
    "data": {
        "orderNo": "RP2610011449406340360",
        "mchOrderNo": "ORDER-1001",
        "amount": "500.00",
        "fee": "55.00",
        "netAmount": "445.00",
        "paidAmount": null,
        "tradeType": "INRUPI",
        "status": "pending",
        "utr": null,
        "pay_url": "https://www.reddypay.live/pay/48568a0be2cab05e6a49",
        "payUrl": "https://www.reddypay.live/pay/48568a0be2cab05e6a49",
        "extra": "",
        "createdAt": "2026-10-01T14:49:40+05:30",
        "expiresAt": "2026-10-01T15:19:40+05:30",
        "paidAt": null
    }
}
रिस्पॉन्स (USDT)
{
    "code": 200,
    "success": true,
    "message": "Success",
    "data": {
        "tradeType": "usdt",
        "usdtAmount": "5.640000",
        "rate": "88.6500",
        "address": "TXYZ…YourReceivingAddress",
        "network": "TRC20",
        "orderNo": "RP2610011449406340360",
        "mchOrderNo": "ORDER-1001",
        "amount": "500.00",
        "fee": "55.00",
        "netAmount": "445.00",
        "paidAmount": null,
        "status": "pending",
        "utr": null,
        "pay_url": "https://www.reddypay.live/pay/48568a0be2cab05e6a49",
        "payUrl": "https://www.reddypay.live/pay/48568a0be2cab05e6a49",
        "extra": "",
        "createdAt": "2026-10-01T14:49:40+05:30",
        "expiresAt": "2026-10-01T15:19:40+05:30",
        "paidAt": null
    }
}
POSThttps://www.reddypay.live/api/v3/check-order-statusmchKey से साइन करें

डिपॉज़िट ऑर्डर की मौजूदा स्थिति लौटाता है। mchKey से हस्ताक्षरित होने पर यह आपके pay-in ऑर्डर में देखता है; mchSecret से हस्ताक्षरित होने पर वही endpoint निकासियाँ क्वेरी करता है (Query Pay-out देखें)। इसे कुछ सेकंड में एक बार से ज़्यादा पोल न करें और कॉलबैक को प्राथमिकता दें।

ParameterTypeRequiredविवरण
mchIdstringहाँYour Merchant ID (also accepted as merchant_id)
mchOrderNostringनहींYour order number (one of mchOrderNo / orderNo is required)
orderNostringनहींOur order number returned by /payin
signstringहाँSignature, see the Signature tab
<?php
function rp_sign(array $p, string $key): string {
    unset($p['sign']);
    $p = array_filter($p, fn($v) => $v !== '' && $v !== null);   // empty values are not signed
    ksort($p, SORT_STRING);                                      // sort by parameter name
    $pairs = [];
    foreach ($p as $k => $v) $pairs[] = $k . '=' . $v;
    return strtoupper(md5(implode('&', $pairs) . '&key=' . $key));
}

$p = ['mchId' => 'YOUR_MERCHANT_ID', 'mchOrderNo' => 'ORDER-1001'];   // or 'orderNo' => our order number
$p['sign'] = rp_sign($p, 'YOUR_API_KEY');                   // mchKey = pay-in order

$ch = curl_init('https://www.reddypay.live/api/v3/check-order-status');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_POSTFIELDS => json_encode($p)]);
$res = json_decode(curl_exec($ch), true);
echo $res['data']['status'] ?? $res['message'];             // pending | success | failed | expired
const crypto = require('crypto');
function rpSign(p, key) {
  const s = Object.keys(p)
    .filter(k => k !== 'sign' && p[k] !== '' && p[k] != null)   // empty values are not signed
    .sort()                                                      // sort by parameter name
    .map(k => `${k}=${p[k]}`).join('&');
  return crypto.createHash('md5').update(`${s}&key=${key}`).digest('hex').toUpperCase();
}

const p = { mchId: 'YOUR_MERCHANT_ID', mchOrderNo: 'ORDER-1001' };   // or orderNo: our order number
p.sign = rpSign(p, 'YOUR_API_KEY');                         // mchKey = pay-in order
const res = await fetch('https://www.reddypay.live/api/v3/check-order-status', {
  method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(p),
}).then(r => r.json());
console.log(res.data ? res.data.status : res.message);     // pending | success | failed | expired
import hashlib

def rp_sign(p, key):
    s = '&'.join(f'{k}={p[k]}' for k in sorted(p)
                 if k != 'sign' and p[k] not in ('', None))      # sorted, empty values skipped
    return hashlib.md5(f'{s}&key={key}'.encode()).hexdigest().upper()

import requests

p = {'mchId': 'YOUR_MERCHANT_ID', 'mchOrderNo': 'ORDER-1001'}          # or 'orderNo': our order number
p['sign'] = rp_sign(p, 'YOUR_API_KEY')                      # mchKey = pay-in order
res = requests.post('https://www.reddypay.live/api/v3/check-order-status', json=p, timeout=30).json()
print(res['data']['status'] if res.get('success') else res.get('message'))   # pending | success | failed | expired
# sign: sorted "name=value" pairs joined with &, then &key=KEY -> MD5 -> upper case
rp_sign() { printf '%s' "$1&key=$2" | md5sum | cut -d' ' -f1 | tr 'a-f' 'A-F'; }   # macOS: md5 -q
MCH_ID='YOUR_MERCHANT_ID'; KEY='YOUR_API_KEY'            # mchKey = pay-in order
SIGN=$(rp_sign "mchId=$MCH_ID&mchOrderNo=ORDER-1001" "$KEY")
curl -sS -X POST 'https://www.reddypay.live/api/v3/check-order-status' -H 'Content-Type: application/json' \
  -d "{\"mchId\":\"$MCH_ID\",\"mchOrderNo\":\"ORDER-1001\",\"sign\":\"$SIGN\"}"
रिस्पॉन्स
{
    "code": 200,
    "success": true,
    "message": "Success",
    "data": {
        "status": "success",
        "paidAmount": "500.00",
        "utr": "627412345678",
        "paidAt": "2026-10-01T14:50:15+05:30",
        "type": "payin",
        "orderNo": "RP2610011449406340360",
        "mchOrderNo": "ORDER-1001",
        "amount": "500.00",
        "fee": "55.00",
        "netAmount": "445.00",
        "tradeType": "INRUPI",
        "pay_url": "https://www.reddypay.live/pay/48568a0be2cab05e6a49",
        "payUrl": "https://www.reddypay.live/pay/48568a0be2cab05e6a49",
        "extra": "",
        "createdAt": "2026-10-01T14:49:40+05:30",
        "expiresAt": "2026-10-01T15:19:40+05:30"
    }
}
स्थितिअर्थ
pendingWaiting for the customer. A payment made after expiry is still credited, and you get the success callback.
successPaid and credited to your wallet (netAmount). Final.
failedभुगतान विफल या अस्वीकार कर दिया गया। अंतिम जब तक ग्राहक बाद में भुगतान नहीं करता।
expiredग्राहक ने समय पर भुगतान नहीं किया (डिफ़ॉल्ट रूप से 30 मिनट)।
processingPayouts only: approved, the transfer is being made.
POSThttps://www.reddypay.live/api/v3/payoutmchSecret से साइन करें
IP अनुमति-सूची ज़रूरी है। API से पेआउट तभी काम करते हैं जब आपने Basic Information में अपने सर्वरों के IP एड्रेस सहेजे हों; allow-list के बिना कॉल 403 ip_whitelist_required से अस्वीकार होती हैं। API Key और IP सूची मिलकर निकासी पासवर्ड की जगह लेती हैं।

निकासी बनाता है। लाभार्थी को ठीक amount मिलता है; हमारा पे-आउट शुल्क ऊपर से लगता है और राशि के साथ आपके उपलब्ध बैलेंस से डेबिट होता है (पेआउट के भुगतान या अस्वीकार होने तक रोका जाता है)। सीमाएँ और आपका बैलेंस पैनल की तरह जाँचे जाते हैं।

ParameterTypeRequiredविवरण
mchIdstringहाँYour Merchant ID (also accepted as merchant_id)
mchOrderNostringहाँYour unique payout number (idempotent, same rules as pay-in)
amountstringहाँAmount the beneficiary receives, in INR with 2 decimals. Our fee is charged on top
payTypestringनहींbank, upi or usdt. Detected from the destination fields when omitted
bankCodestringनहींBank name exactly as in the Bank Codes tab (bank payouts)
accountNamestringनहींखाता धारक का नाम (बैंक भुगतान)
accountNumberstringनहींBank account number, 6–20 digits (bank payouts)
ifscstringनहींIFSC code, e.g. HDFC0001234 (bank payouts)
upiIdstringनहींUPI ID such as name@bank (UPI payouts)
usdtAddressstringनहींTRC20 address starting with T (USDT payouts, needs USDT enabled for your account)
signstringहाँSignature, see the Signature tab
  • गंतव्य: bank = bankCode + accountName + accountNumber + ifsc · upi = upiId · usdt = usdtAddress (TRC20)।
  • mchOrderNo पर इडेम्पोटेंट। पेआउट के लिए notifyUrl इस्तेमाल नहीं होता: पेआउट कॉलबैक आपके पैनल में सहेजे गए कॉलबैक URL पर जाते हैं।
  • पे-आउट शुल्क: 6.5% + ₹10। राशि सीमा: प्रति अनुरोध ₹500.00 से ₹200,000.00, प्रति दिन ₹200,000.00।
<?php
function rp_sign(array $p, string $key): string {
    unset($p['sign']);
    $p = array_filter($p, fn($v) => $v !== '' && $v !== null);   // empty values are not signed
    ksort($p, SORT_STRING);                                      // sort by parameter name
    $pairs = [];
    foreach ($p as $k => $v) $pairs[] = $k . '=' . $v;
    return strtoupper(md5(implode('&', $pairs) . '&key=' . $key));
}

$p = [
    'mchId'         => 'YOUR_MERCHANT_ID',
    'mchOrderNo'    => 'PAYOUT-77',
    'amount'        => '1000.00',               // the beneficiary receives exactly this; our fee is added on top
    'payType'       => 'bank',                  // bank | upi | usdt
    'bankCode'      => 'HDFC Bank',             // see the Bank Codes tab
    'accountName'   => 'Test User',
    'accountNumber' => '123456789012',
    'ifsc'          => 'HDFC0001234',
];
$p['sign'] = rp_sign($p, 'YOUR_API_SECRET');    // mchSecret (NOT mchKey); the call must come from an allow-listed IP

$ch = curl_init('https://www.reddypay.live/api/v3/payout');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_POSTFIELDS => json_encode($p)]);
print_r(json_decode(curl_exec($ch), true));
const crypto = require('crypto');
function rpSign(p, key) {
  const s = Object.keys(p)
    .filter(k => k !== 'sign' && p[k] !== '' && p[k] != null)   // empty values are not signed
    .sort()                                                      // sort by parameter name
    .map(k => `${k}=${p[k]}`).join('&');
  return crypto.createHash('md5').update(`${s}&key=${key}`).digest('hex').toUpperCase();
}

const p = {
  mchId: 'YOUR_MERCHANT_ID', mchOrderNo: 'PAYOUT-77', amount: '1000.00', payType: 'bank',
  bankCode: 'HDFC Bank', accountName: 'Test User', accountNumber: '123456789012', ifsc: 'HDFC0001234',
};
p.sign = rpSign(p, 'YOUR_API_SECRET');          // mchSecret (NOT mchKey); the call must come from an allow-listed IP
const res = await fetch('https://www.reddypay.live/api/v3/payout', {
  method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(p),
}).then(r => r.json());
console.log(res);
import hashlib

def rp_sign(p, key):
    s = '&'.join(f'{k}={p[k]}' for k in sorted(p)
                 if k != 'sign' and p[k] not in ('', None))      # sorted, empty values skipped
    return hashlib.md5(f'{s}&key={key}'.encode()).hexdigest().upper()

import requests

p = {'mchId': 'YOUR_MERCHANT_ID', 'mchOrderNo': 'PAYOUT-77', 'amount': '1000.00', 'payType': 'bank',
     'bankCode': 'HDFC Bank', 'accountName': 'Test User', 'accountNumber': '123456789012', 'ifsc': 'HDFC0001234'}
p['sign'] = rp_sign(p, 'YOUR_API_SECRET')       # mchSecret (NOT mchKey); the call must come from an allow-listed IP
print(requests.post('https://www.reddypay.live/api/v3/payout', json=p, timeout=30).json())
# sign: sorted "name=value" pairs joined with &, then &key=KEY -> MD5 -> upper case
rp_sign() { printf '%s' "$1&key=$2" | md5sum | cut -d' ' -f1 | tr 'a-f' 'A-F'; }   # macOS: md5 -q
MCH_ID='YOUR_MERCHANT_ID'; SECRET='YOUR_API_SECRET'      # mchSecret
SIGN=$(rp_sign "accountName=Test User&accountNumber=123456789012&amount=1000.00&bankCode=HDFC Bank&ifsc=HDFC0001234&mchId=$MCH_ID&mchOrderNo=PAYOUT-77&payType=bank" "$SECRET")
curl -sS -X POST 'https://www.reddypay.live/api/v3/payout' -H 'Content-Type: application/json' -d "{
  \"mchId\":\"$MCH_ID\",\"mchOrderNo\":\"PAYOUT-77\",\"amount\":\"1000.00\",\"payType\":\"bank\",\"bankCode\":\"HDFC Bank\",
  \"accountName\":\"Test User\",\"accountNumber\":\"123456789012\",\"ifsc\":\"HDFC0001234\",\"sign\":\"$SIGN\"}"
रिस्पॉन्स
{
    "code": 200,
    "success": true,
    "message": "Success",
    "data": {
        "orderNo": "WD26100112345678",
        "mchOrderNo": "PAYOUT-77",
        "amount": "1000.00",
        "fee": "75.00",
        "totalDebit": "1075.00",
        "status": "pending",
        "payType": "bank",
        "txid": null,
        "createdAt": "2026-10-01T15:01:02+05:30",
        "paidAt": null
    }
}
POSThttps://www.reddypay.live/api/v3/check-order-statusmchSecret से साइन करें

Query Pay-in जैसा ही endpoint, mchSecret से हस्ताक्षरित: तब ऑर्डर आपकी निकासियों में mchOrderNo (आपका पेआउट नंबर) या orderNo (हमारा नंबर) से खोजा जाता है।

ParameterTypeRequiredविवरण
mchIdstringहाँYour Merchant ID (also accepted as merchant_id)
mchOrderNostringनहींYour order number (one of mchOrderNo / orderNo is required)
orderNostringनहींOur order number returned by /payin
signstringहाँSignature, see the Signature tab
<?php
function rp_sign(array $p, string $key): string {
    unset($p['sign']);
    $p = array_filter($p, fn($v) => $v !== '' && $v !== null);   // empty values are not signed
    ksort($p, SORT_STRING);                                      // sort by parameter name
    $pairs = [];
    foreach ($p as $k => $v) $pairs[] = $k . '=' . $v;
    return strtoupper(md5(implode('&', $pairs) . '&key=' . $key));
}

$p = ['mchId' => 'YOUR_MERCHANT_ID', 'mchOrderNo' => 'PAYOUT-77'];     // or 'orderNo' => our payout number (WD…)
$p['sign'] = rp_sign($p, 'YOUR_API_SECRET');                  // mchSecret = withdrawal

$ch = curl_init('https://www.reddypay.live/api/v3/check-order-status');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_POSTFIELDS => json_encode($p)]);
$res = json_decode(curl_exec($ch), true);
echo $res['data']['status'] ?? $res['message'];               // pending | processing | success | failed
# sign: sorted "name=value" pairs joined with &, then &key=KEY -> MD5 -> upper case
rp_sign() { printf '%s' "$1&key=$2" | md5sum | cut -d' ' -f1 | tr 'a-f' 'A-F'; }   # macOS: md5 -q
MCH_ID='YOUR_MERCHANT_ID'; SECRET='YOUR_API_SECRET'      # mchSecret = withdrawal
SIGN=$(rp_sign "mchId=$MCH_ID&mchOrderNo=PAYOUT-77" "$SECRET")
curl -sS -X POST 'https://www.reddypay.live/api/v3/check-order-status' -H 'Content-Type: application/json' \
  -d "{\"mchId\":\"$MCH_ID\",\"mchOrderNo\":\"PAYOUT-77\",\"sign\":\"$SIGN\"}"
रिस्पॉन्स
{
    "code": 200,
    "success": true,
    "message": "Success",
    "data": {
        "orderNo": "WD26100112345678",
        "mchOrderNo": "PAYOUT-77",
        "amount": "1000.00",
        "fee": "75.00",
        "totalDebit": "1075.00",
        "status": "success",
        "payType": "bank",
        "txid": null,
        "createdAt": "2026-10-01T15:01:02+05:30",
        "paidAt": "2026-10-01T15:20:11+05:30",
        "type": "payout"
    }
}
स्थितिअर्थ
pendingस्वीकृति की प्रतीक्षा में।
processingस्वीकृत, ट्रांसफ़र किया जा रहा है।
successलाभार्थी को भुगतान किया गया। अंतिम।
failedअस्वीकार या रद्द हुआ, रोकी गई राशि और शुल्क आपके बैलेंस में लौट गए। अंतिम।
POSThttps://www.reddypay.live/api/v3/check-gateway-balancemchSecret से साइन करें

आपका वॉलेट लौटाता है: balance (= उपलब्ध, जो आप निकाल सकते हैं), frozen (लंबित निकासियों के लिए रोका गया) और total।

ParameterTypeRequiredविवरण
mchIdstringहाँYour Merchant ID (also accepted as merchant_id)
signstringहाँSignature, see the Signature tab
<?php
function rp_sign(array $p, string $key): string {
    unset($p['sign']);
    $p = array_filter($p, fn($v) => $v !== '' && $v !== null);   // empty values are not signed
    ksort($p, SORT_STRING);                                      // sort by parameter name
    $pairs = [];
    foreach ($p as $k => $v) $pairs[] = $k . '=' . $v;
    return strtoupper(md5(implode('&', $pairs) . '&key=' . $key));
}

$p = ['mchId' => 'YOUR_MERCHANT_ID'];
$p['sign'] = rp_sign($p, 'YOUR_API_SECRET');    // mchSecret
$ch = curl_init('https://www.reddypay.live/api/v3/check-gateway-balance');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_POSTFIELDS => json_encode($p)]);
$res = json_decode(curl_exec($ch), true);
echo $res['data']['balance'] ?? $res['message'];
const crypto = require('crypto');
function rpSign(p, key) {
  const s = Object.keys(p)
    .filter(k => k !== 'sign' && p[k] !== '' && p[k] != null)   // empty values are not signed
    .sort()                                                      // sort by parameter name
    .map(k => `${k}=${p[k]}`).join('&');
  return crypto.createHash('md5').update(`${s}&key=${key}`).digest('hex').toUpperCase();
}

const p = { mchId: 'YOUR_MERCHANT_ID' };
p.sign = rpSign(p, 'YOUR_API_SECRET');          // mchSecret
const res = await fetch('https://www.reddypay.live/api/v3/check-gateway-balance', {
  method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(p),
}).then(r => r.json());
console.log(res.data ? res.data.balance : res.message);
import hashlib

def rp_sign(p, key):
    s = '&'.join(f'{k}={p[k]}' for k in sorted(p)
                 if k != 'sign' and p[k] not in ('', None))      # sorted, empty values skipped
    return hashlib.md5(f'{s}&key={key}'.encode()).hexdigest().upper()

import requests

p = {'mchId': 'YOUR_MERCHANT_ID'}
p['sign'] = rp_sign(p, 'YOUR_API_SECRET')       # mchSecret
res = requests.post('https://www.reddypay.live/api/v3/check-gateway-balance', json=p, timeout=30).json()
print(res['data']['balance'] if res.get('success') else res.get('message'))
# sign: sorted "name=value" pairs joined with &, then &key=KEY -> MD5 -> upper case
rp_sign() { printf '%s' "$1&key=$2" | md5sum | cut -d' ' -f1 | tr 'a-f' 'A-F'; }   # macOS: md5 -q
MCH_ID='YOUR_MERCHANT_ID'; SECRET='YOUR_API_SECRET'      # mchSecret
SIGN=$(rp_sign "mchId=$MCH_ID" "$SECRET")
curl -sS -X POST 'https://www.reddypay.live/api/v3/check-gateway-balance' -H 'Content-Type: application/json' -d "{\"mchId\":\"$MCH_ID\",\"sign\":\"$SIGN\"}"
रिस्पॉन्स
{
    "code": 200,
    "success": true,
    "message": "Success",
    "data": {
        "balance": "12450.00",
        "available": "12450.00",
        "frozen": "1075.00",
        "total": "13525.00",
        "currency": "INR"
    }
}

हर अनुरोध और हर कॉलबैक में एक sign पैरामीटर होता है: क्रमबद्ध पैरामीटर के बाद &key=KEY का MD5 हैश, अपर केस में।

  1. हस्ताक्षर को छोड़कर अनुरोध के सभी पैरामीटर लें। खाली मान वाले पैरामीटर छोड़ दिए जाते हैं।
  2. उन्हें पैरामीटर के नाम से, सादे बाइट क्रम में सजाएँ (mchId, mchOrderNo से पहले आता है; अपर-केस अक्षर लोअर-केस से पहले)।
  3. हर एक को name=value लिखें और & से जोड़ें। मान URL-एन्कोड नहीं होते। राशियाँ दो दशमलव वाले स्ट्रिंग के रूप में भेजें।
  4. &key= लगाकर अपनी कुंजी जोड़ें: pay-in और कॉलबैक के लिए mchKey, पे-आउट और बैलेंस के लिए mchSecret।
  5. उस पाठ का MD5 हैश लें और इसे बड़े अक्षर में लिखें। वह हस्ताक्षर है।
परीक्षण वेक्टर — इसके विरुद्ध अपने कोड की जांच करें
amount=500.00&mchId=123456789&mchOrderNo=ORDER-1001&notifyUrl=https://merchant.example.com/webhook/reddypay&tradeType=INRUPI&key=TEST_KEY_0123456789abcdef
Key: TEST_KEY_0123456789abcdef → 618EB8435DBA875EB138FF5657E8FA6F
function rp_sign(array $p, string $key): string {
    unset($p['sign']);
    $p = array_filter($p, fn($v) => $v !== '' && $v !== null);   // empty values are not signed
    ksort($p, SORT_STRING);                                      // sort by parameter name
    $pairs = [];
    foreach ($p as $k => $v) $pairs[] = $k . '=' . $v;
    return strtoupper(md5(implode('&', $pairs) . '&key=' . $key));
}
const crypto = require('crypto');
function rpSign(p, key) {
  const s = Object.keys(p)
    .filter(k => k !== 'sign' && p[k] !== '' && p[k] != null)   // empty values are not signed
    .sort()                                                      // sort by parameter name
    .map(k => `${k}=${p[k]}`).join('&');
  return crypto.createHash('md5').update(`${s}&key=${key}`).digest('hex').toUpperCase();
}
import hashlib

def rp_sign(p, key):
    s = '&'.join(f'{k}={p[k]}' for k in sorted(p)
                 if k != 'sign' and p[k] not in ('', None))      # sorted, empty values skipped
    return hashlib.md5(f'{s}&key={key}'.encode()).hexdigest().upper()
import java.security.MessageDigest;
import java.nio.charset.StandardCharsets;
import java.util.*;

static String rpSign(Map<String, String> p, String key) throws Exception {
    StringBuilder sb = new StringBuilder();
    for (String k : new TreeMap<>(p).keySet()) {                  // sorted by name
        String v = p.get(k);
        if (k.equals("sign") || v == null || v.isEmpty()) continue;
        sb.append(k).append('=').append(v).append('&');
    }
    sb.append("key=").append(key);
    byte[] d = MessageDigest.getInstance("MD5").digest(sb.toString().getBytes(StandardCharsets.UTF_8));
    StringBuilder hex = new StringBuilder();
    for (byte b : d) hex.append(String.format("%02X", b));
    return hex.toString();
}
# sign: sorted "name=value" pairs joined with &, then &key=KEY -> MD5 -> upper case
rp_sign() { printf '%s' "$1&key=$2" | md5sum | cut -d' ' -f1 | tr 'a-f' 'A-F'; }   # macOS: md5 -q

सिग्नेचर कैलकुलेटर

कोई अनुरोध या कॉलबैक बॉडी और अपनी कुंजी पेस्ट करें। सब कुछ आपके ब्राउज़र में गणना होता है; हमें कुछ नहीं भेजा जाता।

ऑर्डर का भुगतान होने (या विफल होने) पर हम नतीजा आपके notifyUrl पर — या Basic Information में सहेजे कॉलबैक URL पर — POST करते हैं। बॉडी JSON (डिफ़ॉल्ट) या फ़ॉर्म-एन्कोडेड होती है, जैसा “Test endpoint” दबाने पर पता चला हो। हर गैर-खाली फ़ील्ड sign के दायरे में है।

फ़ील्डविवरण
mchIdYour Merchant ID (alias merchant_id)
mchOrderNoYour order number (alias merchant_order_no)
orderNoOur order number (alias gateway_order_no)
amountOrder amount
paidAmountAmount actually paid
feeOur fee
netAmountCredited to your wallet (amount − fee)
tradeTypeINRUPI | usdt
statussuccess | failed
utrBank reference (UTR), when known
payTimePayment time, ISO-8601 IST
extraआपने भेजा गया अतिरिक्त मूल्य
usdtAmountUSDT orders only: exact USDT amount
signSignature (MD5, uppercase) made with your mchKey
कॉलबैक बॉडी
{
    "mchId": "123456789",
    "merchant_id": "123456789",
    "mchOrderNo": "ORDER-1001",
    "merchant_order_no": "ORDER-1001",
    "orderNo": "RP2610011449406340360",
    "gateway_order_no": "RP2610011449406340360",
    "amount": "500.00",
    "paidAmount": "500.00",
    "fee": "55.00",
    "netAmount": "445.00",
    "tradeType": "INRUPI",
    "status": "success",
    "utr": "627412345678",
    "payTime": "2026-10-01T14:50:15+05:30",
    "extra": "",
    "sign": "2B60E30809FDA5D9D5752EED2DAEB84E"
}

जाँचें और स्वीकार करें

  1. अपने mchKey से sign को छोड़कर सभी प्राप्त फ़ील्ड पर sign दोबारा निकालें (Signature देखें) और constant time में तुलना करें। अलग निकले तो अनुरोध अस्वीकार करें।
  2. इडेम्पोटेंट रहें: वही कॉलबैक दोबारा आ सकता है (रीट्राई, हाथ से दोबारा भेजना)। अपना ऑर्डर खोजने के लिए mchOrderNo / orderNo इस्तेमाल करें और जो स्थिति आप पहले प्रोसेस कर चुके हैं उसे अनदेखा करें।
  3. सामान देने से पहले जाँचें कि status = success है और paidAmount आपकी अपेक्षा से मेल खाता है। संदेह हो तो /check-order-status से पुष्टि करें।
  4. सादे टेक्स्ट success के साथ HTTP 200 से जवाब दें। इसके अलावा कुछ भी — टाइमआउट (8 s), रीडायरेक्ट, त्रुटि कोड या बिना “success” वाली बॉडी — विफल गिना जाता है और 1 मिनट, 5 मिनट, 15 मिनट, 1 घंटे और 6 घंटे बाद फिर भेजा जाता है; आख़िरी कोशिश के बाद डिलीवरी विफल चिह्नित हो जाती है (आपको अपनी सूचनाओं में दिखेगा)।
<?php
function rp_sign(array $p, string $key): string {
    unset($p['sign']);
    $p = array_filter($p, fn($v) => $v !== '' && $v !== null);   // empty values are not signed
    ksort($p, SORT_STRING);                                      // sort by parameter name
    $pairs = [];
    foreach ($p as $k => $v) $pairs[] = $k . '=' . $v;
    return strtoupper(md5(implode('&', $pairs) . '&key=' . $key));
}

// Your notifyUrl endpoint. We send JSON or form fields (your choice in Basic Information).
$data = json_decode(file_get_contents('php://input'), true) ?: $_POST;
$received = $data['sign'] ?? '';
if (!hash_equals(rp_sign($data, 'YOUR_API_KEY'), strtoupper($received))) {   // mchKey; for payout callbacks use mchSecret
    http_response_code(400); exit('invalid sign');
}
// Idempotent: the same callback can arrive more than once (retries, manual re-send).
if ($data['status'] === 'success' && !order_already_paid($data['mchOrderNo'])) {
    mark_order_paid($data['mchOrderNo'], $data['paidAmount']);
}
echo 'success';          // plain text "success" with HTTP 200, otherwise we retry
const crypto = require('crypto');
function rpSign(p, key) {
  const s = Object.keys(p)
    .filter(k => k !== 'sign' && p[k] !== '' && p[k] != null)   // empty values are not signed
    .sort()                                                      // sort by parameter name
    .map(k => `${k}=${p[k]}`).join('&');
  return crypto.createHash('md5').update(`${s}&key=${key}`).digest('hex').toUpperCase();
}

const express = require('express');
const app = express();
app.use(express.json()); app.use(express.urlencoded({ extended: false }));
app.post('/webhook/reddypay', (req, res) => {
  const d = req.body;
  const ok = (d.sign || '').toUpperCase() === rpSign(d, 'YOUR_API_KEY');     // mchKey; payout callbacks: mchSecret
  if (!ok) return res.status(400).send('invalid sign');
  if (d.status === 'success' && !orderAlreadyPaid(d.mchOrderNo)) markOrderPaid(d.mchOrderNo, d.paidAmount);   // idempotent
  res.send('success');       // plain text "success" with HTTP 200, otherwise we retry
});
import hashlib

def rp_sign(p, key):
    s = '&'.join(f'{k}={p[k]}' for k in sorted(p)
                 if k != 'sign' and p[k] not in ('', None))      # sorted, empty values skipped
    return hashlib.md5(f'{s}&key={key}'.encode()).hexdigest().upper()

from flask import Flask, request

app = Flask(__name__)

@app.post('/webhook/reddypay')
def webhook():
    d = request.get_json(silent=True) or request.form.to_dict()
    if d.get('sign', '').upper() != rp_sign(d, 'YOUR_API_KEY'):               # mchKey; payout callbacks: mchSecret
        return 'invalid sign', 400
    if d.get('status') == 'success' and not order_already_paid(d['mchOrderNo']):   # idempotent
        mark_order_paid(d['mchOrderNo'], d['paidAmount'])
    return 'success'           # plain text "success" with HTTP 200, otherwise we retry
import java.security.MessageDigest;
import java.nio.charset.StandardCharsets;
import java.util.*;

static String rpSign(Map<String, String> p, String key) throws Exception {
    StringBuilder sb = new StringBuilder();
    for (String k : new TreeMap<>(p).keySet()) {                  // sorted by name
        String v = p.get(k);
        if (k.equals("sign") || v == null || v.isEmpty()) continue;
        sb.append(k).append('=').append(v).append('&');
    }
    sb.append("key=").append(key);
    byte[] d = MessageDigest.getInstance("MD5").digest(sb.toString().getBytes(StandardCharsets.UTF_8));
    StringBuilder hex = new StringBuilder();
    for (byte b : d) hex.append(String.format("%02X", b));
    return hex.toString();
}

// Spring example: verify, then answer the text "success".
@PostMapping("/webhook/reddypay")
String webhook(@RequestBody Map<String, String> d) throws Exception {
    if (!rpSign(d, "YOUR_API_KEY").equalsIgnoreCase(d.getOrDefault("sign", ""))) {   // mchKey; payout callbacks: mchSecret
        throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "invalid sign");
    }
    if ("success".equals(d.get("status")) && !orderAlreadyPaid(d.get("mchOrderNo"))) markOrderPaid(d.get("mchOrderNo"), d.get("paidAmount"));
    return "success";
}

पे-आउट कॉलबैक

API से बनी निकासियों के लिए हम स्थिति processing (मंज़ूर), success (भुगतान हुआ) या failed (अस्वीकार) भेजते हैं। बॉडी आपके mchSecret से हस्ताक्षरित होती है।

पे-आउट कॉलबैक बॉडी
{
    "mchId": "123456789",
    "merchant_id": "123456789",
    "mchOrderNo": "PAYOUT-77",
    "merchant_order_no": "PAYOUT-77",
    "orderNo": "WD26100112345678",
    "gateway_order_no": "WD26100112345678",
    "amount": "1000.00",
    "fee": "75.00",
    "totalDebit": "1075.00",
    "status": "success",
    "txid": "",
    "payTime": "2026-10-01T15:20:11+05:30",
    "message": "",
    "sign": "…"
}

आज़माएँ: Basic Information में “Test endpoint” दबाएँ। हम एक हस्ताक्षरित टेस्ट कॉलबैक (test=true) JSON और फ़ॉर्म डेटा दोनों में भेजते हैं और आपका सर्वर जो फ़ॉर्मेट स्वीकार करता है उसे याद रखते हैं। भुगतान हो चुका ऑर्डर ऑर्डर सूची से दोबारा भेजा जा सकता है (“Resend webhook”)।

कॉपी-पेस्ट शेल स्क्रिप्ट (bash + curl + md5sum)। प्लेसहोल्डर की जगह अपने मान डालें।

डिपॉज़िट ऑर्डर बनाएँ
# sign: sorted "name=value" pairs joined with &, then &key=KEY -> MD5 -> upper case
rp_sign() { printf '%s' "$1&key=$2" | md5sum | cut -d' ' -f1 | tr 'a-f' 'A-F'; }   # macOS: md5 -q
MCH_ID='YOUR_MERCHANT_ID'; KEY='YOUR_API_KEY'            # mchKey
SIGN=$(rp_sign "amount=500.00&mchId=$MCH_ID&mchOrderNo=ORDER-1001&notifyUrl=https://merchant.example.com/webhook/reddypay&tradeType=INRUPI" "$KEY")

curl -sS -X POST 'https://www.reddypay.live/api/v3/payin' -H 'Content-Type: application/json' -d "{
  \"mchId\": \"$MCH_ID\", \"mchOrderNo\": \"ORDER-1001\", \"amount\": \"500.00\", \"tradeType\": \"INRUPI\",
  \"notifyUrl\": \"https://merchant.example.com/webhook/reddypay\", \"sign\": \"$SIGN\"
}"
डिपॉज़िट ऑर्डर देखें
# sign: sorted "name=value" pairs joined with &, then &key=KEY -> MD5 -> upper case
rp_sign() { printf '%s' "$1&key=$2" | md5sum | cut -d' ' -f1 | tr 'a-f' 'A-F'; }   # macOS: md5 -q
MCH_ID='YOUR_MERCHANT_ID'; KEY='YOUR_API_KEY'            # mchKey = pay-in order
SIGN=$(rp_sign "mchId=$MCH_ID&mchOrderNo=ORDER-1001" "$KEY")
curl -sS -X POST 'https://www.reddypay.live/api/v3/check-order-status' -H 'Content-Type: application/json' \
  -d "{\"mchId\":\"$MCH_ID\",\"mchOrderNo\":\"ORDER-1001\",\"sign\":\"$SIGN\"}"
निकासी बनाएँ
# sign: sorted "name=value" pairs joined with &, then &key=KEY -> MD5 -> upper case
rp_sign() { printf '%s' "$1&key=$2" | md5sum | cut -d' ' -f1 | tr 'a-f' 'A-F'; }   # macOS: md5 -q
MCH_ID='YOUR_MERCHANT_ID'; SECRET='YOUR_API_SECRET'      # mchSecret
SIGN=$(rp_sign "accountName=Test User&accountNumber=123456789012&amount=1000.00&bankCode=HDFC Bank&ifsc=HDFC0001234&mchId=$MCH_ID&mchOrderNo=PAYOUT-77&payType=bank" "$SECRET")
curl -sS -X POST 'https://www.reddypay.live/api/v3/payout' -H 'Content-Type: application/json' -d "{
  \"mchId\":\"$MCH_ID\",\"mchOrderNo\":\"PAYOUT-77\",\"amount\":\"1000.00\",\"payType\":\"bank\",\"bankCode\":\"HDFC Bank\",
  \"accountName\":\"Test User\",\"accountNumber\":\"123456789012\",\"ifsc\":\"HDFC0001234\",\"sign\":\"$SIGN\"}"
बैलेंस जाँचें
# sign: sorted "name=value" pairs joined with &, then &key=KEY -> MD5 -> upper case
rp_sign() { printf '%s' "$1&key=$2" | md5sum | cut -d' ' -f1 | tr 'a-f' 'A-F'; }   # macOS: md5 -q
MCH_ID='YOUR_MERCHANT_ID'; SECRET='YOUR_API_SECRET'      # mchSecret
SIGN=$(rp_sign "mchId=$MCH_ID" "$SECRET")
curl -sS -X POST 'https://www.reddypay.live/api/v3/check-gateway-balance' -H 'Content-Type: application/json' -d "{\"mchId\":\"$MCH_ID\",\"sign\":\"$SIGN\"}"

bank पेआउट में bankCode के रूप में बैंक का नाम ठीक वैसा ही इस्तेमाल करें जैसा सूचीबद्ध है (अक्षरों का केस मायने नहीं रखता)। कोई और टेक्स्ट स्वीकार हो जाता है और हमारे ऑपरेटरों को वैसा ही लिखा दिखता है।

#bankCode
1State Bank of India (SBI)
2Punjab National Bank (PNB)
3Bank of Baroda
4Canara Bank
5Union Bank of India
6Bank of India
7Indian Bank
8Central Bank of India
9Indian Overseas Bank
10UCO Bank
11Bank of Maharashtra
12Punjab & Sind Bank
13HDFC Bank
14ICICI Bank
15Axis Bank
16Kotak Mahindra Bank
17IndusInd Bank
18Yes Bank
19IDFC FIRST Bank
20Federal Bank
21South Indian Bank
22RBL Bank
23Karur Vysya Bank
24Karnataka Bank
25City Union Bank
26Tamilnad Mercantile Bank
27DCB Bank
28Bandhan Bank
29CSB Bank
30Dhanlaxmi Bank
31Jammu & Kashmir Bank
32AU Small Finance Bank
33Equitas Small Finance Bank
34Ujjivan Small Finance Bank
35ESAF Small Finance Bank
36Suryoday Small Finance Bank
37Jana Small Finance Bank
38North East Small Finance Bank
39Unity Small Finance Bank
40Utkarsh Small Finance Bank
41Airtel Payments Bank
42India Post Payments Bank
43Fino Payments Bank
44Paytm Payments Bank
45NSDL Payments Bank
46Standard Chartered Bank
47HSBC Bank
48Citibank
49Deutsche Bank
50Other / Not Listed

त्रुटियाँ HTTP स्टेटस कोड और सफलताओं जैसे ही envelope का उपयोग करती हैं। error एक स्थिर मशीन-पठनीय कोड है, message इंसानों के लिए है।

त्रुटि रिस्पॉन्स
{
    "code": 401,
    "success": false,
    "message": "Invalid merchant ID or signature. Sign every parameter (except sign) with the right key — see the API documentation.",
    "error": "invalid_signature"
}
HTTPerrorअर्थ
400invalid_requestmchId or sign is missing, or the body could not be read
401invalid_signatureUnknown merchant ID or wrong signature (the same answer for both, on purpose)
401wrong_key_typeSigned with the wrong key: pay-in endpoints need mchKey, payout and balance need mchSecret
403account_suspendedमर्चेंट खाता निलंबित है
403ip_not_allowedYour server IP is not on the IP allow-list of the account
403ip_whitelist_requiredPayouts through the API need an IP allow-list
404order_not_foundNo order with that mchOrderNo / orderNo on your account
405use_postUse POST
409duplicate_orderThis mchOrderNo was already used with a different amount or trade type
413payload_too_largeBody larger than 64 KB
422missing_param / invalid_amount / invalid_mch_order_noएक पैरामीटर गायब है या गलत है, संदेश देखें
422amount_rangeAmount outside your limits
422method_not_allowedINR or USDT is not enabled for your account
422invalid_trade_type / invalid_pay_type / invalid_urlUnsupported value
422insufficient_balance / daily_limit / bank_invalid / ifsc_invalid / upi_invalid / address_invalidPayout rejected, see message (nothing was debited)
429rate_limited / too_many_failuresToo many requests or failed signatures. Wait for Retry-After seconds
500server_errorOur side failed; retry with the same mchOrderNo (safe, idempotent)
503provider_unavailable / maintenance / rate_unavailableNo payment channel (or USDT rate) available, or maintenance. Retry shortly

/payin पर नेटवर्क त्रुटि या HTTP 5xx का मतलब यह नहीं कि ऑर्डर बना ही नहीं: उसी mchOrderNo के साथ अनुरोध दोबारा भेजें (सुरक्षित है) या उसे क्वेरी करें।

मूल payment-link API बिना बदलाव के चलती रहती है। यह आपके API Secret (mchKey नहीं) से हस्ताक्षरित होती है और {"ok":true,"data":{…}} से जवाब देती है। नया कोड API v3 इस्तेमाल करे।

POSThttps://www.reddypay.live/api/v1/create-link.php
ParameterTypeRequiredविवरण
api_keystringहाँआपकी API Key, या इसे X-Api-Key हेडर में भेजें
amountstringहाँदशमलव संख्या, अधिकतम 2 अंक, जैसे 500.00
notestringनहींसादा टेक्स्ट, अधिकतम 255 अक्षर
client_refstringनहींआपका अपना ऑर्डर आईडी, अधिकतम 120 अक्षर। इसे दोहराने पर वही लिंक लौटता है (इडेम्पोटेंट); स्टेटस और वेबहुक में वापस भेजा जाता है
notify_urlstringनहींआपका वेबहुक URL
return_urlstringनहींग्राहक रिटर्न URL
currencystringनहींINR (डिफ़ॉल्ट) या USDT
signstringहाँsign को छोड़कर सभी पैरामीटर का अपरकेस MD5, कुंजी के क्रम में, खाली मान छोड़े हुए, + &key=<API Secret>
cURL
curl -X POST https://www.reddypay.live/api/v1/create-link.php \
  -H "Content-Type: application/json" \
  -d '{"api_key":"YOUR_API_KEY","amount":"500.00","client_ref":"ORDER-1042","notify_url":"https://merchant.example.com/hook","sign":"COMPUTED_SIGNATURE"}'
रिस्पॉन्स
{
    "ok": true,
    "data": {
        "link_code": "48568a0be2cab05e6a49",
        "client_ref": "ORDER-1042",
        "amount": "500.00",
        "currency": "INR",
        "status": "pending",
        "pay_url": "https://www.reddypay.live/pay/48568a0be2cab05e6a49",
        "created_at": "2026-10-01T14:49:40+05:30",
        "expires_at": "2026-10-01T15:19:40+05:30"
    }
}
GEThttps://www.reddypay.live/api/v1/link-status.php?api_key=…&link_code=…&sign=…

link_code, client_ref, amount, currency, status (pending, success, failed, expired), pay_url, note, created_at और paid_at लौटाता है। क्वेरी पैरामीटर पर उसी तरह हस्ताक्षर करें।

वेबहुक (notify_url)

लिंक का भुगतान होने पर हम link_code, client_ref, amount, currency, status=success, paid_at और sign (वही हस्ताक्षर, API Secret) JSON के रूप में notify_url पर POST करते हैं। कोई भी HTTP 2xx प्राप्त मान लिया जाता है। विफल डिलीवरी v3 कॉलबैक की तरह फिर भेजी जाती हैं।

HTTP / त्रुटिअर्थ
401 missing_api_key / invalid_api_key / invalid_signatureप्रमाणीकरण विफल रहा
403 account_suspended / ip_not_allowedखाता निलंबित या IP की अनुमति नहीं है
404 not_foundआपके अकाउंट पर ऐसा कोई लिंक नहीं है
405 method_not_allowedगलत HTTP मेथड
409 duplicate_client_refclient_ref पहले किसी दूसरी राशि के साथ इस्तेमाल हो चुका है
422 invalid_amount / invalid_notify_url / method_not_allowed …वैलिडेशन विफल, संदेश देखें
502 gateway_errorकोई पेमेंट चैनल उपलब्ध नहीं