developer

How to Handle Network Timeouts and Pending Payments in UPI Transactions

Master error-handling for UPI payment timeouts and pending transactions. Step-by-step runbook for dual-inquiry polling, delayed webhooks, and auto-reconciliation.

VT VyaparGateway Team Payments & Compliance 2 min read
How to Handle Network Timeouts and Pending Payments in UPI Transactions guide
handle upi pending status upi transaction timeout recovery webhook delay fallback logic payment reliability VyaparGateway

Every engineering team running payments in India eventually encounters the dreaded “Schrödinger’s Payment”: the customer’s bank SMS states that ₹3,500 has been debited, but your website checkout displays “Payment Timed Out” because the browser disconnected before the callback arrived.

In high-volume systems, handling edge cases—network timeouts, dropped mobile connections, and delayed bank webhooks—is what separates brittle payment forms from enterprise-grade financial infrastructure. Here is the architectural runbook.


The Dreaded ‘Schrödinger’s Payment’ Scenario

Direct Answer: Never treat a network timeout as an immediate payment failure. In UPI, debit from the customer and credit to the merchant are decoupled across multiple intermediary bank switches; if a connection drops, your system must hold the order in a temporary PENDING_VERIFICATION state and execute automated status-inquiry polling before taking irreversible inventory actions.

Failing to implement this pattern leads to customer service nightmares: the customer is charged, your store cancels the order, and the customer angrily files a bank chargeback or fraud report on the Section 1930 portal.


Why UPI Network Timeouts Occur

A standard UPI transaction touches at least five distinct network nodes in under 3 seconds:

[ Customer Phone ] ──► [ Remitter PSP (GPay/PhonePe) ]
                               │
                               ▼
                    [ NPCI Central Switch ]
                               │
                               ▼
                   [ Remitter Issuing Bank (SBI) ] ── (Account Debited)
                               │
                               ▼
                   [ Beneficiary Bank (HDFC) ]     ── (Account Credited)
                               │
                               ▼
                 [ Merchant Webhook Listener ]

If an intermittent telecom lag occurs between the Beneficiary Bank and the Merchant Server, the bank transfer succeeded, but your frontend timed out.


The 4-Step Automated Reconciliation Runbook

To handle timeouts with zero human intervention:

[ Client Timeout at 15 Minutes ] ──► Move status to PENDING_VERIFICATION
                                           │
                                           ▼
                                [ Schedule Cron Retries: ]
                                ├── T + 1 min:  POST /check_order_status
                                ├── T + 5 min:  POST /check_order_status
                                ├── T + 15 min: POST /check_order_status
                                └── T + 30 min: Final Bank Reconciliation

The Background Status Polling Worker (Node.js Example):

import axios from 'axios';

async function reconcilePendingOrder(clientTxnId) {
  try {
    const response = await axios.post(
      'https://vyapargateway.com/api/v1/check_order_status',
      { client_txn_id: clientTxnId },
      { headers: { 'X-API-Key': process.env.VYAPAR_API_KEY } }
    );

    const { status, utr, amount } = response.data;

    if (status === 'SUCCESS') {
      // Payment confirmed by bank switch!
      await markOrderCompleted(clientTxnId, utr);
      await sendOrderConfirmationSms(clientTxnId);
      return { resolved: true, status: 'COMPLETED' };
    } 
    
    if (status === 'FAILED') {
      // Bank confirms transaction was reversed/aborted
      await markOrderFailed(clientTxnId);
      return { resolved: true, status: 'FAILED' };
    }

    // Still pending at bank switch: will retry on next cycle
    return { resolved: false, status: 'PENDING' };
  } catch (error) {
    console.error(`Recon check failed for ${clientTxnId}:`, error.message);
    return { resolved: false, error };
  }
}

Handling Late Webhooks on Expired Orders

What happens if a customer pays 20 minutes after your 15-minute checkout timer expired, and a valid payment.success webhook arrives?

The Safe Fulfillment Logic:

  1. Check Inventory: If the purchased items are still in stock, seamlessly revive the expired order to COMPLETED and trigger dispatch.
  2. Auto-Refund if Stock Depleted: If the inventory was already released to another customer, trigger an automated one-click UPI refund:
    {
      "action": "AUTO_REFUND",
      "reason": "ORDER_EXPIRED_OUT_OF_STOCK",
      "amount": 1499.00,
      "original_utr": "428109482103"
    }
  3. Immediately notify the customer via WhatsApp: “Your payment was received after the session expired. A full refund has been credited back to your bank account.”

Building Customer Trust During Debit Uncertainty

Frontend UX during timeouts makes or breaks brand reputation:

  • Avoid Red “Failed” Screens: If status is unconfirmed, render an amber screen: “Payment is being verified with your bank. Please do not pay again. We will confirm your order via SMS within 10 minutes.”
  • Provide a 1-Click “I Have Been Debited” Button: Allows the customer to enter their 12-digit UPI reference number (UTR) from their bank SMS to trigger instant manual server-side reconciliation.

Read our developer guide on Matching UTR Numbers with Orders to build self-healing checkout workflows.

Direct answers

Frequently asked questions

Why do UPI transactions get stuck in a 'PENDING' status?
A UPI payment enters PENDING when the customer's issuing bank successfully debits the funds, but high network latency or an intermittent switch timeout prevents the remitting bank from receiving an immediate cryptographic acknowledgment from the NPCI or the merchant's acquiring bank.
What should a merchant website do when a UPI payment times out?
Never mark a timed-out transaction as immediately FAILED. Instead, display a 'Payment Processing' status, retain the order in PENDING, and schedule automated status inquiries (polling) at 1, 5, 15, and 30-minute intervals before triggering resolution.
How does dual-inquiry reconciliation resolve pending payments?
Dual-inquiry invokes the payment provider's server-to-server check_order_status API using the merchant client_txn_id, reconciling the final bank settlement status regardless of whether the customer's browser disconnected.

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.