UPI Payment Implementation Examples
A step by step UPI Payment Implementation example.
What is UPI Payment
UPI stands for
Unified Payments Interface
.
It is an instant real-time payment system developed by National Payments Corporation of India. The interface facilitates inter-bank peer-to-peer and person-to-merchant transactions. It is used on mobile devices to instantly transfer funds between two bank accounts.
UPI Payment Examples
PatilShreyas/EasyUpiPayment-Android
EasyUpiPayment
is an Android Library to implement UPI Payment integration easily in Android App.
Easy UPI Payment - Android Library
It is available in Maven:
And supports API 19+
.
Full Example
Follow these steps to create a full UPI Payment Implementation example.
Step 1. Our Android Manifest
We will need to look at our AndroidManifest.xml
.
(a). AndroidManifest.xml
Our
AndroidManifest
file.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.easyupipayment">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".kotlin.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Step 2. Design Layouts
In Android we design our UI interfaces using XML. So let's create the following layouts:
(a). activity_main.xml
Our
activity_main
layout.
Inside your /res/layout/
directory create an xml layout file named activity_main.xml
.
Design your XML layout using the following 9 UI widgets and ViewGroups:
ScrollView
EditText
TextView
RadioGroup
RadioButton
Button
ImageView
LinearLayout
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp"
tools:context=".java.MainActivity">
<EditText
android:id="@+id/field_vpa"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="VPA" />
<EditText
android:id="@+id/field_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Payee Name" />
<EditText
android:id="@+id/field_payee_merchant_code"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Payee Merchant Code" />
<EditText
android:id="@+id/field_transaction_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Transaction ID" />
<EditText
android:id="@+id/field_transaction_ref_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Transaction Ref ID" />
<EditText
android:id="@+id/field_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Description" />
<EditText
android:id="@+id/field_amount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Amount (XX.XX)" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="UPI App :"
android:textColor="#000000"
android:textSize="18sp" />
<RadioGroup
android:id="@+id/radioAppChoice"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/app_default"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="Default" />
<RadioButton
android:id="@+id/app_amazonpay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="AmazonPay" />
<RadioButton
android:id="@+id/app_bhim_upi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BHIM UPI" />
<RadioButton
android:id="@+id/app_google_pay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Google Pay" />
<RadioButton
android:id="@+id/app_phonepe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PhonePe" />
<RadioButton
android:id="@+id/app_paytm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PayTm" />
</RadioGroup>
<Button
android:id="@+id/button_pay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Pay with UPI" />
<ImageView
android:id="@+id/imageView"
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_gravity="center" />
<TextView
android:id="@+id/textView_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="16dp"
android:text="Click above button to Pay"
android:textColor="#000000"
android:textSize="19sp" />
</LinearLayout>
</ScrollView>
Step 3. Write Code
Finally we need to write our code as follows:
(a). MainActivity.kt
Our
MainActivity
class.
Create a Kotlin file named MainActivity.kt
.
We will then add imports from android SDK and other packages. Here are some of the imports we will use in this class:
Bundle
from theandroid.os
package.Log
from theandroid.util
package.Toast
from theandroid.widget
package.AppCompatActivity
from theandroidx.appcompat.app
package.*
from thekotlinx.android.synthetic.main.activity_main
package.
Next create a class that derives from AppCompatActivity
and add its contents as follows:
We will be overriding the following functions:
onCreate(savedInstanceState: Bundle?)
.onTransactionCompleted(transactionDetails: TransactionDetails)
.onTransactionCancelled()
.
We will be creating the following methods:
initViews()
.pay()
.onTransactionSuccess()
.onTransactionSubmitted()
.onTransactionFailed()
.toast(parameter)
- Let's pass aString
object as a parameter.onDestroy()
.
(a). Our onTransactionFailed()
function
Write the onTransactionFailed()
function as follows:
private fun onTransactionFailed() {
// Payment Failed
toast("Failed")
imageView.setImageResource(R.drawable.ic_failed)
}
(b). Our onTransactionSuccess()
function
Write the onTransactionSuccess()
function as follows:
private fun onTransactionSuccess() {
// Payment Success
toast("Success")
imageView.setImageResource(R.drawable.ic_success)
}
(c). Our onTransactionSubmitted()
function
Write the onTransactionSubmitted()
function as follows:
private fun onTransactionSubmitted() {
// Payment Pending
toast("Pending | Submitted")
imageView.setImageResource(R.drawable.ic_success)
}
(d). Our initViews()
function
Write the initViews()
function as follows:
private fun initViews() {
val transactionId = "TID" + System.currentTimeMillis()
field_transaction_id.setText(transactionId)
field_transaction_ref_id.setText(transactionId)
// Setup click listener for Pay button
button_pay.setOnClickListener { pay() }
}
(e). Our onDestroy()
function
Write the onDestroy()
function as follows:
// override fun onDestroy() {
// super.onDestroy()
// easyUpiPayment.removePaymentStatusListener()
// }
}
(f). Our pay()
function
Write the pay()
function as follows:
private fun pay() {
val payeeVpa = field_vpa.text.toString()
val payeeName = field_name.text.toString()
val transactionId = field_transaction_id.text.toString()
val transactionRefId = field_transaction_ref_id.text.toString()
val payeeMerchantCode = field_payee_merchant_code.text.toString()
val description = field_description.text.toString()
val amount = field_amount.text.toString()
val paymentAppChoice = radioAppChoice
val paymentApp = when (paymentAppChoice.checkedRadioButtonId) {
R.id.app_default -> PaymentApp.ALL
R.id.app_amazonpay -> PaymentApp.AMAZON_PAY
R.id.app_bhim_upi -> PaymentApp.BHIM_UPI
R.id.app_google_pay -> PaymentApp.GOOGLE_PAY
R.id.app_phonepe -> PaymentApp.PHONE_PE
R.id.app_paytm -> PaymentApp.PAYTM
else -> throw IllegalStateException("Unexpected value: " + paymentAppChoice.id)
}
try {
// START PAYMENT INITIALIZATION
easyUpiPayment = EasyUpiPayment(this) {
this.paymentApp = paymentApp
this.payeeVpa = payeeVpa
this.payeeName = payeeName
this.transactionId = transactionId
this.transactionRefId = transactionRefId
this.payeeMerchantCode = payeeMerchantCode
this.description = description
this.amount = amount
}
// END INITIALIZATION
// Register Listener for Events
easyUpiPayment.setPaymentStatusListener(this)
// Start payment / transaction
easyUpiPayment.startPayment()
} catch (e: Exception) {
e.printStackTrace()
toast("Error: ${e.message}")
}
}
(g). Our toast()
function
Write the toast()
function as follows:
Here is the full code:
package replace_with_your_package_name
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.easyupipayment.R
import dev.shreyaspatil.easyupipayment.EasyUpiPayment
import dev.shreyaspatil.easyupipayment.listener.PaymentStatusListener
import dev.shreyaspatil.easyupipayment.model.PaymentApp
import dev.shreyaspatil.easyupipayment.model.TransactionDetails
import dev.shreyaspatil.easyupipayment.model.TransactionStatus
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity(), PaymentStatusListener {
private lateinit var easyUpiPayment: EasyUpiPayment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initViews()
}
private fun initViews() {
val transactionId = "TID" + System.currentTimeMillis()
field_transaction_id.setText(transactionId)
field_transaction_ref_id.setText(transactionId)
// Setup click listener for Pay button
button_pay.setOnClickListener { pay() }
}
private fun pay() {
val payeeVpa = field_vpa.text.toString()
val payeeName = field_name.text.toString()
val transactionId = field_transaction_id.text.toString()
val transactionRefId = field_transaction_ref_id.text.toString()
val payeeMerchantCode = field_payee_merchant_code.text.toString()
val description = field_description.text.toString()
val amount = field_amount.text.toString()
val paymentAppChoice = radioAppChoice
val paymentApp = when (paymentAppChoice.checkedRadioButtonId) {
R.id.app_default -> PaymentApp.ALL
R.id.app_amazonpay -> PaymentApp.AMAZON_PAY
R.id.app_bhim_upi -> PaymentApp.BHIM_UPI
R.id.app_google_pay -> PaymentApp.GOOGLE_PAY
R.id.app_phonepe -> PaymentApp.PHONE_PE
R.id.app_paytm -> PaymentApp.PAYTM
else -> throw IllegalStateException("Unexpected value: " + paymentAppChoice.id)
}
try {
// START PAYMENT INITIALIZATION
easyUpiPayment = EasyUpiPayment(this) {
this.paymentApp = paymentApp
this.payeeVpa = payeeVpa
this.payeeName = payeeName
this.transactionId = transactionId
this.transactionRefId = transactionRefId
this.payeeMerchantCode = payeeMerchantCode
this.description = description
this.amount = amount
}
// END INITIALIZATION
// Register Listener for Events
easyUpiPayment.setPaymentStatusListener(this)
// Start payment / transaction
easyUpiPayment.startPayment()
} catch (e: Exception) {
e.printStackTrace()
toast("Error: ${e.message}")
}
}
override fun onTransactionCompleted(transactionDetails: TransactionDetails) {
// Transaction Completed
Log.d("TransactionDetails", transactionDetails.toString())
textView_status.text = transactionDetails.toString()
when (transactionDetails.transactionStatus) {
TransactionStatus.SUCCESS -> onTransactionSuccess()
TransactionStatus.FAILURE -> onTransactionFailed()
TransactionStatus.SUBMITTED -> onTransactionSubmitted()
}
}
override fun onTransactionCancelled() {
// Payment Cancelled by User
toast("Cancelled by user")
imageView.setImageResource(R.drawable.ic_failed)
}
private fun onTransactionSuccess() {
// Payment Success
toast("Success")
imageView.setImageResource(R.drawable.ic_success)
}
private fun onTransactionSubmitted() {
// Payment Pending
toast("Pending | Submitted")
imageView.setImageResource(R.drawable.ic_success)
}
private fun onTransactionFailed() {
// Payment Failed
toast("Failed")
imageView.setImageResource(R.drawable.ic_failed)
}
private fun toast(message: String) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
// Uncomment this if you have inherited [android.app.Activity] and not [androidx.appcompat.app.AppCompatActivity]
//
// override fun onDestroy() {
// super.onDestroy()
// easyUpiPayment.removePaymentStatusListener()
// }
}
Reference
Download the code below:
No. | Link |
---|---|
1. | Download Full Code |
2. | Read more here. |
3. | Follow code author here. |