Fast Kwik

FastKwik 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 the checkout host; your site only creates the payment and verifies status.

Hosts

  • API / dashboard: https://fastkwik.online · https://fastkwik.info
  • Checkout / payment_url: https://pay.fastkwik.online (example https://pay.fastkwik.online/pay/{site}/{reference})
  • Samples below use the API host you opened (https://fastkwik.online). Always send customers to the returned payment_url.

Download setup pack — README + SecurePayClient.php + config + samples (ZIP when available, else one Markdown file). Paste your API key on your site, set Callback URL on the API page (and Allowed hosts if needed), then create payments via API. Pro: customize checkout colors per site on the API page.

How it works

  1. Register → Methods: add accounts + tick Activate for API on at least one method.
  2. API: site name + Callback URL on your website (https) + support number → create API key. Copy the key once.
  3. On your site server: paste API base https://fastkwik.online + full API key + phone. Keep the key off the browser.
  4. POST https://fastkwik.online/api/v1/payments → redirect customer to payment_url (always on https://pay.fastkwik.online).
  5. On return (?ref=): GET /api/v1/payments/{ref} (or verify) → credit only if status === "captured".

Two hosts (do not mix)

HostUse forDo not use for
https://fastkwik.online API calls, dashboard, webhooks, docs, API keys Opening the customer QR page manually with a wrong path
https://pay.fastkwik.online Customer checkout / QR (payment_url) API base URL, callback URL, or webhook URL on your site

If https://pay.fastkwik.online shows “page not found”, the checkout subdomain is empty on the server — it must serve the same FastKwik app as https://fastkwik.online (see deploy/PAY.md).

Setup on your own website (EN + HI)

English checklist

  1. Hub base URL (API): https://fastkwik.online — put this in SECURE_PAY_BASE.
  2. API key from API (format ap_live_PUBLIC.SECRET) — server only.
  3. Callback URL on the API page = your HTTPS return script, e.g. https://yoursite.com/secure_pay_return.
  4. Support phone = same number you show customers / paste in your admin.
  5. Create payment from your server → redirect to data.payment_url (checkout host https://pay.fastkwik.online).
  6. Return page: read ?ref=, call status API, credit only when captured.
  7. Optional: Download setup pack (client + examples).

Hindi checklist

  1. API base: https://fastkwik.online — yeh SECURE_PAY_BASE mein dalein (pay subdomain nahi).
  2. API se poori key copy karein — sirf server pe rakhein.
  3. API page ka Callback = aapki site ka HTTPS return URL (jaise https://yoursite.com/secure_pay_return).
  4. Support number wahi jo API page par set hai.
  5. Apni site se payment create karke customer ko payment_url pe bhejein (https://pay.fastkwik.online).
  6. Return pe ?ref= se status check — captured par hi balance credit karein.
  7. Zarurat ho to setup pack download karein.

Profile: GET /api/v1/merchant/profile · Methods: GET /api/v1/methods (?all=1 = inactive bhi).

Common mistakes

  • Putting https://pay.fastkwik.online as the API base → signatures / methods fail. Use https://fastkwik.online.
  • Callback URL set to the pay host → customer never returns to your site. Callback = your https URL.
  • return_url host different from API-key callback → invalid_return_url.
  • Exposing the API key in browser JS → rotate the key immediately.
  • Crediting on redirect alone without checking captured → never do this.
  • Checkout 404 on https://pay.fastkwik.online → pay subdomain must point at the same app files as the main host.

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. Checkout shows UTR box + Paste.
bharatpe BharatPay Exact QR + UTR match. Multiple BharatPe accounts. Checkout shows UTR box + Paste.
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://fastkwik.online/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://fastkwik.online/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 (branded path → https://pay.fastkwik.online/pay/{site}/{reference}; custom display name is Pro). Success HTTP status: 201 (idempotent replay may return the same payment).

{
  "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://pay.fastkwik.online/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 (checkout host). When status becomes captured, use redirect_url (or the pay page redirects automatically with ?ref=).

Check / verify

GET https://fastkwik.online/api/v1/payments/{reference}
Authorization: Bearer ap_test_PUBLIC.SECRET

POST https://fastkwik.online/api/v1/payments/{reference}/verify
Authorization: Bearer ap_test_PUBLIC.SECRET
X-Aurapay-Timestamp: 1710000000
X-Aurapay-Signature: HMAC-SHA256(ts + "." + "{}", SECRET)
Content-Type: application/json

{}

# Optional UTR for sms_upi / bharatpe:
# body {"utr":"123456789012"} — sign that exact JSON string

GET is unsigned. POST …/verify must be signed (body {} or {"utr":"…"}). Verify refreshes the provider; with utr it runs UTR match for SMS UPI / BharatPe. Browser pay page also polls and redirects when captured (?ref=). Statuses: pending, captured, failed, cancelled, refunded — credit only on captured.

Merchant profile

GET https://fastkwik.online/api/v1/merchant/profile

Returns this key’s site_name, site_slug, callback_url / return_url, phone, allowed_hosts, premium, badge, pay_base (https://pay.fastkwik.online/pay/), branded_pay_hint, and more.

Checkout branding (Pro)

On API, each connected site can set accent / background / QR card colors. Live preview updates as you pick colors. Saved colors apply on https://pay.fastkwik.online for that site’s payments (site_name / slug-bound). Reset restores FastKwik defaults.

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. Prefer the API host for webhook URLs.

SMS UPI

POST https://fastkwik.online/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://fastkwik.online/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://fastkwik.online';

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', // optional · branded /pay/{site}/{reference}
], 'order-' . time());

if (!empty($created['error'])) {
    http_response_code(400);
    echo json_encode($created);
    exit;
}

// Redirect customer to payment_url (always on the checkout host):
header('Location: ' . ($created['data']['payment_url'] ?? '/'));
exit;

// On return page (?ref=…): credit only if captured — use a separate return.php:
// $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).