Developer Documentation & API Reference
Automate zero-fee peer-to-peer UPI payment verification in your Python scripts, Telegram bots, and web backends.
All-in-One API Endpoints Quick Reference
Instant cheatsheet of all production URLs, methods, authentication tiers, and jump links.| Method | Endpoint / Path | Auth Level | Primary Purpose | Doc Link |
|---|---|---|---|---|
| POST |
/api/create-order
|
API Key Req | Create dynamic UPI order, reserve unique amount, return deep links & QR payload | Sec 2 → |
| GET |
/api/checkout-status.php
|
Public Safe | Client-side browser polling endpoint (zero API key leak) to detect instant payment | Sec 3 → |
| GET |
/api/verify-order.php
|
API Key Req | Server-to-server authoritative order check returning customer UPI reference & UTR | Sec 3 → |
| GET |
/pay.php?order_id=...
|
Public UI | Hosted checkout gateway page with dynamic QR, intent links, and live polling | Sec 2 → |
| GET |
/api/qr.php
|
API Key Req | Direct QR string / image generation endpoint for embedded merchant terminal displays | Sec 2 → |
| GET |
/api/qr-image.php?order_id=...
|
Public Safe | Dynamic QR Code image generator returning raw PNG image stream for HTML <img> tags |
Sec 2 → |
| GET |
/api/verify-order.php?order_id=LINK_...
|
API Key Req | Check real-time payment status of reusable payment link transactions | Sec 5 → |
| GET |
/transaction-details.php?id=...&download=pdf
|
Public / Auth | Generate and download bank-grade PDF transaction invoice & tax receipt | Sec 7 → |
| POST |
Merchant Webhook Listener
|
HMAC-SHA256 | Instant event callback triggered on payment success, verified via X-FamGateway-Signature |
Sec 6 → |
| GET |
/docs.txt
|
Public | Raw plain text documentation formatted specifically for AI models (ChatGPT, Claude, Cursor, Copilot) | Open → |
| GET |
/openapi.json
|
Public | Machine-readable OpenAPI 3.1.0 schema specification for Postman, Swagger & code generation | Open → |
| GET |
/status.php
|
Public | Live gateway operational health, response latency, and system uptime monitor | Live → |
Base URL & Authentication
All API requests are made over HTTPS. Authentication uses a simple api_key query parameter. You can find your API key in the API Keys section of your dashboard.
https://famgateway.in
- Authentication (Header Recommended): Include your API key via the
X-Api-Key: YOUR_API_KEYorAuthorization: Bearer YOUR_API_KEYHTTP header. Query parameter auth (?api_key=...) is supported for rapid cURL tests, but passing credentials in URLs is discouraged in production to prevent leakage in server access logs, reverse proxies, and browser referrers. Never expose your secret API key in client-side JavaScript. - Developer Concurrency & Rate Limits: Registered merchants enjoy unlimited order creation requests with zero monthly artificial quotas. The table below details exact throughput, concurrency limits, and protection mechanisms.
| Resource / Endpoint | Method | Merchant Quota | Protection & Cooldown | Exceeded Response |
|---|---|---|---|---|
/api/create-order |
POST | Unlimited (Active merchants) | Cloudflare L7 Flood Shield (~120 req/min/IP) | HTTP 429 |
/api/checkout-status.php |
GET | 3–5s recommended per session | In-memory cache + 5s merchant IMAP lock | HTTP 200 (cached status in <25ms) |
/api/verify-order.php |
GET | Unlimited server-to-server | API Key auth + IP burst shield | HTTP 429 |
Webhook Dispatch |
POST | Parallel Fan-Out Queue | Isolated queue per URL (webhook_jobs) |
3 retries (5m, 10m, 15m delay) |
Prerequisites — Connect FamPay Account
Before making any API calls, connect your FamPay Gmail account on the Integrations Page. This allows FamGateway to automatically monitor your inbox for payment confirmation emails and verify transactions in real-time.
| Step | What to Do |
|---|---|
| 1 | Enable IMAP in Gmail (Crucial Step): Open Gmail on a desktop browser → Click the Gear icon (Settings) → See all settings → Click Forwarding and POP/IMAP tab → Under IMAP access, select Enable IMAP → Click Save Changes at the bottom. (Direct Link: Gmail Forwarding and POP/IMAP Settings). |
| 2 | Go to your FamGateway dashboard → Integrations → Connect FamPay Gmail |
| 3 | Enter your FamPay-registered Gmail address |
| 4 | Create a 16-character Google App Password (no spaces) and paste it into the password field |
| 5 | Enter your FamPay UPI ID (e.g., yourname@fam) |
| 6 | Click Save — your integration verifies and your api_key activates immediately |
Google accounts often have IMAP access turned off by default. If IMAP is not explicitly enabled in your Gmail Settings → Forwarding and POP/IMAP, Google's mail server will refuse incoming connections, resulting in an IMAP connection failure even if your 16-character App Password is 100% correct. Always verify this setting once on desktop before linking.
- 256-Bit Symmetric Encryption: App Passwords are encrypted at rest using 256-bit AES with unique cryptographically random Initialization Vectors (IVs) generated per record.
- Server-Isolated Keys: The master encryption key is isolated at the server environment layer (
env.php) and never stored in MySQL. A database dump alone cannot decrypt credentials. - Stateless In-Memory Verification: Transaction parsing runs strictly in volatile RAM for under 5 milliseconds; email contents and inbox histories are never stored or logged.
- Unilateral Merchant Control: Merchants can revoke App Passwords at any second via Google Account Security. You can also enable FIDO2 / WebAuthn Biometric Passkeys in Profile Settings for phishing-resistant logins.
Create Order & Generate UPI QR
Creates a unique dynamic payment session. FamGateway generates an atomic order session with Bank UTR Idempotency locking, allowing customers to pay exact clean amounts without double-spend conflicts.
FamGateway provides two interchangeable entry points to generate orders:
• Canonical REST API (POST /api/create-order): Recommended for all production web applications, e-commerce checkouts, and backend microservices. Accepts application/json payloads and header authentication (X-Api-Key or Authorization: Bearer).
• Query & Hardware Display Alias (GET /api/qr.php): Lightweight endpoint accepting query string parameters, returning identical JSON order objects or raw PNG image streams for terminal, POS, and IoT embedded displays.
| Parameter | Type | Status | Description |
|---|---|---|---|
| api_key | string | Required | Your active API Key. |
| amount | float | Required | Payment amount in INR (e.g., 499.00). |
| redirect_url | string | Optional | Where to redirect user after hosted checkout payment. |
| webhook_url | string | Optional | Override the dashboard Webhook URL for this order only. |
| customer_name | string | Optional | Customer's full name or internal user ID. |
| customer_email | string | Optional | Customer's email address. |
| customer_phone | string | Optional | Customer's 10-digit mobile number. |
# 1. Canonical REST API (POST JSON) — Recommended for Production
curl -X POST "https://famgateway.in/api/create-order" \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"amount": 499.00,
"customer_name": "Rahul Sharma",
"customer_email": "[email protected]",
"redirect_url": "https://yoursite.com/payment-success"
}'
# 2. Query Alias (GET) — Ideal for quick terminal testing & scripts
curl -X GET "https://famgateway.in/api/qr.php?api_key=YOUR_API_KEY&amount=499&customer_name=Rahul"
// Modern Node.js (v18+) or Browser JavaScript using fetch()
// Method 1: Standard GET Query Parameters (Recommended for Bots & Scripts)
const apiKey = "YOUR_API_KEY";
const amount = 499.00;
const response = await fetch(`https://famgateway.in/api/qr.php?api_key=${encodeURIComponent(apiKey)}&amount=${amount}&customer_name=Rahul`);
const result = await response.json();
if (result.status === "success") {
const { order_id, payable_amount, qr_url, upi_intent, checkout_url } = result.data;
console.log("Order ID:", order_id);
console.log("Payable Amount: Rs.", payable_amount);
console.log("QR Code URL:", qr_url);
console.log("UPI Deep Link:", upi_intent);
console.log("Hosted Checkout Screen:", checkout_url);
}
// Method 2: Universal POST JSON Request (/api/create-order or /api/qr.php)
/*
const postRes = await fetch("https://famgateway.in/api/create-order", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify({
api_key: "YOUR_API_KEY",
amount: 499.00,
customer_name: "Rahul Sharma"
})
});
const postResult = await postRes.json();
*/
from famgateway import FamGateway fg = FamGateway(api_key="YOUR_API_KEY") order = fg.create_order(amount=499.00)
// RECOMMENDED: Official Standalone PHP SDK (famgateway-sdk.zip or GitHub)
require_once 'FamGateway.php';
$fg = new FamGateway('YOUR_API_KEY');
// Method 1: Instant 1-line checkout redirect (easiest for e-commerce stores)
$fg->createPayment(499.00, 'https://yoursite.com/success');
// Method 2: Custom API integration (returns order data without redirecting)
$order = $fg->createOrder(499.00, [
'customer_name' => 'Rahul Sharma',
'redirect_url' => 'https://yoursite.com/success'
]);
echo "Checkout URL: " . $order['checkout_url'];
echo "QR Image URL: " . $order['qr_url'];
// Alternative: Native PHP without SDK
// $res = file_get_contents("https://famgateway.in/api/qr.php?api_key=YOUR_KEY&amount=499");
// $data = json_decode($res, true)['data'];
{
"status": "success",
"data": {
"order_id": "fg_A1B2C3D4",
"amount": "499.00",
"payable_amount": "499.00",
"upi_id": "merchant@fam",
"qr_url": "https://famgateway.in/api/qr-image.php?order_id=fg_A1B2C3D4",
"checkout_url": "https://famgateway.in/pay.php?order_id=fg_A1B2C3D4",
"upi_intent": "upi://pay?pa=merchant%40fam&pn=FamPay&tr=fg_A1B2C3D4&tn=fg_A1B2C3D4&am=499.00&cu=INR",
"created_at_ist": "02-09-2026 14:30:00",
"expires_at_ist": "02-09-2026 14:35:00"
}
}
Order Creation JSON Response Fields
| Field | Type | Description |
|---|---|---|
| order_id | string | Unique 10-character alphanumeric transaction session identifier (e.g., fg_A1B2C3D4). Used to query status and identify webhook callbacks. |
| amount | string | Base payment amount requested by your client application in INR (e.g., 499.00). |
| payable_amount | string | Exact clean amount the customer must transfer in INR (e.g., 499.00). Strictly matches requested base amount; FamGateway verifies payments via exact Order ID purpose matching and Bank UTR idempotency without altering rupee amounts. |
| upi_id | string | Your personal FamPay UPI VPA (e.g., yourname@fam) receiving 100% of customer funds directly with zero platform custody. |
| qr_url | string | Direct image URL returning a clean PNG/SVG QR code. Can be embedded directly inside mobile apps or HTML <img> tags. |
| checkout_url | string | Hosted checkout gateway page with dynamic QR, mobile UPI intent buttons, and real-time live polling. |
| upi_intent | string | Standard NPCI UPI deep link (upi://pay?...) for opening PhonePe, Google Pay, Paytm, or BHIM directly on mobile devices without scanning. |
| expires_at_ist | string | Indian Standard Time (IST) timestamp when this payment session and reserved amount will expire (exactly 5 minutes / 300 seconds). |
- Hosted Checkout: Redirect customer to
checkout_urlfor an instant mobile-optimized payment screen with live auto-verification. - Telegram & Custom Apps: Deliver
qr_urldirectly as an image in chat, or opencheckout_urlin button links. - Offline & Screenshot Payments (Autonomous Sync): If a customer takes a screenshot of the QR code and closes their browser tab, FamGateway's 1-minute background sync daemon monitors all active sessions. When the customer scans the screenshot from their gallery and pays, the daemon detects the bank receipt, locks the Bank UTR, and fires your webhook automatically.
- Customer Name vs. Bank Sender Name: Passing
customer_nameat order creation allows you to tag your internal buyer/user. Separately, once the customer pays via UPI, FamGateway's IMAP engine extracts the verified bank account holder's name assender_namedirectly from the bank credit email.
Verify Payment Status (Poll)
After displaying the QR code, poll this endpoint every 3–5 seconds from your server. When the customer pays, FamGateway detects the FamPay Gmail notification in real-time and returns the full transaction details with Bank UTR.
| Parameter | Type | Status | Description |
|---|---|---|---|
| api_key | string | Required | Your active API key. |
| order_id | string | Required | The order_id returned from the create order call. |
curl -X GET "https://famgateway.in/api/verify-order.php?api_key=YOUR_KEY&order_id=fg_A1B2C3D4"
// Recommended: Poll every 3 seconds for up to 5 minutes
const orderId = "fg_A1B2C3D4";
const checkStatus = async () => {
// Use /api/checkout-status.php (public) or /api/verify-order.php?api_key=... (backend)
const res = await fetch(`https://famgateway.in/api/checkout-status.php?order_id=${encodeURIComponent(orderId)}`);
const data = await res.json();
if (data.status === "success") {
console.log("Payment Verified! UTR:", data.utr, "Paid by:", data.sender_name);
clearInterval(pollTimer);
} else if (data.status === "expired") {
console.log("Order expired without payment.");
clearInterval(pollTimer);
}
};
// Start 3-second polling interval
const pollTimer = setInterval(checkStatus, 3000);
// RECOMMENDED: Using Official FamGateway PHP SDK
$status = $fg->getOrderStatus('fg_A1B2C3D4');
if (($status['status'] ?? '') === 'success') {
$utr = $status['data']['utr'];
echo "Payment verified! UTR: " . $utr;
}
# Using Official Python SDK
status = fg.get_order_status("fg_A1B2C3D4")
if status.get("status") == "success":
print("Payment Verified! UTR:", status["data"]["utr"])
{
"status": "success",
"data": {
"order_id": "fg_A1B2C3D4",
"transaction_id": "FMP987654321",
"amount": 499,
"utr": "420987654321",
"sender_name": "Rahul Sharma",
"payment_time_ist": "02-09-2026 14:31:12"
}
}
Order Verification JSON Response Fields
| Field | Type | Description |
|---|---|---|
| status | string | Overall lifecycle status: success (confirmed paid), pending (awaiting UPI payment), or expired (session timed out). |
| order_id | string | The 10-character alphanumeric transaction identifier matching your creation request. |
| transaction_id | string | Internal FamGateway ledger reference ID (e.g., FMP987654321). |
| amount | number | The final settled amount verified and credited to your FamPay UPI account in INR. |
| utr | string | 12-digit Unique Transaction Reference assigned by NPCI and IDFC FIRST Bank UPI switch. Guarantees banking idempotency. |
| sender_name | string | Verified full name of the customer extracted directly from the authenticated bank notification email upon payment completion. |
| payment_time_ist | string | Exact Indian Standard Time timestamp when the bank credit notification was processed and verified. |
Idempotency, Retries & Double-Spend Prevention
FamGateway implements bank-grade idempotency mechanisms at both database and transaction levels:
- Database Bank UTR Idempotency: When a payment is processed, the Bank UTR and Transaction ID are atomically validated against existing successful records. Any subsequent attempt to claim or replay the same UTR across any order is rejected immediately with
Duplicate payment attempt blocked. - Atomic Concurrency Locking (MySQL
FOR UPDATE): When processing payment fulfillment, FamGateway executes an atomic row lock on the order and merchant record, pairing the unique Order ID embedded in the UPI transaction note with Bank UTR deduplication. This guarantees 100% collision-free payment attribution on exact clean rupee amounts without altering prices. - Safe Client Retries: If a client network connection drops during
POST /api/create-order, retrying the request creates a clean new session. Unpaid pending orders safely expire in 5 minutes (300s) with zero financial liability.
Order Lifecycle & State Machine
| State | Duration | Description & Action Required |
|---|---|---|
| PENDING | 0 to 5 mins (300s) | Order initialized, dynamic QR code active with exact clean amount and embedded Order ID note. Your frontend or bot should poll status every 3–5 seconds. |
| SUCCESS | Permanent | Payment confirmed via real-time IMAP listener. Bank UTR logged, webhook fired, and PDF receipt generated. Fulfill digital good or activate account. |
| EXPIRED | After 5 mins (300s) | Payment session window elapsed without verified bank credit. Order marked expired and QR invalidated to protect against stale transfers. Display fresh order to user. |
// Safe for frontend browser JavaScript (does not require or expose your secret api_key)
GET https://famgateway.in/api/checkout-status.php?order_id=fg_A1B2C3D4
// Response:
// {"status": "success", "order_id": "fg_A1B2C3D4", "utr": "420987654321", "sender_name": "Rahul Sharma"}
// {"status": "pending"}
// {"status": "expired"}
- Server-to-Server Verification: Use
/api/verify-order.php?api_key=YOUR_KEY&order_id=...for secure backend verification with full transaction metadata. - Frontend Web Checkout Polling: Use
/api/checkout-status.php?order_id=...for browser AJAX / Fetch polling without exposing your API Key. - Anti-Replay Protection: Built-in Bank UTR and Transaction ID idempotency ensures the same FamPay payment cannot be reused.
- Verified Bank Sender: The
sender_namefield is populated strictly upon payment confirmation by extracting the verified bank account holder's name from the credit notification. Prior to payment completion,sender_nameis null. - Bot Polling: Bot developers can query this endpoint in a non-blocking loop every 3 seconds to confirm payment completion.
Universal Architecture & Reference Implementations
FamGateway is an agnostic, universal payment gateway built for any application stack — Websites, E-Commerce, SaaS, Android & iOS Apps (Flutter / React Native), Custom Microservices, and Automation.
FamGateway is NOT dedicated to or limited to Telegram bots. The bot snippets below are provided solely as a concrete reference implementation to illustrate the complete real-time payment lifecycle (Create Order → Render QR → 3-Second Background Polling → Balance/Access Fulfillment). The exact same REST endpoints, JSON payloads, and webhook triggers work identically across Node.js (Express / Next.js), Python (FastAPI / Django), PHP (Laravel / WordPress), Go, Java, Flutter, and custom web frontends.
# 1. Install package: pip install famgateway
from famgateway import FamGateway
# 2. Initialize with your API Key
fg = FamGateway(api_key="YOUR_API_KEY")
# 3. Create Dynamic UPI Order (Zero customer details required — only amount is needed!)
order = fg.create_order(amount=499.00)
print("Order ID:", order.order_id)
print("QR Code Image URL:", order.qr_url)
print("Deep UPI Intent:", order.upi_intent)
print("Hosted Checkout URL:", order.checkout_url)
# 4. Check status anytime (Bank UTR & payer name auto-extracted upon payment)
status = fg.get_status(order.order_id)
if status.is_paid:
print(f"Payment Confirmed! Paid by: {status.sender_name}, Bank UTR: {status.utr}")
// npm install express
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
const API_KEY = process.env.FAMGATEWAY_API_KEY || 'YOUR_FAMGATEWAY_API_KEY';
// 1. Web Checkout Endpoint (Called by your website frontend React/Vue/HTML)
app.post('/api/create-checkout', async (req, res) => {
const { amount, customerName } = req.body;
const resp = await fetch('https://famgateway.in/api/create-order', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
api_key: API_KEY,
amount: amount || 499.00,
customer_name: customerName,
redirect_url: 'https://yoursite.com/payment-success'
})
});
const orderData = await resp.json();
// Return order_id, qr_url, and checkout_url to your frontend
res.json(orderData);
});
// 2. Real-Time Webhook Listener (FamGateway auto-calls this upon bank credit)
// PRODUCTION SECURITY MANDATE: Always verify X-FamGateway-Signature before fulfilling orders (see Section 6)
app.post('/api/famgateway-webhook', async (req, res) => {
const signature = req.headers['x-famgateway-signature'];
const expected = crypto.createHmac('sha256', API_KEY)
.update(req.rawBody || JSON.stringify(req.body))
.digest('hex');
if (signature && signature !== expected) {
return res.status(401).json({ error: 'Invalid webhook signature' });
}
const { status, order_id, utr, amount, sender_name } = req.body;
if (status === 'success') {
// Payment verified! Fulfill order, upgrade subscription, or credit wallet:
console.log(`Verified Order ${order_id} (UTR: ${utr}) of Rs ${amount} from ${sender_name}`);
await fulfillCustomerOrder(order_id);
}
res.json({ status: 'received' });
});
app.listen(3000, () => console.log('Server running on port 3000'));
# pip install fastapi uvicorn famgateway
from fastapi import FastAPI, Request
from famgateway import FamGateway
app = FastAPI()
fg = FamGateway(api_key="YOUR_FAMGATEWAY_API_KEY")
# 1. Create Checkout / QR endpoint for your website or mobile app
@app.post("/api/checkout")
def create_payment(amount: float, customer_name: str = "Customer"):
order = fg.create_order(
amount=amount,
customer_name=customer_name,
redirect_url="https://yoursite.com/payment-success"
)
return {
"order_id": order.order_id,
"qr_url": order.qr_url,
"upi_intent": order.upi_intent,
"checkout_url": order.checkout_url
}
# 2. Webhook Endpoint: Auto-called by FamGateway upon bank credit
# PRODUCTION SECURITY MANDATE: Always verify X-FamGateway-Signature before fulfilling orders (see Section 6)
@app.post("/api/webhook")
async def handle_webhook(request: Request):
sig = request.headers.get("x-famgateway-signature")
body = await request.body()
if sig and not FamGateway.verify_webhook_signature(body, sig, "YOUR_FAMGATEWAY_API_KEY"):
return {"error": "Invalid signature"}
payload = await request.json()
if payload.get("status") == "success":
order_id = payload.get("order_id")
utr = payload.get("utr")
sender_name = payload.get("sender_name")
print(f"Payment Captured! Order: {order_id}, UTR: {utr}, Payer: {sender_name}")
# Fulfill access, activate subscription, or credit wallet balance
return {"status": "ok"}
# pip install famgateway pyTelegramBotAPI
# Concrete Reference Example: Demonstrates 3-second background polling & automatic QR cleanup
import time
import threading
import telebot
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton
from famgateway import FamGateway
bot = telebot.TeleBot("YOUR_TELEGRAM_BOT_TOKEN")
fg = FamGateway(api_key="YOUR_FAMGATEWAY_API_KEY")
# Background auto-polling thread: checks every 3s and deletes old QR image once paid
def auto_poll_order(chat_id, message_id, order_id, amount):
for _ in range(100): # Poll up to 5 minutes (100 attempts x 3s)
time.sleep(3) # Recommended 3-5 second polling interval
try:
status = fg.get_status(order_id)
if status.is_paid:
# 1. Delete old QR code message to keep chat clean
try:
bot.delete_message(chat_id, message_id)
except Exception:
pass
# 2. Send instant payment confirmation with Bank UTR
bot.send_message(
chat_id,
f"Payment Verified Automatically!\n\nOrder ID: `{order_id}`\nBank UTR: `{status.utr}`\nAmount: Rs {amount:.2f}\nYour access has been activated!",
parse_mode="Markdown"
)
break
elif status.is_expired:
break
except Exception:
continue
@bot.message_handler(commands=['buy'])
def handle_buy(message):
order = fg.create_order(amount=50.0, customer_name=message.from_user.first_name)
markup = InlineKeyboardMarkup()
markup.row(
InlineKeyboardButton("Pay via UPI App / Web", url=order.checkout_url)
)
caption = (
f"Instant UPI Payment\n\n"
f"Amount to Pay: Rs {order.payable_amount}\n"
f"Order ID: `{order.order_id}`\n\n"
f"Scan QR code with PhonePe, GPay, or Paytm.\n"
f"Payment will auto-verify within 3 seconds of transfer!"
)
photo_msg = bot.send_photo(
chat_id=message.chat.id,
photo=order.qr_url,
caption=caption,
parse_mode="Markdown",
reply_markup=markup
)
# Launch background auto-polling thread
threading.Thread(
target=auto_poll_order,
args=(message.chat.id, photo_msg.message_id, order.order_id, 50.0),
daemon=True
).start()
bot.infinity_polling()
- Displaying Raw JSON instead of Rendering QR Code or Redirecting: Never display the raw API JSON string (e.g.
{"status":"success", "data": ...}) to end users. Always parse the response and either embedres.data.qr_urlin an image container, or redirect the customer directly tores.data.checkout_urlfor an instant hosted payment experience. - Over-polling (Spamming API faster than 3s): FamPay IMAP verification emails arrive in 2 to 4 seconds. Polling every 500ms or 1 second is unnecessary and will hit the automatic 5-second merchant lock. Always set polling intervals to 3 to 5 seconds.
- Client-Side Secret API Key Exposure: Keep your
api_keystrictly in your server-side environment variables. For frontend browser JavaScript polling, always use the public safe endpoint/api/checkout-status.php?order_id=...which requires no API key. - Assuming Bot-Only Architecture: FamGateway is a standard REST gateway. Whether you are building an e-commerce website, SaaS billing, mobile app top-up, or Discord/Telegram automation, the same dynamic QR and webhook architecture works universally.
Payment Links (Shareable URLs)
Payment Links are reusable, shareable URLs that let anyone pay you without needing custom checkout pages. You can verify if a payment link has been paid using the same verify-order.php endpoint.
| Parameter | Type | Status | Description |
|---|---|---|---|
| order_id | string | Required | For payment links, prefix the slug with LINK_ — e.g., LINK_yourname-abc123 |
GET https://famgateway.in/api/verify-order.php?api_key=YOUR_KEY&order_id=LINK_yourname-abc123
Webhooks & HMAC-SHA256 Signature Verification
Webhooks provide instant, sub-150ms server-to-server notifications when a customer completes payment. FamGateway sends a signed HTTP POST request with a cryptographic X-FamGateway-Signature header calculated using your API Key as the secret.
Unlike legacy aggregators that force you to generate and store a distinct secondary webhook signing secret (such as whsec_...), FamGateway cryptographically signs all outgoing webhook payloads directly using your active Merchant Default API Key (YOUR_FAMGATEWAY_API_KEY) as the HMAC-SHA256 secret. When verifying the X-FamGateway-Signature header on your server, simply pass your FamGateway API Key as the secret. No extra webhook secret configuration is required.
- Multiple Webhook Endpoints (Parallel Fan-Out): FamGateway supports registering multiple distinct webhook destinations under Webhooks Settings. Broadcast payment events simultaneously across your primary store, automated Telegram/Discord bots, and backup databases.
- Isolated Failure Retries: Each destination operates on an independent queue job (
webhook_jobs). If one server experiences a timeout or restart, its isolated exponential retry schedule will never delay deliveries to your other active endpoints. - Granular Lifecycle & SSRF Protection: 1-click Pause / Activate toggles allow seamless server maintenance without deleting URLs. Built-in enterprise SSRF firewall blocks loopback (
127.0.0.1) and private subnets. - Dynamic Per-Order Routing: Pass
&webhook_url=https://yourserver.com/hookdirectly in/api/qr.phpto override destinations for specific custom checkouts. - Architecture Whitepaper: Read our complete technical guide on Multiple Webhook Endpoints & Fan-Out Queue Architecture.
const express = require('express');
const crypto = require('crypto');
const app = express();
const API_KEY = 'YOUR_FAMGATEWAY_API_KEY';
// IMPORTANT: Preserve raw request body buffer for HMAC verification
app.use(express.json({
verify: (req, res, buf) => { req.rawBody = buf; }
}));
app.post('/webhook', (req, res) => {
const signature = req.headers['x-famgateway-signature'];
const expected = crypto.createHmac('sha256', API_KEY)
.update(req.rawBody)
.digest('hex');
// Cryptographically compare signatures (prevents timing attacks)
if (!signature || !crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(401).send('Invalid webhook signature');
}
const event = req.body;
if (event.event === 'payment.success' || event.status === 'success') {
const { order_id, amount, utr, sender_name } = event;
console.log(`Payment confirmed: Order ${order_id} for Rs.${amount} (UTR: ${utr}) from ${sender_name}`);
// TODO: Fulfill order in your database / deliver product
}
// Always respond with 200 OK within 10 seconds
res.status(200).send('OK');
});
app.listen(3000, () => console.log('Webhook server running on port 3000'));
import hmac, hashlib
from fastapi import FastAPI, Request, HTTPException, Header
app = FastAPI()
API_KEY = "YOUR_FAMGATEWAY_API_KEY"
@app.post("/webhook")
async def famgateway_webhook(request: Request, x_famgateway_signature: str = Header(None)):
body = await request.body()
computed = hmac.new(API_KEY.encode(), body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(computed, x_famgateway_signature or ""):
raise HTTPException(status_code=401, detail="Invalid signature")
data = await request.json()
if data.get("status") == "success":
order_id = data.get("order_id")
utr = data.get("utr")
amount = data.get("amount")
print(f"Payment Verified: Order {order_id}, UTR: {utr}, Amount: Rs.{amount}")
return {"status": "ok"}
<?php
// RECOMMENDED: Using Official FamGateway PHP SDK
require_once 'FamGateway.php';
$fg = new FamGateway('YOUR_API_KEY');
$rawBody = file_get_contents('php://input');
$sigHeader = $_SERVER['HTTP_X_FAMGATEWAY_SIGNATURE'] ?? '';
// One-line cryptographic HMAC-SHA256 signature verification
$event = $fg->verifyWebhook($rawBody, $sigHeader);
if ($event !== false && (($event['event'] ?? '') === 'payment.success' || ($event['status'] ?? '') === 'success')) {
$orderId = $event['order_id'];
$utr = $event['utr'];
$amount = $event['amount'];
$senderName = $event['sender_name'];
// TODO: Fulfill order in your database (credit wallet, deliver digital good)
http_response_code(200);
echo 'OK';
} else {
// Fake or invalid signature
http_response_code(401);
die('Invalid signature');
}
{
"event": "payment.success",
"order_id": "fg_A1B2C3D4",
"amount": 499,
"payable_amount": 499,
"status": "success",
"transaction_id": "FMP987654321",
"utr": "420987654321",
"sender_name": "Rahul Sharma",
"payment_time": "02-09-2026 14:31:12",
"timestamp": 1788352710
}
- Header:
X-FamGateway-Signaturecontains the HMAC-SHA256 signature calculated over the raw JSON payload. - Event Header:
X-FamGateway-Event: payment.successis included in all payment success webhooks. - Events Dispatched: Webhooks are fired exclusively for confirmed successful payments (
payment.success). Unpaid or abandoned checkout sessions expire automatically after 5 minutes (status:expiredwhen polled) without debiting the customer, meaning failure webhooks are not generated. - Zero-Drop Delivery: Even if a buyer closes the browser window immediately after payment or before redirection finishes, the 1-minute background cron daemon inspects the bank credit receipt, confirms fulfillment, and dispatches the webhook reliably.
- Automatic Retries: FamGateway retries failed webhook endpoints up to 5 times with exponential backoff if your server returns non-2xx status codes.
Automated PDF Receipts & Invoicing
Every verified UPI transaction automatically compiles an official, institutional A4 PDF receipt with Government of India MSME registration (UDYAM-BR-28-0050000) under ARYANISPE. Receipts are delivered in memory with zero disk lag.
- Automatic Merchant Email Delivery: In parallel with webhook dispatch, an immutable base64-encoded PDF (
Receipt_{order_id}.pdf) is attached directly to your instant merchant notification email. - Direct On-Demand Download API: Both merchants and buyers can retrieve the official signed PDF receipt at any time via a direct HTTP GET request.
- Audit & Legal Compliance: Contains official entity registration, verified Bank UTR, Payer Name, exact payment timestamp, and transaction references for your accounting and tax compliance.
GET https://famgateway.in/transaction-details.php?id=ORDER_ID&download=pdf
// Direct binary download (Content-Type: application/pdf)
// Filename: Receipt_{order_id}.pdf
import requests
order_id = "fg_A1B2C3D4"
receipt_url = f"https://famgateway.in/transaction-details.php?id={order_id}&download=pdf"
res = requests.get(receipt_url)
if res.status_code == 200:
with open(f"Receipt_{order_id}.pdf", "wb") as f:
f.write(res.content)
print(f"Official PDF Receipt saved: Receipt_{order_id}.pdf")
HTTP Status & Error Codes
All error responses follow a consistent JSON format: {"status": "error_type", "message": "Description"}
| HTTP Code | Status Field | When it happens | Fix |
|---|---|---|---|
| 400 | error |
Missing or invalid amount parameter, or malformed URL |
Pass valid numeric amount (e.g. 499.00) |
| 401 | unauthorized |
Missing, malformed, or invalid api_key |
Check or rotate key in API Keys |
| 403 | suspended |
Account suspended by admin for policy violation | Contact support at [email protected] |
| 404 | not_found |
Specified order_id does not exist |
Verify order_id string matches creation response |
| 408 | expired |
5-minute (300s) payment window exceeded without bank credit | Create fresh order session and display new dynamic QR |
| 429 | error |
Client IP flood limit exceeded (~120 req/min) | Throttle client requests; poll every 3 to 5 seconds |
| 500 | error |
Gmail IMAP socket connection failed | Enable IMAP in Gmail Settings & check App Password |
// HTTP 400 Bad Request
{ "status": "error", "message": "Missing or invalid amount parameter" }
// HTTP 401 Unauthorized
{ "status": "unauthorized", "message": "Invalid api_key" }
// HTTP 404 Not Found
{ "status": "not_found", "message": "Order ID or payment link not found" }
// HTTP 408 Request Timeout (Expired Order)
{ "status": "expired", "message": "Order expired" }
// HTTP 429 Too Many Requests
{ "status": "error", "message": "Rate limit exceeded. Please throttle requests." }
// HTTP 500 Server Error
{ "status": "error", "message": "FamPay Gmail not connected. Connect it in your dashboard first." }
Official Open-Source SDKs, Modules & Ecosystem
FamGateway provides official, production-ready open-source client libraries and billing modules. Integrate in seconds using native package managers with zero intermediate gateway fees.
1. Official Python SDK (PyPI)
v1.0.4 Python >= 3.7 MIT License
An enterprise-grade synchronous Python client built with requests.Session connection pooling, strict type hints, custom exceptions, and structured response dataclasses. Fully whitelisted on PythonAnywhere Free Tier for 24/7 cloud hosting.
pip install famgateway
Python Client Methods Reference
| Method | Parameters | Return Type | Description |
|---|---|---|---|
fg.create_order(...) |
amount (float/str), customer_name (opt), customer_email (opt), customer_phone (opt), redirect_url (opt), webhook_url (opt) |
OrderResponse |
Initializes a dynamic order. Provides .qr_url, .upi_intent, .order_id, .payable_amount, and .checkout_url. |
fg.get_status(...) |
order_id (str) |
OrderStatus |
Fast public polling check. Returns object with boolean .is_paid, .is_expired, and .utr. |
fg.verify_order(...) |
order_id (str) |
OrderStatus |
Authoritative server-to-server verification check using your authenticated API Key. |
FamGateway.verify_webhook_signature(...) |
payload (bytes/str), signature (str), api_key (str) |
bool |
Static timing-safe HMAC-SHA256 signature verifier preventing timing attack exploits. |
Python Custom Exceptions
| Exception Class | Base Exception | Trigger Condition |
|---|---|---|
AuthenticationError |
FamGatewayError |
Raised on HTTP 401 when API Key is missing, malformed, or revoked. |
OrderNotFoundError |
FamGatewayError |
Raised on HTTP 404 when querying an invalid or deleted order_id. |
APIError |
FamGatewayError |
Raised on API business failures or server error codes (HTTP 4xx/5xx). |
NetworkError |
FamGatewayError |
Raised on DNS resolution failures, proxy connection drops, or timeouts. |
2. Official PHP SDK (Composer & Standalone)
v2.0 PHP 7.4 – 8.3 Zero Dependencies
Ultra-lightweight, zero-dependency PHP SDK engineered for seamless operation on cPanel, shared web hosting, and modern VPS setups. Automatically detects and prefers native cURL with a clean stream context fallback when allow_url_fopen is restricted.
// Method 1: Via Composer / Packagist composer require aryanispe/famgateway-php-sdk // Method 2: Standalone Drop-in File (Download famgateway-sdk.zip) require_once __DIR__ . '/FamGateway.php';
PHP SDK Methods Reference
| Method | Parameters | Return Type | Description |
|---|---|---|---|
new FamGateway($apiKey) |
$apiKey (string) |
FamGateway |
Initializes the client with your merchant API key. |
$fg->createPayment(...) |
$amount, $redirectUrl = '', $webhookUrl = '' |
void (redirect) |
Creates order and immediately redirects customer browser to hosted checkout page. Ideal for standard web shops. |
$fg->createOrder(...) |
$amount, $params = [] |
array |
Headless order creation. Returns full array with order_id, checkout_url, qr_url, and upi_intent without redirecting. |
$fg->getOrderStatus(...) |
$orderId (string) |
array |
Queries server-to-server verification endpoint. Returns payment status, Bank UTR, and payer name. |
$fg->verifyWebhook(...) |
$rawPostData (string), $signature (string) |
array|false |
Timing-safe signature validator using hash_equals(). Returns decoded JSON payload if authentic, or false if forged. |
3. Official WHMCS Payment Gateway Module
WHMCS 8.x / 7.x 0% Gateway FeeBuilt for web hosts, domain registrars, and cloud server providers. Accept direct UPI payments on your WHMCS billing system with zero transaction cuts and automated instant invoice clearance.
3-Step WHMCS Installation Guide
| Step | Action | Details |
|---|---|---|
| Step 1 | Upload Module Files | Download FamGateway-WHMCS-Module.zip, extract, and upload the modules/ directory to your WHMCS root (e.g. public_html/whmcs/). This places modules/gateways/famgateway.php and modules/gateways/callback/famgateway.php. |
| Step 2 | Activate in WHMCS Admin | Navigate to Configuration (System Settings) → Payment Gateways → All Payment Gateways tab. Click FamGateway (0% Fee UPI) to activate. |
| Step 3 | Configure Credentials | Check Show on Order Form, paste your secret API Key from your FamGateway dashboard, and click Save Changes. Invoices will automatically mark as Paid upon webhook callback verification. |
4. Reference Bot Implementations
Production-ready automation bots featuring background polling threads, dynamic QR photo upload, and instant delivery.
5. OpenAPI 3.1.0 Specification
Standardized machine-readable contract covering every parameter, schema model, and status code.
Architecture Philosophy & Intentional Design Choices (FAQ)
Clear answers on why FamGateway is non-custodial, how settlement works, and the engineering rationale behind our core API design.
Q1. Why is there no programmatic refund API endpoint (e.g. /api/refund)?
Because FamGateway operates on a 100% Non-Custodial Architecture. Traditional payment aggregators (Razorpay, Stripe, Cashfree) hold your revenue in nodal escrow accounts for 2 to 3 business days (T+2 settlement) and charge a 2% cut, giving them unilateral debit authority over your funds. In contrast, FamGateway charges 0% platform fees and never holds, touches, or escrows your money. 100% of customer funds transfer peer-to-peer directly into your personal FamPay UPI wallet instantly. Because FamGateway possesses zero debit permissions on your personal bank account, all refunds are issued manually by you directly from your FamApp or UPI mobile banking application.
Q2. Why does the platform verify payments via Gmail IMAP rather than direct bank switch hooks?
To eliminate paperwork, GSTIN mandates, and current account restrictions for independent creators. Direct banking switches require private limited incorporation, audited balance sheets, enterprise merchant underwriting, and weeks of compliance verification. FamGateway democratizes payment automation for students, solo developers, and early-stage indie hackers with a personal savings account. Our low-latency IMAP engine evaluates incoming bank confirmation emails in volatile RAM under 5 milliseconds with 256-bit AES encryption, verifying payments without exposing your personal banking credentials.
Q3. Why does FamGateway support only UPI in INR (no international credit cards / foreign currencies)?
FamGateway is purposefully specialized for India's National Payments Corporation of India (NPCI) UPI network. UPI represents India's most ubiquitous, instant, zero-MDR payment rail. For international cross-border sales in USD/EUR requiring Visa/Mastercard processing, custodial international processors (like Stripe) are recommended. FamGateway exists specifically to solve frictionless, zero-fee domestic peer-to-peer UPI payments without corporate overhead.
Q4. Why do dynamic payment sessions expire after 5 minutes (300 seconds)?
To prevent stale payment collisions and match Indian banking session standards. FamGateway pairs exact Order IDs embedded in the UPI transaction note with Bank UTR idempotency locking. The 5-minute (300-second) dynamic QR window matches standard NPCI banking session timeouts, prevents abandoned checkouts from lingering indefinitely, and protects merchants against delayed or confused transfers while giving genuine buyers plenty of time to scan and approve.
Q6. Do I need a separate webhook signing secret, or do I use my master API Key?
FamGateway intentionally uses your Merchant Default API Key as the cryptographic HMAC-SHA256 secret. There is no separate or secondary webhook secret to configure. When verifying the X-FamGateway-Signature header on incoming webhooks, pass your active FamGateway API Key as the secret key. This unified key architecture eliminates configuration drift and simplifies secrets management across staging and production.
Q7. How should I test payment verification and webhook delivery in development?
Test directly using small live micro-transactions (e.g., Re. 1.00). Because FamGateway operates on a 100% zero-fee, non-custodial rail, testing with Re. 1.00 incurs zero deductions or gateway fees — the full amount transfers peer-to-peer into your own FamPay wallet instantly. This allows you to verify real bank UTR generation, automated Gmail email parsing, and production webhook delivery in true real-world conditions.
Q8. Why is enabling IMAP inside Gmail settings mandatory if I already generated an App Password?
Because Google enforces a two-tier protocol check on mailboxes. An App Password grants application-level authentication, but Google's mail server will reject all IMAP connection handshakes (imap.gmail.com:993) if the IMAP transport protocol is toggled off in your mailbox settings. Many Gmail accounts have IMAP disabled by default. Enabling IMAP under Gmail Settings → Forwarding and POP/IMAP ensures Google accepts incoming socket handshakes.
Q9. How does FamGateway handle high-concurrency traffic and API rate limits?
Order creation is virtually unlimited with zero merchant throttling, protected at the network edge by Cloudflare DDoS mitigation and standard IP burst limits (~120 req/min per IP). For status checks, frontend checkouts poll /api/checkout-status.php every 3 to 5 seconds. To protect your connected Gmail account from Google IMAP connection bans, our backend enforces a 5-second per-merchant concurrency cooldown on IMAP inbox connects. For large enterprise volumes (>500 concurrent orders), merchants should rely on our parallel Webhook Fan-Out architecture for zero-polling, instant fulfillment.
Q5. What happens if a customer takes a screenshot of the QR and pays after closing their browser?
Payments are automatically captured by our background reconciliation engine. Even if the customer closes their browser tab or loses network connectivity, our autonomous 1-minute cron worker continuously reconciles newly received bank credits against all active orders. The moment the transfer clears, the system matches the amount, logs the Bank UTR, updates the database, and dispatches your webhook instantly.
Related Developer Guides & Resources
How to Integrate FamPay UPI Payment Gateway in SMM Panels (Rental, Perfect Panel & SmartPanel)
Step-by-step developer guide to integrating FamPay UPI payment gateway in SMM panels (Rental, Perfect Panel...
How to Accept UPI Payments on WooCommerce Without GST or Current Account (2026 Guide)
Complete tutorial on accepting automated UPI payments on WooCommerce without GST or a commercial current ac...
How to Accept Automated UPI Payments in Telegram Bots (Python & Node.js Guide)
Step-by-step tutorial on accepting automated UPI payments in Telegram shop bots using Python (FastAPI) and ...