Fast Kwik

API docs

Integration guide · webhooks · copy-paste samples

Download pack

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.com · https://fastkwik.online · https://fastkwik.info
  • Checkout / payment_url: https://pay.fastkwik.info (example https://pay.fastkwik.info/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.info).
  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.info Customer checkout / QR (payment_url) API base URL, callback URL, or webhook URL on your site

If https://pay.fastkwik.info 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. On the hub: Methods → add at least one method + Activate for API (Heleket / UPI / etc. live here — not on yoursite.com).
  3. API key from API (format ap_yoursite_PUBLIC.SECRET) — server only.
  4. Callback URL on the API page = your HTTPS return script, e.g. https://yoursite.com/secure_pay_return.
  5. Support phone = same number you show customers / paste in your admin.
  6. Create payment from your server with a provider code → redirect to data.payment_url (checkout host https://pay.fastkwik.info).
  7. Return page: read ?ref=, call status API, credit only when captured.
  8. Optional: Download setup pack (client + examples).

Hindi checklist

  1. API base: https://fastkwik.online — yeh SECURE_PAY_BASE mein dalein (pay subdomain nahi).
  2. Hub pe Methods configure + Activate for API (Heleket HTML verify bhi yahi — yoursite.com pe nahi).
  3. API se poori key copy karein (ap_sitename_… — site name se shuru) — sirf server pe rakhein.
  4. API page ka Callback = aapki site ka HTTPS return URL (jaise https://yoursite.com/secure_pay_return).
  5. Support number wahi jo API page par set hai.
  6. Apni site se provider ke saath payment create karke customer ko payment_url pe bhejein (https://pay.fastkwik.info).
  7. Return pe ?ref= se status check — captured par hi balance credit karein.
  8. 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.info 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.info → pay subdomain must point at the same app files as the main host.
  • Heleket Project URL = yoursite.com → wrong. Use API host https://fastkwik.online and upload HTML on hub Methods.
  • Method saved but API says invalid_provider → tick Activate for API and Save.

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.

IconCodeMethodNotes
paytm_business PayTM Business Paytm Business exact-amount UPI QR (mode 01). MID auto-checks amount; checkout UTR box finishes capture (UTR for record). ~5 min → not received if unpaid.
simple_upi Simple UPI UPI ID + SMS forwarder. Captured only when checkout UTR matches SMS UTR + amount.
bharatpe_business BharatPe Business QR like Smile Panel / BharatPe (mode 01, UPI ID + amount + merchant payee name — no ref/note in QR). UTR match on merchant list. Site brand only above QR.
fampay FamPay FamPay UPI QR (mode 01). Customer submits UTR; FastKwik matches FamApp Gmail alert (UTR + amount).
heleket_crypto Heleket Crypto Opens Heleket invoice (no UPI QR). Captured via webhook + status re-check. Domain verify on FastKwik host.
manual_upi Manual UPI Static UPI QR/ID. You Approve after checking the credit.
manual_bank Bank transfer Bank details on pay page. You Approve after bank credit.
manual_crypto Crypto wallet Wallet/network shown. You Approve after on-chain confirm.
GET https://fastkwik.online/api/v1/methods
Authorization: Bearer ap_yoursite_PUBLIC.SECRET
{
  "data": {
    "default": "simple_upi",
    "icons_base": "https://fastkwik.online/assets/icons/upi/",
    "methods": [
      {
        "code": "simple_upi",
        "label": "Simple UPI",
        "description": "…",
        "configured": true,
        "activated": true,
        "accounts": 1,
        "default": true,
        "icon": "/assets/icons/upi/simple-upi.png",
        "icon_url": "https://fastkwik.online/assets/icons/upi/simple-upi.png"
      }
    ]
  }
}

Method icons on your site: each method returns the same brand image used on the hub Methods page. Use icon_url (absolute) in your deposit UI — hotlink from this API host, or download once and host yourself. Create/verify payment responses also include provider_icon_url for the chosen method.

<?php
$methods = secure_pay('GET', '/api/v1/methods');
foreach (($methods['data']['methods'] ?? []) as $m) {
    if (empty($m['activated'])) continue;
    $icon = htmlspecialchars((string) ($m['icon_url'] ?? ''), ENT_QUOTES, 'UTF-8');
    $code = htmlspecialchars((string) ($m['code'] ?? ''), ENT_QUOTES, 'UTF-8');
    $label = htmlspecialchars((string) ($m['label'] ?? ''), ENT_QUOTES, 'UTF-8');
    echo '<button type="button" data-provider="' . $code . '">';
    if ($icon !== '') echo '<img src="' . $icon . '" alt="" width="32" height="32"> ';
    echo $label . '</button>';
}

Authentication

Authorization: Bearer ap_yoursite_PUBLIC.SECRET
# starts with your site name from the API page (legacy ap_test_ / ap_live_ still work)

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_yoursite_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": "simple_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.info/pay/{site}/{reference}; custom display name is Pro). Success HTTP status: 201 (idempotent replay may return the same payment).

{
  "data": {
    "reference": "K7M3P9Q2XW",
    "status": "pending",
    "amount": "99.00",
    "payable": "99.00",
    "currency": "INR",
    "provider": "simple_upi",
    "provider_icon": "/assets/icons/upi/simple-upi.png",
    "provider_icon_url": "https://fastkwik.online/assets/icons/upi/simple-upi.png",
    "provider_payment_id": null,
    "utr": null,
    "verified_at": null,
    "payment_url": "https://pay.fastkwik.info/pay/yoursite/K7M3P9Q2XW",
    "site": "yoursite.com",
    "site_slug": "yoursite",
    "return_url": "https://yoursite.com/secure_pay_return",
    "redirect_url": null
  }
}

reference is a 10-character uppercase order id — use the value returned by create (do not invent one). Send the customer to payment_url (checkout host). When status becomes captured, the pay page shows Payment received for about 3–4 seconds, then returns to your site with ?ref=. Your return page should still confirm captured via API before crediting.

Check / verify

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

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

{}

# Optional UTR for simple_upi / bharatpe_business / fampay / paytm_business (exactly 12 digits):
# 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 Simple UPI / BharatPe Business / PayTM Business (checkout UTR) (utr must be exactly 12 digits; Simple UPI captures only when checkout UTR and SMS UTR + amount match). PayTM Business still auto-checks amount via MID before UTR is accepted for record. A UTR already used on any checkout stays blocked for 7 days (“already used”). Browser pay page polls, shows Payment received, waits ~3–4s, then returns (?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.info/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.info 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.

Simple UPI

Setup on Methods → Simple UPI:

  1. Save your UPI ID (no webhook-secret box).
  2. Copy the personal SMS Forwarder Webhook URL (private token is already in the URL).
  3. Paste that full URL into an SMS forwarder app → POST body {"message":"%text%"} (no secret header).
  4. Customer pays on checkout and enters the 12-digit UTR.
  5. Credit SMS must match the same UTR + same amount → status becomes captured (UTR single-use for 7 days).
  6. Checkout shows Payment received for a few seconds, then returns to your site (?ref=).
POST https://fastkwik.online/api/v1/webhooks/simple_upi?token=<from Methods page>
Content-Type: application/json

{"message":"…credit SMS…"}
# also accepted: {"text":"%text%","from":"%from%"}
# Copy the full URL from Methods — do not invent the token.
# Capture rule: checkout UTR + SMS UTR + amount must all match.

Success: {"ok":true,"message":"…"}. Bad / missing token: HTTP 400 {"ok":false,…}. Duplicate events return 200 and do not capture twice. Amount-only match never captures. Legacy path https://fastkwik.online/api/v1/webhooks/sms_upi still works.

Heleket

POST https://fastkwik.online/api/v1/webhooks/heleket_crypto
SIGN: md5(base64(rawBody) + api_key)
Content-Type: application/json

{ …Heleket invoice payload… }

Configure this URL inside Heleket (not on your shop). Header name is SIGN (case-insensitive). Success: HTTP 200 {"ok":true,…}. Bad signature / reject: HTTP 400 {"ok":false,…}. FastKwik re-fetches the invoice from Heleket before marking captured.

Heleket setup (hub + your site)

Domain verification and API keys are configured on this FastKwik hub. Your website only creates payments with "provider":"heleket_crypto" and checks captured.

  1. Heleket dashboard → API key + Merchant UUID → paste under Methods → Heleket.
  2. Copy Webhook URL https://fastkwik.online/api/v1/webhooks/heleket_crypto into Heleket Callback / Webhook settings.
  3. Project URL in Heleket = https://fastkwik.online (API host). Not https://pay.fastkwik.info, not yoursite.com.
  4. Download Heleket’s HTML verification file → upload on Methods → open the published https://…/*.html URL → Verify in Heleket.
  5. Tick Activate for API → Save.
  6. On your site: POST /api/v1/payments with "provider":"heleket_crypto" → redirect to payment_url → customer taps Open Heleket invoice.
  7. Credit only when status is captured (webhook and/or POST …/verify).
{
  "amount": "500.00",
  "note": "Crypto top-up",
  "provider": "heleket_crypto",
  "return_url": "https://yoursite.com/secure_pay_return"
}

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_yoursite_PUBLIC.SECRET (site name prefix)
$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 (includes icon_url per method)
$methods = secure_pay('GET', '/api/v1/methods');
// Example: show the same icons as hub Methods on YOUR site
// foreach (($methods['data']['methods'] ?? []) as $m) {
//     echo '<img src="' . htmlspecialchars($m['icon_url'] ?? '', ENT_QUOTES, 'UTF-8') . '" alt=""> '
//         . htmlspecialchars($m['label'] ?? '', ENT_QUOTES, 'UTF-8');
// }

// Create — choose provider per checkout (HTTP 201)
$created = secure_pay('POST', '/api/v1/payments', [
    'amount' => '99.00',
    'note' => 'Deposit',
    'provider' => 'simple_upi', // paytm_business | simple_upi | bharatpe_business | fampay | heleket_crypto | manual_*
    'return_url' => 'https://yoursite.com/secure_pay_return',
    'site_name' => 'yoursite.com', // optional · branded /pay/{site}/{reference}
], 'order-' . time());
// $created['data']['provider_icon_url'] — same method icon for your UI

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).