Comments
Sign in to join the conversation
Sign in to join the conversation
Unified Payments Interface (UPI) has revolutionized digital payments in India, processing billions of transactions monthly. For any "India-first" business, prioritizing UPI isn't just an option—it's a necessity.
While gateways like Razorpay handle the complexity, understanding the underlying Intent Flow (Deep Linking) is crucial for optimizing conversion rates on mobile devices.
On a desktop, a user enters their VPA (e.g., user@upi) and gets a collect request on their phone.
However, on mobile, asking a user to switch apps, approve a request, and switch back leads to high drop-offs.
The Intent Flow allows your web app to directly trigger installed UPI apps (PhonePe, GPay, Paytm) on the user's device.
upi://pay?pa=merchant@bank&pn=MerchantName&tr=TransactionID&am=100.00&cu=INR
<a href="...">).If you are building a P2P app or have a direct banking integration (rare for small startups), you might construct this link manually. However, most developers use a gateway's "Seamless UPI" flow.
Here is how you handle the "Intent" mode if you were redirecting users manually (e.g., for a donation link or P2P transfer).
import React from 'react';
const UPILink = ({ amount, vpa, name }) => {
// Construct the UPI Deep Link
const upiLink = `upi://pay?pa=${vpa}&pn=${encodeURIComponent(name)}&am=${amount}&cu=INR`;
return (
<div className="p-4 border rounded-lg shadow-md max-w-sm mx-auto mt-10">
<h2 className="text-xl font-bold mb-2">Pay via UPI</h2>
<p className="text-gray-600 mb-4">Click below to pay ₹{amount}</p>
{/*
On mobile, this will open the sheet to choose an app (GPay, PhonePe).
On desktop, this will likely do nothing or prompt to open an app.
*/}
<a
href={upiLink}
className="block w-full bg-green-600 text-white text-center py-3 rounded-lg font-bold"
>
Pay ₹{amount} with UPI App
</a>
<p className="text-xs text-gray-400 mt-2 text-center">
Only works on mobile devices with UPI apps installed.
</p>
</div>
);
};
export default UPILink;
PhonePe has emerged as a massive player. If you want to integrate their Payment Gateway directly (bypassing aggregators):
PhonePe requires a base64 encoded payload and a checksum (X-VERIFY) header.
import base64
import hashlib
import json
import requests
SALT_KEY = "your_salt_key"
SALT_INDEX = "1"
def initiate_phonepe_payment(amount_in_paise, transaction_id, user_id):
payload = {
"merchantId": "YOUR_MERCHANT_ID",
"merchantTransactionId": transaction_id,
"merchantUserId": user_id,
"amount": amount_in_paise,
"redirectUrl": "https://yourwebsite.com/api/payment/callback",
"redirectMode": "POST",
"callbackUrl": "https://yourwebsite.com/api/payment/webhook",
"mobileNumber": "9999999999",
For Indian businesses:
Choosing the right stack depends on whether you need a quick setup (Razorpay) or deeper direct integration (PhonePe/UPI Direct).