API docs
Download setup pack
Secure Payment is a central payment hub for any website.
Add methods and accounts here once — then connect each of your sites through this API.
Customers pay on this platform; your site only redirects and verifies status.
The same API is served on https://secure-payment.online and https://secure-payment.in.net.
Samples below use the host you opened. payment_url stays on that host.
Download setup pack — README + SecurePayClient.php + config + samples
(ZIP when available, else one Markdown file).
Paste your API key on your site, add domain under Merchant → Allowed hosts, then create payments via API.
How it works
- Register → Merchant: activate at least one method for API.
- API: site name + callback URL + support number → create per-site API key (Premium = multiple sites).
- On your site admin: paste base URL + API key + phone, then tick deposit methods.
POST /api/v1/payments→ send customer topayment_url→ on returnGET /api/v1/payments/{ref}and credit only ifcaptured.
Client site admin setup (EN + HI)
English: On any website’s admin (deposit / payment settings), paste:
- Hub base URL:
https://www.secure-payment.in.net - API key from this hub’s API page (one key per site on Premium).
- Support / merchant phone number (same as on API page).
- Enable which hub methods (
upi_qr,sms_upi, …) should appear on that site’s deposit page.
Hindi: Kisi bhi website ke admin mein Secure Payment connect karte waqt:
- Base URL:
https://www.secure-payment.in.net - Is hub ke API page se API key paste karein (Premium mein har site ki alag key).
- Support number wahi jo API page par set kiya.
- Us site ke deposit page par dikhane wale methods enable karein — sirf jo hub par Activate for API hain.
Profile: GET /api/v1/merchant/profile · Methods: GET /api/v1/methods (add ?all=1 to include inactive).
Payment methods (hub)
Enable / rename in admin. Users configure their own accounts under Merchant (optional Min/Max ₹ per account — only matching accounts are used, randomly if several match). Pass provider (or provider_code) when creating a payment. Paytm / Razorpay are not merchant deposit methods via this API.
| Code | Method | Notes |
|---|---|---|
upi_qr |
UPI Pay | Auto UPI — exact-amount QR. Multiple VPAs, random pick. |
sms_upi |
SMS UPI | Phone SMS forwarder verifies credit. Per-account webhook secret. |
bharatpe |
BharatPay | Exact QR + UTR match. Multiple BharatPe accounts. |
heleket |
Heleket Crypto | Crypto invoice + webhook / poll verify. |
manual_upi |
Manual UPI | QR shown; admin marks paid. |
manual_bank |
Bank transfer | Bank details shown; admin marks paid. |
manual_crypto |
Crypto wallet | Wallet shown; admin marks paid. |
GET https://www.secure-payment.in.net/api/v1/methods Authorization: Bearer ap_test_PUBLIC.SECRET
{
"data": {
"default": "sms_upi",
"methods": [
{
"code": "sms_upi",
"label": "SMS UPI",
"description": "…",
"configured": true,
"activated": true,
"accounts": 1,
"default": true
}
]
}
}
Authentication
Authorization: Bearer ap_test_PUBLICID.SECRET # or ap_live_PUBLICID.SECRET (hub mode)
Merchant API POSTs only (/api/v1/payments and …/verify) also need:
X-Aurapay-Timestamp: <unix seconds> X-Aurapay-Signature: HMAC-SHA256(timestamp + "." + raw_body, SECRET) Content-Type: application/json
Signature window ±300 seconds. SECRET is the part after the dot in your API key.
Optional on create: Idempotency-Key: unique-order-id.
Webhooks (/api/v1/webhooks/*) do not use these Aurapay headers.
Create payment
POST https://www.secure-payment.in.net/api/v1/payments
Authorization: Bearer ap_test_PUBLIC.SECRET
X-Aurapay-Timestamp: 1710000000
X-Aurapay-Signature: <hmac>
Idempotency-Key: order-14
Content-Type: application/json
{
"amount": "99.00",
"note": "Order 14",
"provider": "sms_upi",
"return_url": "https://yoursite.com/secure_pay_return",
"site_name": "yoursite.com"
}
amount = rupees. provider / return_url optional (defaults from merchant / API key).
return_url host must match this key’s callback or an Allowed site host.
site_name / site / website optional (Premium brand → /pay/{site}/{reference}).
Success HTTP status: 201.
{
"data": {
"reference": "…",
"status": "pending",
"amount": "99.00",
"payable": "99.00",
"currency": "INR",
"provider": "sms_upi",
"provider_payment_id": null,
"verified_at": null,
"payment_url": "https://www.secure-payment.in.net/pay/yoursite/…",
"site": "yoursite.com",
"site_slug": "yoursite",
"return_url": "https://yoursite.com/secure_pay_return",
"redirect_url": null
}
}
Send the customer to payment_url. When status becomes captured, use redirect_url (or the pay page redirects automatically with ?ref=).
Check / verify
GET https://www.secure-payment.in.net/api/v1/payments/{reference}
POST https://www.secure-payment.in.net/api/v1/payments/{reference}/verify
verify refreshes the payment’s provider (SMS UPI, BharatPe, Heleket, etc.).
Browser pay page also polls and redirects when captured.
Statuses: pending, captured, failed, cancelled, refunded — credit only on captured.
Merchant profile
GET https://www.secure-payment.in.net/api/v1/merchant/profile
Returns this key’s site_name, site_slug, callback_url / return_url,
phone, allowed_hosts, premium, badge, pay_base, branded_pay_hint, and more.
Return to your site (safe flow)
1. Customer lands on https://yoursite.com/secure_pay_return?ref=REFERENCE 2. Your backend: GET /api/v1/payments/REFERENCE (or POST …/verify) 3. Credit balance only if data.status === "captured" Never trust a browser ?success= flag.
Webhooks
No Bearer API key. Provider secret / signature only.
SMS UPI
POST https://www.secure-payment.in.net/api/v1/webhooks/sms_upi
X-Webhook-Secret: <account secret>
Content-Type: application/json
{"message":"…credit SMS…"}
# also accepted: {"text":"%text%","from":"%from%"}
Success: {"ok":true,"message":"…"}. Bad secret: HTTP 400 {"ok":false,…}. Duplicate events return 200 and do not capture twice.
Heleket
POST https://www.secure-payment.in.net/api/v1/webhooks/heleket SIGN: md5(base64(rawBody) + api_key)
PHP helper (any site)
<?php
// Use on ANY site (shops, apps, portals). Keep the key on the server only.
$apiKey = getenv('SECURE_PAY_KEY'); // ap_test_PUBLICID.SECRET or ap_live_…
$secret = explode('.', $apiKey, 2)[1] ?? '';
$base = 'https://www.secure-payment.in.net';
function secure_pay(string $method, string $path, ?array $body = null, ?string $idem = null): array {
global $apiKey, $secret, $base;
$raw = $body === null ? '' : json_encode($body, JSON_UNESCAPED_SLASHES);
$headers = [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
'Accept: application/json',
];
if ($method === 'POST') {
$ts = (string) time();
// Must match hub: HMAC-SHA256(timestamp + "." + raw_body, SECRET)
$headers[] = 'X-Aurapay-Timestamp: ' . $ts;
$headers[] = 'X-Aurapay-Signature: ' . hash_hmac('sha256', $ts . '.' . $raw, $secret);
if ($idem) {
$headers[] = 'Idempotency-Key: ' . $idem;
}
}
$ch = curl_init($base . $path);
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => $method === 'POST' ? $raw : null,
CURLOPT_TIMEOUT => 30,
]);
$res = json_decode((string) curl_exec($ch), true);
return is_array($res) ? $res : [];
}
// List methods activated on this hub account
$methods = secure_pay('GET', '/api/v1/methods');
// Create — choose provider per checkout (HTTP 201)
$created = secure_pay('POST', '/api/v1/payments', [
'amount' => '99.00',
'note' => 'Deposit',
'provider' => 'sms_upi', // upi_qr | sms_upi | bharatpe | heleket | manual_*
'return_url' => 'https://yoursite.com/secure_pay_return',
'site_name' => 'yoursite.com', // Premium → /pay/{site}/{reference}
], 'order-' . time());
// Redirect customer:
header('Location: ' . ($created['data']['payment_url'] ?? '/'));
// On return (?ref=…): credit only if captured
$ref = $_GET['ref'] ?? '';
$check = secure_pay('GET', '/api/v1/payments/' . rawurlencode($ref));
// if (($check['data']['status'] ?? '') === 'captured') { /* credit */ }
Errors
Merchant API: {"error":{"code":"…","message":"…"}} —
401 unauthorized / bad_signature ·
403 merchant_disabled / plan_required ·
404 not_found / unknown_provider ·
422 invalid_amount / invalid_provider / invalid_return_url / payment_rejected ·
429 rate_limited.
Webhooks use {"ok":false,"message":"…"} on failure (HTTP 400).