Almost every consumer app built for the Indian market runs into the same early decision: how does a user actually pay? In most other markets, cards dominate. In India, UPI does — it's the payment method users expect to see first, not as an alternative to cards but as the default. Getting this integration right is one of the highest-leverage pieces of technical work in an Indian app, because a broken or clunky payment flow shows up directly as lost revenue at the exact moment a user has already decided to buy.
This guide walks through how UPI and payment gateway integration actually works for teams building apps in India, including the parts that don't show up in a quick-start tutorial — reconciliation, failure handling, and the compliance basics every team needs to get right. It's a natural next step for teams that have already scoped out what it costs to build an eCommerce app in India, since payments are usually one of the largest integration line items in that budget.
UPI itself is the underlying real-time payment rail, built and governed by NPCI, that lets money move directly between bank accounts using a UPI ID or QR code. Most apps don't integrate with UPI directly — that path requires a direct bank tie-up and a much heavier compliance and certification process. Instead, the vast majority of startups integrate through a payment gateway or aggregator that exposes UPI, cards, net banking, and wallets behind a single, much simpler API, and handles the bank-side complexity on the startup's behalf. Direct UPI integration generally only makes sense once transaction volume is large enough to justify negotiating better rates than an aggregator can offer.
Consider a food delivery startup building its ordering app. A customer places an order, selects UPI at checkout, and is redirected to their UPI app to approve the payment. At this point, three different things can happen: the payment succeeds instantly, it fails outright (insufficient balance, wrong PIN), or — the case most tutorials skip — it enters a pending state where the customer's bank hasn't confirmed the outcome yet, sometimes for a few minutes.
A poorly built integration treats "pending" the same as "failed," shows the customer an error, and lets them retry — at which point the original payment might still go through, and the customer gets charged twice. A properly built integration shows a clear pending state, doesn't let the customer submit a duplicate order, and relies on a webhook from the payment gateway to update the order the moment the bank confirms the final result. That single design decision — handling the pending state correctly — is usually the difference between a payments system that quietly works and one that generates a steady stream of "I was charged twice" support tickets.
For example, an early-stage app processing a modest volume of daily transactions could reasonably expect a well-implemented UPI flow to convert noticeably better than a cards-only checkout, since UPI is often the payment method Indian users reach for first — the actual lift depends heavily on the specific user base and product, so this should be treated as a directional expectation rather than a guaranteed outcome.
The gateway handles the payment. Your app is responsible for handling every state that payment can be in — and most payment bugs live in the states teams didn't plan for.
Many apps built in India eventually need to support customers or partners outside the country, and this is where a single-gateway approach can start to show its limits. Not every gateway that handles UPI well also offers competitive rates or reliable support for international cards and currencies. Teams expecting cross-border volume early should evaluate this upfront rather than migrating gateways later, since a gateway migration touches every part of the payment state machine described above and is far more disruptive once real transaction history and reconciliation processes are already built around the original provider.
Some teams solve this by using one gateway for domestic UPI and card volume and a second, specialized provider for international payments, routing based on the customer's detected region. This adds integration complexity but often produces better success rates and lower fees than forcing all traffic through a single provider that isn't equally strong at both.
Refund handling is another area that's easy to underbuild in the initial rush to ship checkout. A refund isn't just the reverse of a payment — it needs its own state tracking, its own webhook handling for confirmation, and clear customer-facing messaging about how long it will take, since UPI and card refunds don't always settle on the same timeline. Teams that treat refunds as an edge case to handle manually through the payment gateway's dashboard tend to find that approach breaks down quickly once transaction volume grows past a handful of requests a week. Building a basic in-app refund flow, even a simple one, early on saves considerable manual support overhead later.
Relying on a compliant gateway handles most of the regulatory burden, but a few practices remain squarely the app team's responsibility. Payment-related API endpoints should have stricter rate limiting than the rest of the app, since they're a common target for automated abuse. Webhook endpoints need signature verification to confirm a request genuinely came from the payment gateway and wasn't spoofed by an attacker who discovered the endpoint URL. And any logs that capture payment-related data should be reviewed to make sure they aren't inadvertently storing sensitive fields the gateway explicitly tells you not to store, such as raw card numbers or UPI PINs.
These aren't exotic requirements, but they're easy to overlook when a team is focused on getting the happy-path checkout flow working. Building them in during the initial integration is considerably cheaper than retrofitting them after a security review flags a gap.
Payment integration is one of those areas where the difference between "it works in the demo" and "it works in production" is almost entirely about edge cases: pending states, duplicate webhooks, and reconciliation gaps that only show up under real transaction volume. Getting the fundamentals right the first time — a clear state machine, idempotent webhook handling, and daily reconciliation — saves a startup from a category of bugs that are expensive to fix retroactively once real money and real customer trust are involved. For teams scoping this work alongside the rest of their mobile app development roadmap, it's worth treating payments as core infrastructure from day one, not a feature to bolt on right before launch.