Secure Payment
Sign in Register

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

  1. Register → Merchant: activate at least one method for API.
  2. API: site name + callback URL + support number → create per-site API key (Premium = multiple sites).
  3. On your site admin: paste base URL + API key + phone, then tick deposit methods.
  4. POST /api/v1/payments → send customer to payment_url → on return GET /api/v1/payments/{ref} and credit only if captured.

Client site admin setup (EN + HI)

English: On any website’s admin (deposit / payment settings), paste:

  1. Hub base URL: https://secure-payment.in.net
  2. API key from this hub’s API page (one key per site on Premium).
  3. Support / merchant phone number (same as on API page).
  4. 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:

  1. Base URL: https://secure-payment.in.net
  2. Is hub ke API page se API key paste karein (Premium mein har site ki alag key).
  3. Support number wahi jo API page par set kiya.
  4. 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.

CodeMethodNotes
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://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://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://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://secure-payment.in.net/api/v1/payments/{reference}
POST https://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://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://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://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://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).