Razorpay is a digital payment gateway for accepting online payments. Above all, it has more than 8,00,000 clients worldwide. Reputed companies like Airtel, Swiggy, Zomatto use Razorpay as their Payment Gateway. Features like Payment Pages, Payment Links, Subscription, and Smart Collect takes the Payment Gateway solution to the next level. Razorpay also provides Payment Gateway which is available for web and mobile platforms. It has a vast variety of payment options like Credit/Debit Card, Net Banking, UPI, International payment, etc. In this article, we are going to learn how to integrate Razorpay Payment Gateway Integration in a simple eCommerce application. Making eCommerce is a bit complex each and every class can not be covered here So, I have prepared a sample project you can find it here.

DEMO

Razorpay payment gateway integration in android | loopwiki.com

1. Fashion Shop Application

This application has a limited amount of screens. Application created using design library components like RecyclerView, CardView, etc. To reduce view initialization boilerplate code we are using the butterknife library.

  • Fashion Shop Home- This screen lists available products. Here we are creating product data programmatically. You can load products from the server by tweaking a little bit of code. Each product contains a thumbnail, name, price.
  • Fashion Shop Cart- Lists products that are added to the cart. A button to remove products from the cart, and a button to proceed to checkout.
  • Razorpay Checkout- This screen is initiated when we start the checkout flow. It will contain all the available payment options.

Below are some screenshots of the Razorpay payment flow.

  • Shopping home screen
  • Shooping cart screen
  • Razorpay Payment Screen
  • Razorpay test result chooser screen
  • Payment successful screen

2. Razorpay Payment Lifecycle

Razorpay android SDK has very straight forward execution lifecycle.

  1. Preparing Order: When a customer adds products to the cart and goes to the cart screen we calculate the total amount to be paid.
  2. Initiate Razorpay Checkout: Once the customer adds products from the cart and clicks the checkout button then Razorpay checkout will be initiated. The checkout screen will have different payment options. The customer will choose one of them and completes the payment.
  3. Order Status: Razorpay will return the appropriate payment status code to the application. The application will handle the status code and will show the message accordingly.

3. Razorpay Integration

While building applications we need to take care of modern architecture and security measures. This article is made to demonstrate the Razorpay payment gateway so I tried to keep the application as minimum as possible to understand it better.

Step 1: Create Account at Razorpay.

Step 2: You can activate your account step by step wizard will be presented by Razorpay. I am going to use a test account credential for this application.

Step 3: Add dependency for Razorpay android SDK in build.gradle file. Below is the latest dependency while creating this article.

repositories {
    mavenCentral()
}

dependencies {
    implementation 'com.razorpay:checkout:1.5.16'
}

Step 4: Open the dashboard and go to setting -> API Keys. Copy API Key and paste inside manifest.xml as shown below inside application tag.

<meta-data
            android:name="com.razorpay.ApiKey"
            android:value="Your API key" />
Razorpay dashboard
Razorpay dashboard

4. Razorpay Android SDK Integration

1. When the activity launches productFragment will be shown. Customer will select the products.

2. After that customer clicks the cart icon fragment manager will place cartFragment in the main content.

3. When Customer clicks Proceed to Pay button RazorPayCheckout method gets called and Razorpay payment flow will start.

4. RazorPay will provide payment options for example Credit/Debit Card, UPI, Net Banking will be presented by Razorpay and the customer completes the payment.

5. Razorpay will call onPaymentSuccess or onPaymentError method based on status code. After that application will show an appropriate status message.

import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;

import com.loopwiki.razorpaychekoutexample.Fragment.CartFragment;
import com.loopwiki.razorpaychekoutexample.Fragment.ProductsFragment;
import com.loopwiki.razorpaychekoutexample.Model.Product;
import com.loopwiki.razorpaychekoutexample.R;
import com.loopwiki.razorpaychekoutexample.Util.Helper;
import com.razorpay.Checkout;
import com.razorpay.PaymentResultListener;

import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;

public class PaymentActivity extends AppCompatActivity implements PaymentResultListener, ProductsFragment.ProductInteractionListener, CartFragment.CartInteractionListener {
    public static final String TAG = PaymentActivity.class.getSimpleName();
    FragmentManager fragmentManager;
    ProductsFragment productsFragment;
    int cartCount = 0;
    @BindView(R.id.textViewCartCount)
    TextView textViewCartCount;
    @BindView(R.id.imageViewCart)
    ImageView imageViewCart;
    List<Product> products;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        Checkout.preload(getApplicationContext());
        fragmentManager = getSupportFragmentManager();
        productsFragment = ProductsFragment.newInstance();
        products = getProducts();
        productsFragment.products = products;
        fragmentManager.beginTransaction().replace(R.id.main_content, productsFragment).commit();
        imageViewCart.setOnClickListener(v -> {
            CartFragment cartFragment = new CartFragment();
            List<Product> productList = new ArrayList<>();
            for (Product product : products) {
                if (product.isAddedToCart()) {
                    productList.add(product);
                }
            }
            cartFragment.products = productList;
            fragmentManager.beginTransaction().replace(R.id.main_content, cartFragment).addToBackStack(ProductsFragment.TAG).commit();
        });

    }

    // Callback from Products fragment when product is added
    @Override
    public void ProductAddedToCart(Product product) {
        cartCount++;
        textViewCartCount.setVisibility(View.VISIBLE);
        textViewCartCount.setText(String.valueOf(cartCount));
        Toast.makeText(this, getString(R.string.product_added), Toast.LENGTH_SHORT).show();
    }

    // Callback from Products fragment when product is removed
    @Override
    public void ProductRemovedFromCart(Product product) {
        cartCount--;
        textViewCartCount.setText(String.valueOf(cartCount));
        if (cartCount == 0) {
            textViewCartCount.setVisibility(View.GONE);
        }
        Toast.makeText(this, getString(R.string.product_removed), Toast.LENGTH_SHORT).show();
    }

    // method to create dummy product
    private List<Product> getProducts() {
        List<Product> products = new ArrayList<>();
        int[] ImageUrl = {R.drawable.one, R.drawable.two, R.drawable.three, R.drawable.four, R.drawable.five, R.drawable.six};
        String[] Title = {"HRX by Hrithik", "Crew STREET", "Royal Enfield", "Kook N Keech", "ADIDAS", "UNDER ARMOUR"};
        int[] Price = {5000, 2000, 1500, 3000, 1256, 700};
        boolean[] IsNew = {true, false, false, true, true, false};
        for (int i = 0; i < ImageUrl.length; i++) {
            Product product = new Product();
            product.setName(Title[i]);
            product.setImageResourceId(ImageUrl[i]);
            product.setNew(IsNew[i]);
            product.setPrice(Price[i]);
            products.add(product);
        }
        return products;

    }

    // Back button press method
    @Override
    public void onBackPressed() {
        if (fragmentManager.getBackStackEntryCount() == 0) {
            super.onBackPressed();
        } else {
            fragmentManager.popBackStackImmediate();
        }

    }

    // this method calls our payment gateway
    public void RazorPayCheckout(int Amount) {
         /*
          You need to pass current activity in order to let Razorpay create CheckoutActivity
         */
        final Activity activity = this;

        final Checkout co = new Checkout();

        try {
            JSONObject options = new JSONObject();
            options.put("name", "Razorpay Corp");
            options.put("description", "Demoing Charges");// You can omit the image option to fetch the image from dashboard
            // set image of you brand
            // options.put("image", "https://s3.amazonaws.com/rzp-mobile/images/rzp.png");
            options.put("currency", "INR");
            options.put("amount", Amount * 100);

            JSONObject preFill = new JSONObject();
            // Preset email and phone
            // preFill.put("email", "[email protected]");
            // preFill.put("contact", "123456789");

            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();
        }
    }

    /**
     * The name of the function has to be
     * onPaymentSuccess
     * Wrap your code in try catch, as shown, to ensure that this method runs correctly
     */
    @SuppressWarnings("unused")
    @Override
    public void onPaymentSuccess(String razorpayPaymentID) {
        try {
            Dialog dialog = Helper.getSuccessDialog(this);
            TextView textViewGoHome = dialog.findViewById(R.id.textViewGoHome);
            textViewGoHome.setOnClickListener(v -> {
                dialog.dismiss();
                clearCart();
                cartCount = 0;
                textViewCartCount.setVisibility(View.GONE);
                fragmentManager.beginTransaction().replace(R.id.main_content, productsFragment).commit();
            });
            dialog.show();
            Toast.makeText(this, "Payment Successful: " + razorpayPaymentID, Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            Log.e(TAG, "Exception in onPaymentSuccess", e);
        }
    }

    /**
     * The name of the function has to be
     * onPaymentError
     * Wrap your code in try catch, as shown, to ensure that this method runs correctly
     */
    @SuppressWarnings("unused")
    @Override
    public void onPaymentError(int code, String response) {
        try {
            Toast.makeText(this, "Payment failed: " + code + " " + response, Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            Log.e(TAG, "Exception in onPaymentError", e);
        }
    }

    // Method called when product is removed from cart
    @Override
    public void RemoveProduct(Product product) {
        int index = this.products.indexOf(product);
        Product ProductToRemove = this.products.get(index);
        ProductToRemove.setAddedToCart(false);
        ProductRemovedFromCart(product);
    }

    // Method is called when we click on Pay button
    @Override
    public void ProceedToPay(int TotalPrice) {
        RazorPayCheckout(TotalPrice);
    }

    // method to clear cart
    public void clearCart() {
        for (Product product : products) {
            if (product.isAddedToCart()) {
                product.setAddedToCart(false);
            }
        }
    }
}

5. Testing the Application

After Razorpay integration you can test the application using test card details. Razorpay provides test card details which only work with test mode API Key. You can find the latest card details here.

  • Card for Domestic Payments
Test Card for Domestic Payment
Test Card for Domestic Payment
  • Card for International Payments
Test Card for International Payments
Test Card for International Payments

6. References

Below are useful links to use while working the project.

  1. Razorpay Dashboard: https://dashboard.razorpay.com
  2. Test Cards: https://razorpay.com/docs/payment-gateway/test-card-details
  3. Credentials: https://dashboard.razorpay.com/app/keys
  4. Razorpay Documentation: https://razorpay.com/docs

I hope you understand Razorpay android integration. If you still have any queries, please post them in the comments section below, I will be happy to help you.

Author

Hello there, My name is Amardeep founder of loopwiki.com. I have experience in many technologies like Android, Java, Php, etc. In this variety of technologies, I love Android App Development. If you have any idea and you want me to develop for you then let's have chat Conatct

Write A Comment