← All notes

Fintech

UPI checkout reliability is a timeout problem

Most failed UPI payments are not declines. They are collect requests that expired, callbacks that never arrived, and status checks nobody made.

  • Invexa Technologies
  • 3 min read

NPCI processes well over 16 billion UPI transactions in a typical month, and the published technical decline rate hovers around 0.7 to 1 percent. That number sounds comfortable until you sit with a merchant’s own dashboard, where checkout success on a bad evening reads 88 percent. The gap between the rail’s decline rate and the merchant’s success rate is almost entirely engineering, and most of it is about time.

A UPI payment is not a request and a response. It is a request, a human action on a phone that may take thirty seconds or three minutes, a bank debit, an NPCI switch hop, and a callback that arrives whenever it arrives. Teams that model it as a synchronous call ship a checkout that lies to customers.

Where The Seconds Actually Go

An intent flow on a good network completes in 8 to 15 seconds from app switch to callback. A collect request has a mandate window that can stretch to five minutes, and customers routinely open the app, get distracted, and approve at minute four. Meanwhile the PSP webhook may be delayed by seconds or by minutes during peak load, typically the 8pm to 11pm window when salary-day traffic and quick commerce orders overlap.

The failure modes that show up in production logs are consistent:

  • The premature failure screen. The checkout gives up at 30 seconds, tells the customer the payment failed, and then the debit lands. The customer pays twice or calls support angry.
  • The missing callback. The PSP fires the webhook once, your server is redeploying, and the order sits in pending forever because nothing ever asks again.
  • The duplicate order. A retry without an idempotency key creates a second payment object against the same cart.
  • The stale mandate. A collect request expires server-side but the UI still shows a spinner, so the customer approves nothing and leaves.

Build For Reconciliation, Not For Speed

The fix is not a faster integration. It is treating the payment status as something you own and continuously converge on. Three habits do most of the work.

Poll on a decaying schedule. Fire a status check at 5, 10, 20, 40, and 90 seconds, then every 30 seconds until the mandate window closes. NPCI and PSP status APIs are cheap compared to a support ticket, and rate limits are generous enough for this pattern at SME volumes.

Make every write idempotent. One key per cart attempt, enforced with a unique index in the database rather than an application check, so that a retry storm during a network blip cannot mint two orders.

Treat the webhook as a hint, not a source of truth. When it arrives, verify against the status API before releasing goods. Signed payloads get spoofed less often than they get replayed.

What Customers Should See

Reliability that customers perceive is mostly about honest UI states. Show “waiting for your approval” with the actual remaining mandate time rather than an indefinite spinner. Distinguish “we do not know yet” from “this failed”, because a wrong failure message triggers a second payment attempt and turns one problem into a refund cycle that takes three to five working days.

For a merchant doing 20,000 orders a month, moving checkout success from 88 to 95 percent is 1,400 recovered orders. None of that required a change on the rail.

At Invexa, we start payment work by mapping the timeout budget and the reconciliation path before writing a single API call, because a checkout that cannot explain its own state is not finished.

Next step

Have a project in mind?

A 30-minute call is usually enough to know whether we are the right team for it. If we are not, we will say so.

Start a project

Replies within one working day

Start a project