developer

UPI Payment Gateway API in India: A Developer's Guide to Zero Fees

How to integrate a zero-fee direct-to-bank UPI Payment API in India. Automate intent generation, dynamic QR codes, and secure webhook reconciliation.

VE VyaparGateway Engineering API Integration Team 3 min read
UPI Payment Gateway API in India: A Developer's Guide to Zero Fees guide
payment gateway api india upi payment api direct to bank upi api zero fee payment gateway

When Indian developers and engineering teams build digital products, they need a reliable, programmable way to collect payments.

If you are searching for a payment gateway API in India, you will quickly discover that legacy aggregators offer APIs heavily burdened by 2% transaction fees, complex nodal escrow account routing, and delayed T+2 settlements.

To solve this, developers are shifting to Direct-to-Bank UPI APIs. These APIs generate standard NPCI payment intents and provide webhook infrastructure, allowing you to bypass aggregator fees entirely.

Here is a technical guide to integrating a zero-fee UPI API into your backend.


The Shift to API-First UPI Infrastructure

Traditional payment gateway APIs act as financial intermediaries. They collect the money into their bank account, hold it, take a 2% cut, and eventually wire you the rest.

A direct-to-bank API is a purely technical layer.

  1. Your server makes an API call to generate a UPI intent.
  2. The user pays.
  3. The funds move directly across NPCI rails into your bank account (Instant T+0 Settlement).
  4. The API provider’s banking integration detects the credit and fires a webhook to your server.

You get the programmable infrastructure of a modern gateway, but with 0% transaction fees.


Generating Dynamic Payment Intents

The core of the API is intent generation. When a user reaches your checkout page, your backend (Node.js, Python, PHP, etc.) makes an authenticated HTTP POST request.

Example Request:

curl -X POST https://api.vyapargateway.com/v1/intents \
  -H "Authorization: Bearer sk_live_your_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "client_reference_id": "order_uuid_9876",
    "amount": 1499.00,
    "currency": "INR",
    "description": "Annual Pro Subscription"
  }'

Example Response:

{
  "id": "vg_int_abc123",
  "client_reference_id": "order_uuid_9876",
  "amount": 1499.00,
  "status": "CREATED",
  "upi_intent_uri": "upi://pay?pa=yourmerchant@bank&pn=YourApp&am=1499.00&tr=order_uuid_9876&cu=INR"
}

You return this upi_intent_uri to your frontend. On mobile, you trigger it as a deep link (which opens GPay/PhonePe). On desktop, you pass it to a QR code library to render a dynamic QR code for the user to scan.


Listening for Secure Webhooks

You must never rely on the frontend to tell you a payment was successful. You must listen for server-to-server webhooks.

When the transaction clears, VyaparGateway sends a POST request to your configured webhook URL.

To prevent malicious users from sending fake webhooks to unlock digital goods, you must verify the HMAC signature provided in the X-VyaparGateway-Signature header.

Python (FastAPI) Verification Example:

import hmac
import hashlib
from fastapi import APIRouter, Request, Header, HTTPException

router = APIRouter()
WEBHOOK_SECRET = "whsec_your_secret"

@router.post("/webhook/vyapargateway")
async def handle_webhook(request: Request, x_vyapargateway_signature: str = Header(None)):
    if not x_vyapargateway_signature:
        raise HTTPException(status_code=401, detail="Missing signature")
        
    payload_body = await request.body()
    
    # Calculate the expected signature
    expected_signature = hmac.new(
        WEBHOOK_SECRET.encode('utf-8'),
        payload_body,
        hashlib.sha256
    ).hexdigest()
    
    # Use constant-time comparison to prevent timing attacks
    if not hmac.compare_digest(expected_signature, x_vyapargateway_signature):
        raise HTTPException(status_code=401, detail="Invalid signature")
        
    # Signature is valid. Safely parse JSON and fulfill the order.
    import json
    data = JSON.loads(payload_body)
    
    if data["event"] == "intent.paid":
        fulfill_order(data["data"]["client_reference_id"])
        
    return {"status": "ok"}

Polling as a Fallback Strategy

Webhooks are asynchronous. Sometimes, due to network latency at the NPCI or a temporary blip on your server, a webhook might be delayed.

If your user is sitting on a “Waiting for payment…” screen on your frontend, your client should poll your backend every 3 seconds. If your backend hasn’t received the webhook yet, your backend should explicitly poll the VyaparGateway API to check the status.

Example Polling Request:

curl -X GET https://api.vyapargateway.com/v1/intents/vg_int_abc123 \
  -H "Authorization: Bearer sk_live_your_secret_key"

If the API returns "status": "COMPLETED", your backend can immediately fulfill the order, knowing the webhook is either on its way or was dropped.

Build robust, zero-fee payment flows with the VyaparGateway API today.

Direct answers

Frequently asked questions

What is a direct-to-bank UPI API?
A direct-to-bank UPI API allows your application to generate a dynamic UPI Intent (a specific URI string). When the user pays, the NPCI clears the funds directly from the user's bank account into your existing current account. The API provider simply acts as the software layer to generate the intent and fire webhooks upon success, charging 0% transaction fees.
How do I secure my webhook endpoint from fake requests?
Every webhook sent by the VyaparGateway API includes an X-VyaparGateway-Signature header. This is an HMAC SHA-256 hash of the raw JSON body calculated using your private Webhook Secret. Your backend must recalculate this hash and compare it to the header to cryptographically verify the payload.
Do I need to handle polling if the webhook fails?
It is a best practice. While VyaparGateway automatically retries failed webhooks with exponential backoff for up to 7 days, your backend should also poll our Transaction Status API if a user is waiting on the checkout screen but the webhook hasn't arrived yet.
Is this API compliant with RBI regulations?
Yes. Because direct-to-bank APIs route funds directly over NPCI rails and do not hold your money in an unauthorized escrow or nodal account, they bypass the heavy compliance overhead required for payment aggregators.

Build your payment flow

Explore the API and browser-only merchant tools.

Create UPI checkout orders, verify signed events, or test the free calculators and generators without exposing credentials.