Welcome to the WatchPay Open Gateway API documentation. This document covers both PayIn (Collection) and PayOut (Disbursement / Transfer on behalf) integrations.
80010001e10adc3949ba59abbe56e057f20f883e| Interface Service | Method | API Address | Description |
|---|---|---|---|
| PayIn (Collection) | POST | /pay/web |
Place transaction order, redirect or return JSON payment link |
| PayOut (Disbursement) | POST | /pay/transfer |
Transfer funds to customer bank account or UPI ID |
| Order Inquiry | POST | /query/order |
Query PayIn collection transaction status |
| Payout Inquiry | POST | /query/transfer |
Query payout disbursement status |
| Balance Inquiry | POST | /query/balance |
Check available, total, and frozen merchant balances |
To ensure transaction security and prevent parameter tampering, all requests and responses must carry an MD5 signature verified against the merchant's private API secret key.
null or empty string "".sign and sign_type (or signType).key1=val1&key2=val2...&key= followed by your API Secret Key at the end of the string.Test and verify MD5 signature calculations directly in your browser:
Initiates a payment collection request for UPI, QR, or Netbanking payments.
payInfo URL), include version=1.0.version parameter.
| Parameter | Name | Type | Required | Description |
|---|---|---|---|---|
version | Version | String | N | Fixed value 1.0 to return JSON synchronously. |
mch_id | Merchant Code | String | Y | Unique merchant ID allocated by the platform (e.g. 80010001). |
notify_url | Asynchronous URL | String | Y | Webhook notification address initiated after payment completion. |
page_url | Redirect URL | String | N | Frontend redirect address after payment. |
mch_order_no | Merchant Order No | String | Y | Guaranteed unique order ID generated by merchant system. |
channel_code / pay_type | Channel Code | String | Y | Dynamic routing code to select gateway: 101 (WatchPay), 102 (JikPay), 103 (AeroPay), 104 (SunPay), 105 (AllPay), 106 (NikPay). |
trade_amount | Order Amount | String | Y | Transaction amount in INR (e.g. 100.00). |
order_date | Order Time | String | Y | Format: yyyy-MM-dd HH:mm:ss |
bank_code | Bank Code | String | N | Optional. See Indian Bank Codes for online banking. |
goods_name | Goods Name | String | Y | Product name (no more than 50 bytes). |
mch_return_msg | Pass-through Data | String | N | Custom parameters returned untouched in callback. |
sign_type | Signature Method | String | Y | Fixed value: MD5 |
sign | Signature | String | Y | 32-character lowercase MD5 signature. |
{
"respCode": "SUCCESS",
"tradeMsg": "request success",
"tradeResult": "1",
"mchId": "80010001",
"mchOrderNo": "2026090412345",
"oriAmount": "100.00",
"tradeAmount": "100.00",
"orderDate": "2026-09-04 12:34:56",
"orderNo": "ORD2026090403150001",
"payInfo": "http://localhost/pay/uniqueurl?dataIndex=ORD2026090403150001",
"signType": "MD5",
"sign": "4ba90c98783a04d2dff2a032148d6d2b"
}
After customer payment is confirmed, the platform sends a POST request with application/x-www-form-urlencoded parameters to the merchant's notify_url.
success (lowercase). Any other response will cause the platform to retry up to 8 times.
| Parameter | Type | Required | Description |
|---|---|---|---|
tradeResult | String | Y | 1: Payment Successful. |
mchId | String | Y | Merchant ID. |
mchOrderNo | String | Y | Merchant's order ID. |
oriAmount | String | Y | Original order amount uploaded by merchant. |
amount | String | Y | Actual payment amount. |
orderDate | String | Y | Order timestamp. |
orderNo | String | Y | Platform payment order number. |
merRetMsg | String | N | Pass-through parameters sent by merchant. |
signType | String | Y | MD5 |
sign | String | Y | MD5 signature for notification verification. |
Submits a payout request to disburse funds to a customer's Indian bank account or UPI ID.
| Parameter | Name | Type | Required | Description |
|---|---|---|---|---|
mch_id | Merchant Code | String | Y | Merchant ID. |
mch_transferId | Merchant Transfer ID | String | Y | Unique serial number for payout. |
transfer_amount | Transfer Amount | String | Y | Amount to transfer in INR. |
apply_date | Order Time | String | Y | Format: yyyy-MM-dd HH:mm:ss |
bank_code | Bank Code | String | Y | IDPT0001 (or ABB or UPI). |
receive_name | Beneficiary Name | String | Y | Account holder's name. |
receive_account | Beneficiary Account | String | Y | Bank account number or UPI ID. |
remark | IFSC / Remark | String | Y | Required for India: Bank IFSC code (e.g. HDFC0001234). |
back_url | Callback Address | String | N | Asynchronous payout notification URL. |
sign_type | Signature Method | String | Y | MD5 |
sign | Signature | String | Y | MD5 signature. |
{
"respCode": "SUCCESS",
"errorMsg": null,
"signType": "MD5",
"sign": "53d5cee43aa98c4f91b8b7bc7ea67d90",
"mchId": "80010001",
"merTransferId": "TRF_1788472021",
"transferAmount": "100.00",
"applyDate": "2026-09-04 03:15:00",
"tradeNo": "SER2026090403150002",
"tradeResult": "0"
}
tradeResult codes: 0 = Application received / in progress, 1 = Successful, 2 = Failed.
When the payout status changes (funds credited or failed), the platform notifies the merchant's back_url.
success to stop retries.{
"tradeResult": "1",
"mchId": "80010001",
"merTransferId": "TRF_1788472021",
"transferAmount": "100.00",
"applyDate": "2026-09-04 03:15:00",
"tradeNo": "SER2026090403150002",
"signType": "MD5",
"sign": "d95e221325baaaf16396f323f40b7627"
}
Check the status of any payout disbursement if notification is delayed.
| Parameter | Type | Required | Description |
|---|---|---|---|
mch_id | String | Y | Merchant ID. |
mch_transferId | String | Y | Merchant's transfer serial number. |
sign_type | String | Y | MD5 |
sign | String | Y | MD5 signature. |
{
"mchId": "80010001",
"mchTransferId": "TRF_1788472021",
"transferAmount": 100,
"applyDate": "2026-09-04 03:15:00",
"respCode": "SUCCESS",
"tradeResult": 1,
"tradeNo": "SER2026090403150002",
"signType": "MD5",
"sign": "d95e221325baaaf16396f323f40b7627",
"errorMsg": null
}
Check the status of any PayIn collection transaction.
{
"respCode": "SUCCESS",
"tradeResult": "1",
"mchId": "80010001",
"mchOrderNo": "WP_TEST_1788472021",
"tradeAmount": "250.00",
"orderNo": "ORD202609032347019555",
"orderDate": "2026-09-04 03:17:01",
"signType": "MD5",
"errorMsg": null,
"sign": "a12498ab0da5bef88e3ba8c46a6b6b76"
}
Fetch real-time available funds, total funds, and frozen funds.
{
"mchId": "80010001",
"amount": 50010.00,
"frozenAmount": 0.00,
"availableAmount": 50010.00,
"respCode": "SUCCESS",
"signType": "MD5",
"errorMsg": null,
"sign": "b2c5f26d5bc474279e08faba8dc0348e"
}
Use these bank codes when initiating online banking or payout transactions.
| Bank Code | Bank Name | Short Name |
|---|---|---|
IDPT0001 | Canara Bank | CANARA |
IDPT0002 | DCB Bank | DCB |
IDPT0003 | Federal Bank | FED |
IDPT0004 | HDFC Bank | HDFC |
IDPT0005 | Punjab National Bank | PNB |
IDPT0006 | Indian Bank | IDBI |
IDPT0007 | ICICI Bank | ICICI |
IDPT0008 | State Bank of India | SBI |
IDPT0009 | Axis Bank | AXIS |
IDPT0010 | Kotak Mahindra Bank | KOTAK |
UPI | Direct UPI / VPA Transfer | UPI |
Copy-pasteable code examples for placing orders and verifying callbacks.
<?php
function generateSign($params, $secretKey) {
ksort($params);
$pairs = [];
foreach ($params as $k => $v) {
if ($k === 'sign' || $k === 'sign_type' || $v === '' || $v === null) continue;
$pairs[] = $k . '=' . $v;
}
return md5(implode('&', $pairs) . '&key=' . $secretKey);
}
// 1. PayIn Order Request
$mchId = '80010001';
$secretKey = 'e10adc3949ba59abbe56e057f20f883e';
$data = [
'version' => '1.0',
'mch_id' => $mchId,
'mch_order_no' => 'ORDER_' . time(),
'trade_amount' => '500.00',
'pay_type' => '101',
'goods_name' => 'Coins',
'order_date' => date('Y-m-d H:i:s'),
'notify_url' => 'https://yourdomain.com/payin_webhook.php',
'sign_type' => 'MD5'
];
$data['sign'] = generateSign($data, $secretKey);
$ch = curl_init('http://localhost/pay/web');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
echo "Payment Link: " . $result['payInfo'];
?>
import requests
import hashlib
import time
from datetime import datetime
def generate_sign(params, secret_key):
filtered = {k: str(v) for k, v in params.items() if k not in ['sign', 'sign_type'] and v != ''}
sorted_pairs = [f"{k}={filtered[k]}" for k in sorted(filtered.keys())]
query_str = "&".join(sorted_pairs) + f"&key={secret_key}"
return hashlib.md5(query_str.encode('utf-8')).hexdigest()
params = {
'version': '1.0',
'mch_id': '80010001',
'mch_order_no': f"PY_ORD_{int(time.time())}",
'trade_amount': '500.00',
'pay_type': '101',
'goods_name': 'Subscription',
'order_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'notify_url': 'https://yourdomain.com/webhook',
'sign_type': 'MD5'
}
params['sign'] = generate_sign(params, 'e10adc3949ba59abbe56e057f20f883e')
res = requests.post('http://localhost/pay/web', data=params)
print("Response:", res.json())
const axios = require('axios');
const crypto = require('crypto');
function generateSign(params, secretKey) {
const filteredKeys = Object.keys(params)
.filter(k => k !== 'sign' && k !== 'sign_type' && params[k] !== '' && params[k] !== null)
.sort();
const queryStr = filteredKeys.map(k => `${k}=${params[k]}`).join('&') + `&key=${secretKey}`;
return crypto.createHash('md5').update(queryStr, 'utf8').digest('hex');
}
const payload = {
version: '1.0',
mch_id: '80010001',
mch_order_no: 'NODE_' + Date.now(),
trade_amount: '300.00',
pay_type: '101',
goods_name: 'Diamonds',
order_date: new Date().toISOString().replace('T', ' ').substring(0, 19),
notify_url: 'https://yourdomain.com/webhook',
sign_type: 'MD5'
};
payload.sign = generateSign(payload, 'e10adc3949ba59abbe56e057f20f883e');
axios.post('http://localhost/pay/web', new URLSearchParams(payload))
.then(res => console.log('Payment URL:', res.data.payInfo));