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 →
0

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.

BASE URL
https://famgateway.in
  • Authentication (Header Recommended): Include your API key via the X-Api-Key: YOUR_API_KEY or Authorization: Bearer YOUR_API_KEY HTTP 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)
  • Non-Custodial Settlement & Refunds: 100% of customer funds transfer directly into your personal FamPay UPI wallet with zero platform custody. Because FamGateway never holds, escrows, or debits your money, programmatic debit/refund endpoints are intentionally not supported; merchants issue refunds manually directly from their FamApp or UPI banking app.
  • 1

    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.

    StepWhat to Do
    1Enable 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).
    2Go to your FamGateway dashboard → Integrations → Connect FamPay Gmail
    3Enter your FamPay-registered Gmail address
    4Create a 16-character Google App Password (no spaces) and paste it into the password field
    5Enter your FamPay UPI ID (e.g., yourname@fam)
    6Click Save — your integration verifies and your api_key activates immediately
    Critical Production Gotcha — Gmail IMAP Must Be Enabled Manually:

    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.

    Cryptographic Security & Key Management Architecture:
    • 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.
    2

    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.

    Canonical REST API vs Direct Query Alias:

    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.

    ParameterTypeStatusDescription
    api_keystringRequiredYour active API Key.
    amountfloatRequiredPayment amount in INR (e.g., 499.00).
    redirect_urlstringOptionalWhere to redirect user after hosted checkout payment.
    webhook_urlstringOptionalOverride the dashboard Webhook URL for this order only.
    customer_namestringOptionalCustomer's full name or internal user ID.
    customer_emailstringOptionalCustomer's email address.
    customer_phonestringOptionalCustomer'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'];
    RESPONSE — SUCCESS (200 OK)
    {
      "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

    FieldTypeDescription
    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_url for an instant mobile-optimized payment screen with live auto-verification.
    • Telegram & Custom Apps: Deliver qr_url directly as an image in chat, or open checkout_url in 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_name at 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 as sender_name directly from the bank credit email.
    3

    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.

    ParameterTypeStatusDescription
    api_keystringRequiredYour active API key.
    order_idstringRequiredThe 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"])
    RESPONSE — SUCCESS (200 OK)
    {
      "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

    FieldTypeDescription
    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

    StateDurationDescription & 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.
    FRONTEND JAVASCRIPT POLLING (PUBLIC NO-AUTH ENDPOINT)
    // 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_name field is populated strictly upon payment confirmation by extracting the verified bank account holder's name from the credit notification. Prior to payment completion, sender_name is null.
    • Bot Polling: Bot developers can query this endpoint in a non-blocking loop every 3 seconds to confirm payment completion.
    4

    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.

    Universal Gateway Notice (Websites, SaaS, Apps & Custom Stacks)

    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.

    PYTHON SDK QUICKSTART (pip install famgateway)
    # 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()
    Common Integration Mistakes & Pitfalls to Avoid:
    • 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 embed res.data.qr_url in an image container, or redirect the customer directly to res.data.checkout_url for 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_key strictly 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.
    5

    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.

    ParameterTypeStatusDescription
    order_idstringRequiredFor payment links, prefix the slug with LINK_ — e.g., LINK_yourname-abc123
    CHECK IF PAYMENT LINK IS PAID
    GET https://famgateway.in/api/verify-order.php?api_key=YOUR_KEY&order_id=LINK_yourname-abc123
    6

    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.

    Signing Secret Architecture Clarification — Master API Key as 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/hook directly in /api/qr.php to 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');
    }
    WEBHOOK EVENT PAYLOAD (JSON)
    {
      "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-Signature contains the HMAC-SHA256 signature calculated over the raw JSON payload.
    • Event Header: X-FamGateway-Event: payment.success is 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: expired when 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.
    7

    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.
    DOWNLOAD PDF RECEIPT VIA HTTP GET
    GET https://famgateway.in/transaction-details.php?id=ORDER_ID&download=pdf
    
    // Direct binary download (Content-Type: application/pdf)
    // Filename: Receipt_{order_id}.pdf
    PYTHON DOWNLOAD HELPER
    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")
    8

    HTTP Status & Error Codes

    All error responses follow a consistent JSON format: {"status": "error_type", "message": "Description"}

    HTTP CodeStatus FieldWhen it happensFix
    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
    STANDARD ERROR RESPONSE EXAMPLES (JSON)
    // 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." }
    9

    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.

    INSTALLATION (TERMINAL)
    pip install famgateway

    Python Client Methods Reference

    MethodParametersReturn TypeDescription
    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 ClassBase ExceptionTrigger 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.

    INSTALLATION (COMPOSER OR DIRECT ZIP)
    // 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

    MethodParametersReturn TypeDescription
    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 Fee

    Built 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

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

    Raw OpenAPI JSON Schema openapi.json → Import directly into Postman, Insomnia, or Swagger UI to generate interactive request collections or client SDKs in Go, Java, C#, or Ruby.
    10

    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.

    Topic Cluster & Tutorials

    Related Developer Guides & Resources

    View All 70+ Guides →
    SMM Panels

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

    Read Guide →
    WooCommerce

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

    Read Guide →
    Telegram Bot

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

    Read Guide →

    About the Platform

    FamGateway is an official unit of ARYANISPE, founded by Aryan Gupta (Aryanispe) and officially registered under the Ministry of Micro, Small and Medium Enterprises (MSME), Government of India (Reg: UDYAM-BR-28-0050000).

    All Systems Operational