RAZOR PAY Payment Gateway Integration in Android Application (Including App Demo Source Code) Example
In this article, we learn to integrate the Razor Pay Payment gateway in our android app. Razor Pay is a widely used payment gateway in india and they support a number of payment mehtods like users can pay by using credit cards, debit cards, wallet money, UPI payments, etc. We will also provide you demo app source code.
In this tutorial am going to show you how to integrate the Razor-Pay Payment gateway in android studio. I will also explain in detail every bit of the code. In this tutorial, I also provided an app demo source code.
Before you integrate the Razor-Pay payment gateway in the android app you need to first have a developer account. This means that you should go to the Razor-Pay website to create your own developer account which you will be using to receive payments in your app.
Steps to integrate the Razor-Pay in android studio
The first thing you have to do is to open your app-level build.gradle file and add the code below inside the dependences
implementation 'com.razorpay:checkout:1.5.16'
The next step is to go to the manifrest.xml and add the below inside the application tag
<meta-data
android:name="com.razorpay.ApiKey"
android:value="@string/razor_key"/>
///<application>
<meta-data
android:name="com.razorpay.ApiKey"
android:value="@string/razor_key"/>
</application>///
Note the razor-pay key is in a string file in the manifest
How to get your razor-pay key
Simply go to your razor-pay dashboard and then select settings and there select API in Api section you will see your default Razor-Pay Key. In order to receive real payments from your app users, you will need to activate your Razor pay live Payment Mode. Put in mind that you have to provide some documents when requesting a razor-pay live key.
Designing the UI
Now here we are going to be designing the app UI to see how it works. So in this tutorial, I am just trying to show you how to integrate the Razor-Pay in android studio, therefore the app design is not going to be that complex. I designed a layout where you want to buy some products and when you clicked on the buy button it will automatically take you to the Razor-Pay payment gateway to make your purchase payment. The values in the layout are not dynamic values they are fixed values; I just want to illustrate how it works.
For this project we have created only one Activity Called MainActivity.java and source code of MainActivity XML file is given bellow
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parent_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/grey">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginTop="10dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.core.widget.NestedScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scrollbars="none"
android:scrollingCache="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="18dp"
android:layout_marginEnd="18dp"
app:cardBackgroundColor="@android:color/white"
app:cardCornerRadius="20dp"
app:cardElevation="2dp"
app:cardUseCompatPadding="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
app:layout_constraintEnd_toStartOf="@+id/imageView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Fresh Tomato 1KG"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="@android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="₹20"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="@color/lightGreen"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_marginTop="8dp"
android:orientation="horizontal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="18dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:tint="@color/greyQuantityColor"
app:srcCompat="@drawable/ic_remove" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/space_15_dp"
android:layout_marginRight="@dimen/space_15_dp"
android:gravity="center_vertical"
android:text="1"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
android:textColor="@color/greyQuantityColor"
app:fontFamily="sans-serif-medium" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="@dimen/space_35_dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:tint="@color/greyQuantityColor"
app:srcCompat="@drawable/ic_add" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="@+id/imageView"
android:layout_width="120dp"
android:layout_height="120dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/tomato" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="18dp"
android:layout_marginEnd="18dp"
app:cardBackgroundColor="@android:color/white"
app:cardCornerRadius="20dp"
app:cardElevation="2dp"
app:cardUseCompatPadding="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
app:layout_constraintEnd_toStartOf="@+id/imageView1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/textView12"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Fresh Carrot 1KG"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="@android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="₹10"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="@color/lightGreen"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView12" />
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_marginTop="8dp"
android:orientation="horizontal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView4">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="18dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:tint="@color/greyQuantityColor"
app:srcCompat="@drawable/ic_remove" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/space_15_dp"
android:layout_marginRight="@dimen/space_15_dp"
android:gravity="center_vertical"
android:text="1"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
android:textColor="@color/greyQuantityColor"
app:fontFamily="sans-serif-medium" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="@dimen/space_35_dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:tint="@color/greyQuantityColor"
app:srcCompat="@drawable/ic_add" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="@+id/imageView1"
android:layout_width="120dp"
android:layout_height="120dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/carrot" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="18dp"
android:layout_marginEnd="18dp"
app:cardBackgroundColor="@android:color/white"
app:cardCornerRadius="20dp"
app:cardElevation="2dp"
app:cardUseCompatPadding="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
app:layout_constraintEnd_toStartOf="@+id/imageView2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/textView10"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Fresh cauliflower 1KG"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="@android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="₹18"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="@color/lightGreen"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView10" />
<LinearLayout
android:id="@+id/linearLayou3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_marginTop="8dp"
android:orientation="horizontal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView6">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="18dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:tint="@color/greyQuantityColor"
app:srcCompat="@drawable/ic_remove" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/space_15_dp"
android:layout_marginRight="@dimen/space_15_dp"
android:gravity="center_vertical"
android:text="1"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
android:textColor="@color/greyQuantityColor"
app:fontFamily="sans-serif-medium" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="@dimen/space_35_dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:tint="@color/greyQuantityColor"
app:srcCompat="@drawable/ic_add" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="@+id/imageView2"
android:layout_width="120dp"
android:layout_height="120dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/cauliflower" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="@dimen/space_10_dp"
android:paddingBottom="@dimen/space_18_dp"
android:paddingLeft="@dimen/space_20_dp"
android:paddingRight="@dimen/space_20_dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/space_10_dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Total Amount"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
android:textColor="@color/grey_80"
/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<TextView
android:id="@+id/finalAmmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="₹48"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="@color/lightgreen400"
android:textStyle="bold" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/greybtns" />
<androidx.appcompat.widget.AppCompatButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/space_18_dp"
android:background="@drawable/round_btn"
android:paddingLeft="@dimen/space_20_dp"
android:paddingRight="@dimen/space_20_dp"
android:text="Pay With Razor Pay"
android:onClick="startRazor"
android:textColor="@android:color/white" />
</LinearLayout>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
The xml layouts for the activity and the successful payment dialog code are also given in the source code.
The MainActivity.Java class
First of all your Activity or Fragment should have the PaymentResultListener implemented so that you can use Razor-Pay payment interface to make payments
public class MainActivity extends AppCompatActivity implements PaymentResultListener {
ProgressDialog progressDialog;
TextView finalAmmount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
when you will implement PaymentResultListener in your activity or fragment you will see an error that indicates that you must have to implement PaymentResultListener Methods in order to resolve this error so just click on you activity or fragment class name and then select show context and then select implement methods. there you will see two methods one is onPaymentSuccess and second onPaymentError select both of them and then click on OK button.
Bellow you can see onPaymentSuccess method and its implementations.
@Override
public void onPaymentSuccess(String s)
{
progressDialog.dismiss();
showCustomDialog();
}
This is the method that will run if the payment is successfully completed. When the payment is successful the progressDialog will be dismissed and a custom a dialog will show; telling you that the transaction is successfully completed.
onPaymentError Method
@Override
public void onPaymentError(int i, String s)
{
if (progressDialog!=null)
{
progressDialog.dismiss();
}
Toast.makeText(this, "Something Went Wrong", Toast.LENGTH_SHORT).show();
}
This is the method that will run whenever there is an error in the transaction process. The progressDialog will be dismissed it is not equal to null. Hence a toast message will show telling there is an error occurring.
Now you should initialize the progressDialog in the main activity. The progress dialog will load once the buy button is pressed.
public class MainActivity extends AppCompatActivity implements PaymentResultListener {
ProgressDialog progressDialog;
TextView finalAmmount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Please Wait..");
progressDialog.setCancelable(false);
//progressDialog.show();// this will be added inside the onclick method
}
}
Now create the instance of Razor-Pay Checkout class
final Checkout co = new Checkout();
Next thing you should do is provide some transaction details for the Checkout. But the try and catch method was included to handle any error which might occur
try
{
JSONObject options = new JSONObject();
options.put("name", "Test User Name");
options.put("description", "");
options.put("currency", "INR");//currency code
options.put("amount", round( Integer.parseInt(finalAmmount.getText().toString().substring(1)) * 100, 2));
// 10000 you will provide 100// (2 zeros will be added to the actual amount, which has been done in code above)
JSONObject preFill = new JSONObject();
preFill.put("email", "[email protected]");
preFill.put("contact", "1234567890");
options.put("prefill", preFill);
co.open(activity, options);
}
catch (Exception e)
{
Toast.makeText(activity, "Error in payment: " + e.getMessage(), Toast.LENGTH_SHORT) .show();
e.printStackTrace();
}///
From the above code some of the information given can be optional like the name, description, email and contact.
Creating the amount rounding method
public static float round(float d, int decimalPlace)
{
BigDecimal bd = new BigDecimal(Float.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.floatValue();
}
This the method that will be used to round up the payment amount. The calculation on the amount to be paid is carried out inside this method just like you have seen earlier when setting up the payment amount in the description.
“round( Integer.parseInt(finalAmmount.getText().toString().substring(1)) * 100, 2));”
For example 100 rupees will be in the form of 100.00
The last thing to do is to create a showCustomDialog method
private void showCustomDialog()
{
final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.payment_success_dialog);
dialog.setCancelable(true);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(dialog.getWindow().getAttributes());
lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
((AppCompatButton) dialog.findViewById(R.id.bt_close)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
dialog.getWindow().setAttributes(lp);
}
When we created the onPaymentSuccess method we called this method so now we have created it. This method will pop-up a dialog telling that the transaction carried out has been successfully completed.
MainActivity.class Complete Code
package com.example.razorpayintegrationitinside;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatButton;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;
import com.razorpay.Checkout;
import com.razorpay.PaymentResultListener;
import org.json.JSONObject;
import java.math.BigDecimal;
public class MainActivity extends AppCompatActivity implements PaymentResultListener {
ProgressDialog progressDialog;
TextView finalAmmount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Please Wait..");
progressDialog.setCancelable(false);
finalAmmount = findViewById(R.id.finalAmmount);
}
public void startRazor(View view) {
progressDialog.show();
final Activity activity = this;
final Checkout co = new Checkout();
try {
JSONObject options = new JSONObject();
options.put("name", "Test User Name");
options.put("description", "");
options.put("currency", "INR");//currency code
options.put("amount", round( Integer.parseInt(finalAmmount.getText().toString().substring(1)) * 100, 2));
// 100000 you will provide 100//
//10 1000
JSONObject preFill = new JSONObject();
preFill.put("email", "[email protected]");
preFill.put("contact", "1234567890");
options.put("prefill", preFill);
co.open(activity, options);
} catch (Exception e) {
Toast.makeText(activity, "Error in payment: " + e.getMessage(), Toast.LENGTH_SHORT)
.show();
e.printStackTrace();
}
}
@Override
public void onPaymentSuccess(String s) {
progressDialog.dismiss();
showCustomDialog();
}
@Override
public void onPaymentError(int i, String s) {
if (progressDialog!=null){
progressDialog.dismiss();
}
Toast.makeText(this, "Something Went Wrong", Toast.LENGTH_SHORT).show();
}
public static float round(float d, int decimalPlace) {
BigDecimal bd = new BigDecimal(Float.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.floatValue();
}
private void showCustomDialog() {
final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); // before
dialog.setContentView(R.layout.payment_success_dialog);
dialog.setCancelable(true);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(dialog.getWindow().getAttributes());
lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
((AppCompatButton) dialog.findViewById(R.id.bt_close)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
// finish();
}
});
dialog.show();
dialog.getWindow().setAttributes(lp);
}
}
Now it's time to run the app Happy Coding!
Conclusion
From the beginning of this tutorial up to the end, I have fully explained in details how to integrate the Razor-Pay in android studio. Each segment of the code had been explained too. Also one thing you should note is that when using the test mode in the app; you can choose to make the transaction successful or not to test your code and see how it works in both conditions. I have also provided you this android app complete source code. Whenever you are done with the testing mode, you can request for your razor_pay key from your dashboard so that you can receive real payments from your app users.
Files ( Login Required )
What's Your Reaction?






