API docs
Integration guide · webhooks · copy-paste samples
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(examplehttps://pay.fastkwik.info/pay/{site}/{reference}) - Samples below use the API host you opened (
https://fastkwik.online). Always send customers to the returnedpayment_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
- Register → Methods: add accounts + tick Activate for API on at least one method.
- API: site name + Callback URL on your website (https) + support number → create API key. Copy the key once.
- On your site server: paste API base
https://fastkwik.online+ full API key + phone. Keep the key off the browser. POST https://fastkwik.online/api/v1/payments→ redirect customer topayment_url(always onhttps://pay.fastkwik.info).- On return (
?ref=):GET /api/v1/payments/{ref}(or verify) → credit only ifstatus === "captured".
Two hosts (do not mix)
| Host | Use for | Do 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
- Hub base URL (API):
https://fastkwik.online— put this inSECURE_PAY_BASE. - On the hub: Methods → add at least one method + Activate for API (Heleket / UPI / etc. live here — not on yoursite.com).
- API key from API (format
ap_yoursite_PUBLIC.SECRET) — server only. - Callback URL on the API page = your HTTPS return script, e.g.
https://yoursite.com/secure_pay_return. - Support phone = same number you show customers / paste in your admin.
- Create payment from your server with a
providercode → redirect todata.payment_url(checkout hosthttps://pay.fastkwik.info). - Return page: read
?ref=, call status API, credit only whencaptured. - Optional: Download setup pack (client + examples).
Hindi checklist
- API base:
https://fastkwik.online— yehSECURE_PAY_BASEmein dalein (pay subdomain nahi). - Hub pe Methods configure + Activate for API (Heleket HTML verify bhi yahi — yoursite.com pe nahi).
- API se poori key copy karein (
ap_sitename_…— site name se shuru) — sirf server pe rakhein. - API page ka Callback = aapki site ka HTTPS return URL (jaise
https://yoursite.com/secure_pay_return). - Support number wahi jo API page par set hai.
- Apni site se
providerke saath payment create karke customer kopayment_urlpe bhejein (https://pay.fastkwik.info). - Return pe
?ref=se status check —capturedpar hi balance credit karein. - 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.infoas the API base → signatures / methods fail. Usehttps://fastkwik.online. - Callback URL set to the pay host → customer never returns to your site. Callback = your https URL.
return_urlhost 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.onlineand 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.
| Icon | Code | Method | Notes |
|---|---|---|---|
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:
- Save your UPI ID (no webhook-secret box).
- Copy the personal SMS Forwarder Webhook URL (private token is already in the URL).
- Paste that full URL into an SMS forwarder app → POST body
{"message":"%text%"}(no secret header). - Customer pays on checkout and enters the 12-digit UTR.
- Credit SMS must match the same UTR + same amount → status becomes
captured(UTR single-use for 7 days). - 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.
- Heleket dashboard → API key + Merchant UUID → paste under Methods → Heleket.
- Copy Webhook URL
https://fastkwik.online/api/v1/webhooks/heleket_cryptointo Heleket Callback / Webhook settings. - Project URL in Heleket =
https://fastkwik.online(API host). Nothttps://pay.fastkwik.info, not yoursite.com. - Download Heleket’s HTML verification file → upload on Methods → open the published
https://…/*.htmlURL → Verify in Heleket. - Tick Activate for API → Save.
- On your site:
POST /api/v1/paymentswith"provider":"heleket_crypto"→ redirect topayment_url→ customer taps Open Heleket invoice. - Credit only when status is
captured(webhook and/orPOST …/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).