REDDYPAY INR API
पूरा मर्चेंट इंटीग्रेशन डॉक्यूमेंटेशन
सभी एंडपॉइंट के तहत लाइव https://www.reddypay.live/api/v3. अनुरोध और जवाब का फ़ॉर्मेट, हस्ताक्षर (mchKey / mchSecret के साथ MD5 UPPERCASE) और कॉलबैक आम v3 गेटवे विनिर्देश के अनुसार हैं, इसलिए base URL, Merchant ID और कुंजियाँ बदलने के बाद मौजूदा v3 इंटीग्रेशन चलता है। हर जवाब में हमारा अपना होस्टेड पेमेंट URL होता है — आपके ग्राहक को कभी प्रोवाइडर के पेज का पता नहीं दिखता।
आपके API क्रेडेंशियल
इन्हें सुरक्षित रखें। पे-इन में API Key, पे-आउट में API Secret इस्तेमाल होता है।
उदाहरणों में अपना Merchant ID और keys देखने के लिए साइन इन करें। साइन इन
समर्थित भुगतान विधियां
INRUPI
Pay-in: tradeType INRUPI · Pay-out: payType upi
IMPS / NEFT
Pay-out: payType bank (account number + IFSC)
usdt
Pay-in: tradeType usdt (TRC20) · Pay-out: payType usdt
API संदर्भ
सभी एंडपॉइंट
ग्लोबल नियम
- 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)
क्विक स्टार्ट
- ऊपर के बॉक्स से अपना Merchant ID, API Key (mchKey) और API Secret (mchSecret) कॉपी करें।
- Basic Information में अपना कॉलबैक URL सहेजें और “Test endpoint” दबाएँ — हम एक हस्ताक्षरित टेस्ट अनुरोध भेजते हैं।
- POST /payin से ऑर्डर बनाएँ और अपने ग्राहक को लौटाए गए pay_url पर भेजें।
- हमारे कॉलबैक की प्रतीक्षा करें (टेक्स्ट success से जवाब दें) और /check-order-status को विकल्प के रूप में इस्तेमाल करें।
आपकी सीमाएँ
स्थिति मान
| स्थिति | अर्थ |
|---|---|
pending | Waiting for the customer. A payment made after expiry is still credited, and you get the success callback. |
success | Paid and credited to your wallet (netAmount). Final. |
failed | भुगतान विफल या अस्वीकार कर दिया गया। अंतिम जब तक ग्राहक बाद में भुगतान नहीं करता। |
expired | ग्राहक ने समय पर भुगतान नहीं किया (डिफ़ॉल्ट रूप से 30 मिनट)। |
processing | Payouts 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.0 | First 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.x | Legacy payment-link API (/api/v1/create-link.php, /link-status.php) stays available and unchanged; optional currency / trade_type were added. |
डिपॉज़िट ऑर्डर बनाता है। जवाब में हमारा होस्टेड चेकआउट पता pay_url में होता है: ग्राहक को वहाँ रीडायरेक्ट करें (या नए टैब / iframe में खोलें)। ग्राहक हमारे डोमेन पर भुगतान करता है; भुगतान पुष्ट होने पर आपको कॉलबैक मिलता है।
| Parameter | Type | Required | विवरण |
|---|---|---|---|
mchId | string | हाँ | Your Merchant ID (also accepted as merchant_id) |
mchOrderNo | string | हाँ | Your own unique order number (1–100 chars: letters, digits and _ - . : # /). Repeating it returns the same order (idempotent). Also accepted as merchant_order_no |
amount | string | हाँ | Order amount in INR, 2 decimals, e.g. "500.00". Limits: see Overview |
tradeType | string | नहीं | INRUPI (default) or usdt. Also accepted as trade_type |
notifyUrl | string | नहीं | URL that receives our callback. Falls back to the callback URL saved in your panel. Also accepted as callback_url |
returnUrl | string | नहीं | Where the customer is sent after paying (also return_url) |
extra | string | नहीं | Free text (max 255 chars) echoed back in queries and callbacks |
sign | string | हाँ | 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¬ifyUrl=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
}
}{
"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
}
}डिपॉज़िट ऑर्डर की मौजूदा स्थिति लौटाता है। mchKey से हस्ताक्षरित होने पर यह आपके pay-in ऑर्डर में देखता है; mchSecret से हस्ताक्षरित होने पर वही endpoint निकासियाँ क्वेरी करता है (Query Pay-out देखें)। इसे कुछ सेकंड में एक बार से ज़्यादा पोल न करें और कॉलबैक को प्राथमिकता दें।
| Parameter | Type | Required | विवरण |
|---|---|---|---|
mchId | string | हाँ | Your Merchant ID (also accepted as merchant_id) |
mchOrderNo | string | नहीं | Your order number (one of mchOrderNo / orderNo is required) |
orderNo | string | नहीं | Our order number returned by /payin |
sign | string | हाँ | 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 | expiredconst 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 | expiredimport 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"
}
}| स्थिति | अर्थ |
|---|---|
pending | Waiting for the customer. A payment made after expiry is still credited, and you get the success callback. |
success | Paid and credited to your wallet (netAmount). Final. |
failed | भुगतान विफल या अस्वीकार कर दिया गया। अंतिम जब तक ग्राहक बाद में भुगतान नहीं करता। |
expired | ग्राहक ने समय पर भुगतान नहीं किया (डिफ़ॉल्ट रूप से 30 मिनट)। |
processing | Payouts only: approved, the transfer is being made. |
निकासी बनाता है। लाभार्थी को ठीक amount मिलता है; हमारा पे-आउट शुल्क ऊपर से लगता है और राशि के साथ आपके उपलब्ध बैलेंस से डेबिट होता है (पेआउट के भुगतान या अस्वीकार होने तक रोका जाता है)। सीमाएँ और आपका बैलेंस पैनल की तरह जाँचे जाते हैं।
| Parameter | Type | Required | विवरण |
|---|---|---|---|
mchId | string | हाँ | Your Merchant ID (also accepted as merchant_id) |
mchOrderNo | string | हाँ | Your unique payout number (idempotent, same rules as pay-in) |
amount | string | हाँ | Amount the beneficiary receives, in INR with 2 decimals. Our fee is charged on top |
payType | string | नहीं | bank, upi or usdt. Detected from the destination fields when omitted |
bankCode | string | नहीं | Bank name exactly as in the Bank Codes tab (bank payouts) |
accountName | string | नहीं | खाता धारक का नाम (बैंक भुगतान) |
accountNumber | string | नहीं | Bank account number, 6–20 digits (bank payouts) |
ifsc | string | नहीं | IFSC code, e.g. HDFC0001234 (bank payouts) |
upiId | string | नहीं | UPI ID such as name@bank (UPI payouts) |
usdtAddress | string | नहीं | TRC20 address starting with T (USDT payouts, needs USDT enabled for your account) |
sign | string | हाँ | 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
}
}Query Pay-in जैसा ही endpoint, mchSecret से हस्ताक्षरित: तब ऑर्डर आपकी निकासियों में mchOrderNo (आपका पेआउट नंबर) या orderNo (हमारा नंबर) से खोजा जाता है।
| Parameter | Type | Required | विवरण |
|---|---|---|---|
mchId | string | हाँ | Your Merchant ID (also accepted as merchant_id) |
mchOrderNo | string | नहीं | Your order number (one of mchOrderNo / orderNo is required) |
orderNo | string | नहीं | Our order number returned by /payin |
sign | string | हाँ | 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 | अस्वीकार या रद्द हुआ, रोकी गई राशि और शुल्क आपके बैलेंस में लौट गए। अंतिम। |
आपका वॉलेट लौटाता है: balance (= उपलब्ध, जो आप निकाल सकते हैं), frozen (लंबित निकासियों के लिए रोका गया) और total।
| Parameter | Type | Required | विवरण |
|---|---|---|---|
mchId | string | हाँ | Your Merchant ID (also accepted as merchant_id) |
sign | string | हाँ | 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 हैश, अपर केस में।
- हस्ताक्षर को छोड़कर अनुरोध के सभी पैरामीटर लें। खाली मान वाले पैरामीटर छोड़ दिए जाते हैं।
- उन्हें पैरामीटर के नाम से, सादे बाइट क्रम में सजाएँ (mchId, mchOrderNo से पहले आता है; अपर-केस अक्षर लोअर-केस से पहले)।
- हर एक को name=value लिखें और & से जोड़ें। मान URL-एन्कोड नहीं होते। राशियाँ दो दशमलव वाले स्ट्रिंग के रूप में भेजें।
- &key= लगाकर अपनी कुंजी जोड़ें: pay-in और कॉलबैक के लिए mchKey, पे-आउट और बैलेंस के लिए mchSecret।
- उस पाठ का MD5 हैश लें और इसे बड़े अक्षर में लिखें। वह हस्ताक्षर है।
amount=500.00&mchId=123456789&mchOrderNo=ORDER-1001¬ifyUrl=https://merchant.example.com/webhook/reddypay&tradeType=INRUPI&key=TEST_KEY_0123456789abcdef
618EB8435DBA875EB138FF5657E8FA6Ffunction 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 के दायरे में है।
| फ़ील्ड | विवरण |
|---|---|
mchId | Your Merchant ID (alias merchant_id) |
mchOrderNo | Your order number (alias merchant_order_no) |
orderNo | Our order number (alias gateway_order_no) |
amount | Order amount |
paidAmount | Amount actually paid |
fee | Our fee |
netAmount | Credited to your wallet (amount − fee) |
tradeType | INRUPI | usdt |
status | success | failed |
utr | Bank reference (UTR), when known |
payTime | Payment time, ISO-8601 IST |
extra | आपने भेजा गया अतिरिक्त मूल्य |
usdtAmount | USDT orders only: exact USDT amount |
sign | Signature (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"
}जाँचें और स्वीकार करें
- अपने mchKey से sign को छोड़कर सभी प्राप्त फ़ील्ड पर sign दोबारा निकालें (Signature देखें) और constant time में तुलना करें। अलग निकले तो अनुरोध अस्वीकार करें।
- इडेम्पोटेंट रहें: वही कॉलबैक दोबारा आ सकता है (रीट्राई, हाथ से दोबारा भेजना)। अपना ऑर्डर खोजने के लिए mchOrderNo / orderNo इस्तेमाल करें और जो स्थिति आप पहले प्रोसेस कर चुके हैं उसे अनदेखा करें।
- सामान देने से पहले जाँचें कि status = success है और paidAmount आपकी अपेक्षा से मेल खाता है। संदेह हो तो /check-order-status से पुष्टि करें।
- सादे टेक्स्ट 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 retryconst 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 retryimport 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¬ifyUrl=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 | |
|---|---|---|
| 1 | State Bank of India (SBI) | |
| 2 | Punjab National Bank (PNB) | |
| 3 | Bank of Baroda | |
| 4 | Canara Bank | |
| 5 | Union Bank of India | |
| 6 | Bank of India | |
| 7 | Indian Bank | |
| 8 | Central Bank of India | |
| 9 | Indian Overseas Bank | |
| 10 | UCO Bank | |
| 11 | Bank of Maharashtra | |
| 12 | Punjab & Sind Bank | |
| 13 | HDFC Bank | |
| 14 | ICICI Bank | |
| 15 | Axis Bank | |
| 16 | Kotak Mahindra Bank | |
| 17 | IndusInd Bank | |
| 18 | Yes Bank | |
| 19 | IDFC FIRST Bank | |
| 20 | Federal Bank | |
| 21 | South Indian Bank | |
| 22 | RBL Bank | |
| 23 | Karur Vysya Bank | |
| 24 | Karnataka Bank | |
| 25 | City Union Bank | |
| 26 | Tamilnad Mercantile Bank | |
| 27 | DCB Bank | |
| 28 | Bandhan Bank | |
| 29 | CSB Bank | |
| 30 | Dhanlaxmi Bank | |
| 31 | Jammu & Kashmir Bank | |
| 32 | AU Small Finance Bank | |
| 33 | Equitas Small Finance Bank | |
| 34 | Ujjivan Small Finance Bank | |
| 35 | ESAF Small Finance Bank | |
| 36 | Suryoday Small Finance Bank | |
| 37 | Jana Small Finance Bank | |
| 38 | North East Small Finance Bank | |
| 39 | Unity Small Finance Bank | |
| 40 | Utkarsh Small Finance Bank | |
| 41 | Airtel Payments Bank | |
| 42 | India Post Payments Bank | |
| 43 | Fino Payments Bank | |
| 44 | Paytm Payments Bank | |
| 45 | NSDL Payments Bank | |
| 46 | Standard Chartered Bank | |
| 47 | HSBC Bank | |
| 48 | Citibank | |
| 49 | Deutsche Bank | |
| 50 | Other / 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"
}| HTTP | error | अर्थ |
|---|---|---|
| 400 | invalid_request | mchId or sign is missing, or the body could not be read |
| 401 | invalid_signature | Unknown merchant ID or wrong signature (the same answer for both, on purpose) |
| 401 | wrong_key_type | Signed with the wrong key: pay-in endpoints need mchKey, payout and balance need mchSecret |
| 403 | account_suspended | मर्चेंट खाता निलंबित है |
| 403 | ip_not_allowed | Your server IP is not on the IP allow-list of the account |
| 403 | ip_whitelist_required | Payouts through the API need an IP allow-list |
| 404 | order_not_found | No order with that mchOrderNo / orderNo on your account |
| 405 | use_post | Use POST |
| 409 | duplicate_order | This mchOrderNo was already used with a different amount or trade type |
| 413 | payload_too_large | Body larger than 64 KB |
| 422 | missing_param / invalid_amount / invalid_mch_order_no | एक पैरामीटर गायब है या गलत है, संदेश देखें |
| 422 | amount_range | Amount outside your limits |
| 422 | method_not_allowed | INR or USDT is not enabled for your account |
| 422 | invalid_trade_type / invalid_pay_type / invalid_url | Unsupported value |
| 422 | insufficient_balance / daily_limit / bank_invalid / ifsc_invalid / upi_invalid / address_invalid | Payout rejected, see message (nothing was debited) |
| 429 | rate_limited / too_many_failures | Too many requests or failed signatures. Wait for Retry-After seconds |
| 500 | server_error | Our side failed; retry with the same mchOrderNo (safe, idempotent) |
| 503 | provider_unavailable / maintenance / rate_unavailable | No 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 इस्तेमाल करे।
| Parameter | Type | Required | विवरण |
|---|---|---|---|
api_key | string | हाँ | आपकी API Key, या इसे X-Api-Key हेडर में भेजें |
amount | string | हाँ | दशमलव संख्या, अधिकतम 2 अंक, जैसे 500.00 |
note | string | नहीं | सादा टेक्स्ट, अधिकतम 255 अक्षर |
client_ref | string | नहीं | आपका अपना ऑर्डर आईडी, अधिकतम 120 अक्षर। इसे दोहराने पर वही लिंक लौटता है (इडेम्पोटेंट); स्टेटस और वेबहुक में वापस भेजा जाता है |
notify_url | string | नहीं | आपका वेबहुक URL |
return_url | string | नहीं | ग्राहक रिटर्न URL |
currency | string | नहीं | INR (डिफ़ॉल्ट) या USDT |
sign | string | हाँ | sign को छोड़कर सभी पैरामीटर का अपरकेस MD5, कुंजी के क्रम में, खाली मान छोड़े हुए, + &key=<API Secret> |
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"
}
}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_ref | client_ref पहले किसी दूसरी राशि के साथ इस्तेमाल हो चुका है |
422 invalid_amount / invalid_notify_url / method_not_allowed … | वैलिडेशन विफल, संदेश देखें |
502 gateway_error | कोई पेमेंट चैनल उपलब्ध नहीं |