How to Implement UPI & Razorpay Payment Gateway in Android & PHP
Unified Payments Interface (UPI) processes billions of transactions every month, dominating digital commerce across India and expanding internationally. For Android developers targeting the Indian consumer base, seamless UPI Intent flow and reliable payment gateway integration (like Razorpay) are non-negotiable requirements. Here is how to engineer a secure payment pipeline.

1. The Two Integration Approaches

  1. Direct UPI Intent URI (Zero Gateway Fees): Fires an android.intent.action.VIEW intent with a upi://pay URI. Launches installed apps (GPay, PhonePe, BHIM) directly to pay your merchant VPA.
  2. Payment Gateway SDK (Razorpay / Cashfree): Provides automated reconciliation, credit cards, debit cards, net banking, and automatic webhook verification.

2. Approach A: Direct UPI Intent in Kotlin

Construct a compliant NPCI UPI payment URI and launch the system app chooser:

import android.content.Intent
import android.net.Uri
import androidx.activity.result.contract.ActivityResultContracts

fun initiateUpiPayment(
    vpa: String = "mohit@upi",
    merchantName: String = "JMD WORLD",
    txnId: String,
    amount: Double,
    note: String = "Software License Order"
) {
    val uri = Uri.parse("upi://pay").buildUpon()
        .appendQueryParameter("pa", vpa) // Payee VPA
        .appendQueryParameter("pn", merchantName) // Payee Name
        .appendQueryParameter("tr", txnId) // Transaction Ref ID
        .appendQueryParameter("am", String.format("%.2f", amount)) // Amount
        .appendQueryParameter("cu", "INR") // Currency
        .appendQueryParameter("tn", note) // Note
        .build()

    val upiIntent = Intent(Intent.ACTION_VIEW, uri)
    val chooser = Intent.createChooser(upiIntent, "Pay with UPI Application")
    // Launch activity for result
}

3. Approach B: Razorpay Standard Checkout SDK

Add the dependency to your build.gradle.kts:

implementation("com.razorpay:checkout:1.6.36")

In your Checkout Activity:

import com.razorpay.Checkout
import com.razorpay.PaymentResultListener
import org.json.JSONObject

class PaymentActivity : AppCompatActivity(), PaymentResultListener {

    fun startRazorpayPayment(orderId: String, amountInPaise: Int) {
        val checkout = Checkout()
        checkout.setKeyID("rzp_live_YourKeyHere")

        val options = JSONObject().apply {
            put("name", "JMD WORLD")
            put("description", "Enterprise Software Services")
            put("currency", "INR")
            put("amount", amountInPaise) // e.g. 50000 = 500.00 INR
            put("order_id", orderId)
            put("prefill", JSONObject().apply {
                put("email", "client@example.com")
                put("contact", "8530008980")
            })
        }

        checkout.open(this, options)
    }

    override fun onPaymentSuccess(razorpayPaymentId: String?) {
        // Confirm with your PHP backend server
    }

    override fun onPaymentError(code: Int, response: String?) {
        // Handle cancellation or payment failure
    }
}

4. Server-Side Signature Verification in PHP

Never rely on client-side success callbacks alone! Attackers can forge onPaymentSuccess. Always verify the HMAC SHA-256 signature on your PHP server before fulfilling orders:

<?php
$orderId = $_POST['razorpay_order_id'];
$paymentId = $_POST['razorpay_payment_id'];
$signature = $_POST['razorpay_signature'];
$secret = 'YourRazorpayKeySecret';

$expectedSignature = hash_hmac('sha256', "$orderId|$paymentId", $secret);

if (hash_equals($expectedSignature, $signature)) {
    // Payment authentic: Update database status to 'completed'
    echo json_encode(['verified' => true]);
} else {
    http_response_code(400);
    echo json_encode(['verified' => false, 'error' => 'Invalid payment signature']);
}
?>

Conclusion

Combining the frictionless customer experience of UPI Intent on the front-end with rigorous HMAC signature validation on your backend produces an enterprise-grade fintech integration that protects both merchant revenue and buyer trust.

Share this Guide Help colleagues and developers learn from this article
In-Article Sponsored Content
Mohit Kumaar
AUTHOR & FOUNDER

Mohit Kumaar

Founder & CEO of JMD WORLD with 8+ Years of industrial software engineering leadership (active since 2018). Creator and manager of 500+ production Google Play applications (proprietary & client solutions) and architect of apps.jmdworld.in. Operating from Pune & Mumbai under MSME Registration: UDYAM-MH-26-1071218 and D-U-N-SĀ® 581707246.

Previous Guide

Android App Security: How to Protect Your App from Decompilation & Hacking šŸ›”ļøšŸ”

App Security
Next Guide

Android MVVM vs MVI Architecture: Choosing the Right Pattern in 2026

Software Architecture
Recommended For You Ads by Google

Comments (0)

No comments yet. Share your thoughts below!

Leave a Comment

Share your thoughts or questions. Your email address remains private.