NxtBanking — NxtBanking — API Infrastructure for Indian Fintech

UPI API Integration Guide for Indian Fintech Apps

Updated April 23, 2026 min read

NxtBanking Editorial

UPI handles the majority of retail payments in India. If you are building a

fintech app, marketplace or SaaS billing product, **UPI will be your

default rail**. This guide walks through the full UPI API surface

— collect, pay, refund, AutoPay — with runnable examples and a production-readiness

checklist.

1. UPI architecture in one diagram (in words)

At the protocol level there are four parties: your app (merchant/PSP client),

the merchant PSP (an RBI-licensed PA-PG or a UPI-enabled bank),

NPCI (which routes the request through the central UPI switch) and the

remitter PSP (the customer’s bank). Your API client only ever talks to

the merchant PSP. Everything below that is NPCI’s concern — but the error codes

that bubble up to you are NPCI’s, so knowing the layering helps with

debugging.

2. Authenticating to the UPI API

Most UPI API vendors use a bearer-token OAuth2 client-credentials flow. You

exchange a client_id + client_secret pair for a

short-lived access token, then send that token on every request.

curl -X POST "https://api.nxtbanking.com/oauth/token"
-H "Content-Type: application/json"
-d '{"client_id":"CK_xxx","client_secret":"CS_xxx","grant_type":"client_credentials"}'

3. UPI Collect — requesting a payment

A collect request pushes a payment prompt to a VPA (Virtual Payment

Address) such as ravi@okhdfc. The customer approves or declines on

their UPI app. Keep four things in mind:

  • Idempotency — always send a unique merchant_txn_id and reject duplicates on your side.
  • Expiry — NPCI’s default collect expiry is 3 minutes; configure it explicitly.
  • Reference remarks — max 50 chars, no special characters beyond space, dot, hyphen.
  • Minimum amount — 1 INR; maximum 1 lakh per transaction (merchant-category-dependent).

curl -X POST "https://api.nxtbanking.com/upi/v1/collect"
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{
"merchant_txn_id": "ORD-2026-00042",
"vpa": "ravi@okhdfc",
"amount": 499.00,
"currency": "INR",
"remarks": "Order #42 subscription renewal",
"expiry_minutes": 3,
"callback_url": "https://shop.example.com/webhooks/upi"
}'
A successful response returns status: "INITIATED" and a

bank_rrn once NPCI accepts it (usually within 200–800 ms). The

final status arrives via webhook, not in the HTTP response.

4. UPI Pay — pushing money out (payout-style)

UPI Pay is the mirror of collect — you send money to a VPA. This is

what you use for refunds, creator payouts, gig-worker disbursals, and affiliate

commissions. The main compliance point: **your aggregator must be

PPI-licensed or an RBI-authorised PA-PG** to originate push payments; if

you are building on a neo-bank API, they’ll already be licensed.

5. Webhooks — the only source of truth

UPI is asynchronous. Treat the initial HTTP response as “accepted for

processing” only. Your webhook handler must:

  • Verify the HMAC-SHA256 signature (see our webhook-signature guide).
  • Be idempotent on merchant_txn_id — the same event can arrive 2–3 times.
  • Respond with HTTP 200 within 5 seconds; process asynchronously if needed.
  • Handle the terminal statuses: SUCCESS, FAILED, EXPIRED, DECLINED.

// Node.js — minimal idempotent handler
app.post('/webhooks/upi', express.raw({type:'application/json'}), (req, res) => {
const sig = req.get('X-NxtB-Signature');
const expected = crypto.createHmac('sha256', WEBHOOK_SECRET)
.update(req.body).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
return res.status(401).end();
}
const evt = JSON.parse(req.body);
if (await alreadyProcessed(evt.id)) return res.sendStatus(200);
await processEvent(evt); // update DB, notify customer, etc.
await markProcessed(evt.id);
res.sendStatus(200);
});

6. AutoPay mandates

Recurring subscriptions (OTT, SaaS, insurance premiums) use **UPI

AutoPay** — a mandate the customer approves once, after which you can

debit up to a pre-agreed cap on a schedule. Three endpoints:

/mandate/create, /mandate/execute,

/mandate/revoke. Key constraints set by NPCI (January 2026 guidelines):

  • Maximum mandate amount per debit: 15,000 INR (higher limits require additional factor of auth).
  • Pre-debit notification must be sent to the customer ≥24 hours in advance.
  • Mandate state is versioned — always store the mandate_id and version.

7. Common failure modes & their real meanings

NPCI code
What it really means
Your action

ZA
Transaction declined by remitter bank
Surface to user; no retry.

ZM
Invalid UPI PIN (3rd attempt locks VPA for ~24h)
Stop retrying; ask user to re-enter PIN in their UPI app.

U30
Debit has been done, but credit is pending at beneficiary bank
Keep the txn “processing”; it’ll resolve in T+1.

XH
Remitter bank not available
Safe to retry after 30 seconds.

U69
Collect expired
Create a new collect; do not auto-retry the old one.

8. Production checklist

  • ☐ HMAC verification on every webhook
  • ☐ Idempotency store with ≥ 7-day retention
  • ☐ T+1 reconciliation cron against settlement file
  • ☐ Prometheus metrics: collect-p50, collect-p99, webhook-lag, decline-rate by code
  • ☐ Playbook for “U30 stuck” and “mandate-version mismatch”
  • ☐ RBI data-localisation: payment data stored only in India-region infra

Further reading on NxtBanking

← All insights

Ready when you are

Go live on NxtBanking rails.

Tell us which rails you need — payouts, AEPS, BBPS, UPI, KYC, or the full stack. Our solution architects map the right APIs to your use case, usually within a day.