1. Integration Steps

Build a custom payment flow integration for your Android app

Before you start with the integration, enable the payment methods that you want to offer to your customers from Dashboard > Settings > Payment methods. We enable Cards, UPI, and other payment methods by default, and we recommend that you enable other payment methods that are relevant to you.

Step 1: Create a PayU account

First, create a PayU account. See Register for a Merchant Account.

Step 2: Initialise Merchant web service

Create an object of MerchantWebService with any of the supported API commands.

MerchantWebService merchantWebService = new MerchantWebService();
merchantWebService.setKey(merchantKey); // Merchant key
merchantWebService.setCommand(<Api Commands>); // Command for fetching payment related details
merchantWebService.setVar1(userCredential) // User Credential of the merchant
merchantWebService.setHash(<Api Command Hash>) //Hash for fetching payment related details such as payment options

For more information on Web Service hash generation, refer to Generate Hash.

Step 3: Create Merchant web service PostData

PostData postData = new MerchantWebServicePostParams(merchantWebService).getMerchantWebServicePostParams();
if (postData.getCode() == PayuErrors.NO_ERROR) {
payuConfig.setData(postData.getResult());
}

📘

If the PostData code snippet (above) is returning errors, check the data point set in merchantWebService.

Supported API commands

The following API commands are offered in the PayUConstantsclass.

CommandsDescriptionTaskListener
PAYMENT_RELATED_DETAILS_FOR_MOBILE_SDKTo get all enabled payment optionsGetPaymentRelatedDetailsTask payuTask = GetPaymentRelatedDetailsTask(this); payuTask.execute(payuConfig);PaymentRelatedDetailsListener
VAS_FOR_MOBILE_SDKTo get the health status of payment optionsValueAddedServiceTask payuTask = ValueAddedServiceTask(this); payuTask.execute(payuConfig);ValueAddedServiceApiListener
CHECK_IS_DOMESTICGet Bin information on CC/DCGetCardInformationTask payuTask = GetCardInformationTask(this); payuTask.execute(payuConfig);GetCardInformationApiListener
GET_TRANSACTION_INFOGetting Transaction informationGetTransactionInfoTask payuTask = GetTransactionInfoTask(this); payuTask.execute(payuConfig);GetTransactionInfoApiListener
VERIFY_PAYMENTVerify Payment StatusVerifyPaymentTask payuTask = VerifyPaymentTask(this); payuTask.execute(payuConfig);VerifyPaymentApiListener
CHECK_OFFER_DETAILSTo get the offer details.CheckOfferDetailsTask payuTask = CheckOfferDetailsTask(this); payuTask.execute(payuConfig);CheckOfferDetailsApiListener
API_GET_EMI_AMOUNT_ACCORDING_INTERESTTo get the EMI amount according to interest.GetEmiAmountAccordingToInterestTask payuTask = GetEmiAmountAccordingToInterestTask(this); payuTask.execute(payuConfig);GetEmiAmountAccordingToInterestApiListener
CHECK_OFFER_STATUSTo check the status of the offerGetOfferStatusTask payuTask = GetOfferStatusTask(this); payuTask.execute(payuConfig);GetOfferStatusApiListener
ELIGIBLE_BINS_FOR_EMITo check if the bin is eligible for EMIEligibleBinsForEMITask payuTask = EligibleBinsForEMITask(this); payuTask.execute(payuConfig);EligibleBinsForEMIApiListener
GET_CHECKOUT_DETAILSTo get info about additional charges, bank down, tax info, and offersGetCheckoutDetailsTask getCheckoutDetailsTask = GetCheckoutDetailsTask(this); getCheckoutDetailsTask.execute(payuConfig);CheckoutDetailsListener
GET_PAYMENT_INSTRUMENTTo get stored cards of the userGetTokenisedCardTask getTokenisedCardTask = GetTokenisedCardTask(this); getTokenisedCardTask.execute(payuConfig);GetTokenisedCardApiListener
DELETE_PAYMENT_INSTRUMENTTo delete the stored card of the userDeleteTokenisedCardTask deleteTokenisedCardTask = DeleteTokenisedCardTask(this); deleteTokenisedCardTask.execute(payuConfig);DeleteTokenisedCardApiListener
GET_PAYMENT_DETAILSTo get details of the stored card to make payment on another PGGetTokenisedCardDetailsTask getTokenisedCardDetailsTask = GetTokenisedCardDetailsTask(this); getTokenisedCardDetailsTask.execute(payuConfig);GetTokenisedCardDetailsApiListener
CHECK_BALANCETo get info about Sodexo saved CardCheckBalanceTask checkBalanceTask= CheckBalanceTask(this); checkBalanceTask.execute(payuConfig);CheckBalanceListener

Additional APIs

Enable Payment Options for Merchant Web Services

This section describes how to get all payment options enabled on your merchant key, along with additional information like stored cards and payment option details.

Step 1: Call GetPaymentRelatedDetailsTask

GetPaymentRelatedDetailsTask paymentRelatedDetailsForMobileSdkTask = new GetPaymentRelatedDetailsTask(this);
//where ,
//Input param (this) is the instance of class which implements PaymentRelatedDetailsListener
//‘PaymentRelatedDetailsListener’ is interface with abstract method, which is
//public void onPaymentRelatedDetailsResponse(PayuResponse payuResponse)

After you execute the GetPaymentRelatedDetailsTask, onPaymentRelatedDetailsResponse callback is called. Check for the available methods to check if the selected payment option is available.

@Override
public void onPaymentRelatedDetailsResponse(PayuResponse payuResponse) {
mPayuResponse = payuResponse;
// Check if UPI as payment option available.
if(payuResponse.isUpiAvailable()){
// To check if UPI as payment option is available
}
if(payuResponse.isGoogleTezAvailable()){
// To check if Google Pay as payment option is available
}
if(payuResponse.isPhonePeIntentAvailable()){
// To check if Phonepe as payment option is available
}
if(payuResponse.isLazyPayAvailable()){
// To check if LazyPay as payment option is available
}
if(payuResponse.isGenericIntentAvailable()){
// To check if Generic Intent as payment option is available
}
//For SI Payments
if(payuResponse.isNBAvailableFoSI){
//Fetch SI NB List from payuResponse.getSiBankList() method
}
}

Get Checkout details API

The Get Check Out Details API provides information on the bank down status, tax info, and offers enabled on a merchant key. You can call this API is similar to other Web Services. The only difference is that it requires a JSON in var1 as in the following code block:

{
   "requestId":"1614595430980",
   "transactionDetails":{
      "amount":5000
   },
    "customerDetails": {
      // optional
      "mobile": "9999999999", // optional
    },
   "useCase":{
      "getAdditionalCharges":true,
      "getTaxSpecification":true,
      "checkDownStatus":true,
      "getExtendedPaymentDetails":true,
      "getOfferDetails":true
   }
}

📘

Note

In the above example, requestId is a unique random number passed in the request.

Step 1: Create var1

Mobile SDK has a Utility class to create a JSON, as explained above. The implementation is similar to the following code snippet:

  Usecase.Builder usecase = new Usecase.Builder()
  .setCheckCustomerEligibility(true)
  .shouldCheckDownStatus(true) // set it to true to fetch bank down status for each payment option 
  .shouldGetAdditionalCharges(true) // set it to true to fetch additional charges applicable on each payment option
  .shouldGetOfferDetails(true) // set it to true to fetch offers enabled on merchant key 
  .shouldGetExtendedPaymentDetails(true) // set it to true to get extended payment details
  .shouldGetTaxSpecification(true) // set it to true to fetch tax info applicable on each payment mode 
  .build();
  
  GetTransactionDetails.Builder transactionDetails = new GetTransactionDetails.Builder()
  .setAmount(1000.0)//transaction amount in double
  .build();
  
  //Passing Customer Details is optional and can be used 
  //to check EMI eligibility based on mobile number
  CustomerDetails.Builder customerDetails = new CustomerDetails.Builder()
  .setMobile("9999999999") //pass the mobile number if want to get eligibility status in payment option
  .build()
  
  String var1 = new GetCheckoutDetailsRequest.Builder()
            .setUsecase(usecase)
            .setCustomerDetails(customerDetails)
            .setTransactionDetails(transactionDetails)
            .build().prepareJSON();

After getting var1, pass that in Merchant Web Service with command as PayuConstants.GET_CHECKOUT_DETAILS.

Get API Response

PayuResponse is received in the onCheckoutDetailsResponse() callback method of CheckoutDetailsListener as mentioned in the API Commands Supported table.

Get Additional Charges, Bank Down Status and Offers

Additional Charges are returned in the PaymentDetails object for each payment option. The following example code snippet is for fetching Additional Charges for Net Banking:

//if netbanking is available on merchant key
if(payuResponse.isNetBanksAvailable()){
ArrayList<PaymentDetails> = payuResponse.getNetbanks();
}

Additional Charge is available inside each PaymentDetails object and can be accessed using the paymentDetails.getAdditionalCharge() method

Similarly, bank health is available inside each PaymentDetails object and can be accessed using the paymentDetails.isBankDown() method.

For Offers, An ArrayList<PayuOffer> is available inside each PaymentDetails object. To get the offers list, use paymentDetails.getOfferDetailsList().

Get Tax Info

Tax is not applied on individual Net Banking or card schemes but instead applied at the payment mode-level for all CC(Credit Card), DC(Debit Card), NB(Net Banking), Wallets, etc. So, to fetch the Tax Specification, use the following code block:

if(payuResponse.isTaxSpecificationAvailable())
TaxSpecification taxSpecification = payuResponse.getTaxSpecification();

taxSpecification.getCcTaxValue() //tax applicable on CC transactions
taxSpecification.getDcTaxValue() //tax applicable on DC transactions
taxSpecification.getNbTaxValue() //tax applicable on NB transactions
taxSpecification.getCashTaxValue() //tax applicable on Wallet transactions
...

Look up API

Step 1: Create request

The Lookup API needs a JSON request. Product type needs to be passed either as DCC or MCP. DCC means Direct Currency Conversion, that is, it returns the conversion prices for card currency only. To get all enabled currencies on Merchant Access Key and their conversion prices, use product type as MCP. For DCC, cardBin is mandatory, but cardBin is not required for MCP.
The following example is a request for DCC as the product type.

{
   "merchantAccessKey":"E5ABOXOWAAZNXB6JEF5Z",
   "baseAmount":{
      "value":10000.00,
      "currency":"INR"
   },
   "cardBin":"513382",
   "merchantOrderId":"OBE-JU89-13151-110",
   "productType":"DCC",
   "signature":"be5a56667354d9e2ea5ea1c6af78b0afc1894eb2"
}

To create the Lookup API request as above, use the LookupApiRequestBuilder class similar to the following code block:

String postData = new LookupRequest.LookupApiRequestBuilder()
                .setAmount("10000.00")
                .setCardBin("513382")
                .setCurrency("INR")
                .setMerchantAccessKey("E5ABOXOWAAZNXB6JEF5Z")
                .setMerchantOrderId("OBE-JU89-13151-110")
                .setProductType(LookupRequest.ProductType.DCC)
                .setSignature(hash)
                .build().prepareJSON();
 val postData = LookupRequest.LookupApiRequestBuilder()
                .setAmount("10000.00")
                .setCardBin("513382")
                .setCurrency("INR")
                .setMerchantAccessKey("E5ABOXOWAAZNXB6JEF5Z")
                .setMerchantOrderId("OBE-JU89-13151-110")
                .setProductType(LookupRequest.ProductType.DCC)
                .setSignature(hash)
                .build().prepareJSON()

The following example request is for MCP as the product type.

{
   "merchantAccessKey":"E5ABOXOWAAZNXB6JEF5Z",
   "baseAmount":{
      "value":10000.00,
      "currency":"INR"
   },
   "merchantOrderId":"OBE-JU89-13151-110",
   "productType":"MCP",
   "signature":"be5a56667354d9e2ea5ea1c6af78b0afc1894eb2"
}

To create the Lookup API request for MCP, use the LookupApiRequestBuilder class similar to the following code block:

String postData = new LookupRequest.LookupApiRequestBuilder()
                .setAmount("10000.00")
                .setCurrency("INR")
                .setMerchantAccessKey("E5ABOXOWAAZNXB6JEF5Z")
                .setMerchantOrderId("OBE-JU89-13151-110")
                .setProductType(LookupRequest.ProductType.MCP)
                .setSignature(hash)
                .build().prepareJSON();
 val postData = LookupRequest.LookupApiRequestBuilder()
                .setAmount("10000.00")
                .setCurrency("INR")
                .setMerchantAccessKey("E5ABOXOWAAZNXB6JEF5Z")
                .setMerchantOrderId("OBE-JU89-13151-110")
                .setProductType(LookupRequest.ProductType.MCP)
                .setSignature(hash)
                .build().prepareJSON()
Parameter NameDescription
AmountTransaction Amount
Card BinFirst 6 digits of card number
CurrencyBase Currency of Transaction
Merchant Access KeyMerchant Access Key provided by PayU
Merchant OrderIdA unique request id for Lookup API request
Product TypeUse MCP to get all enabled currency on Merchant Access Key or DCC to get direct currency conversion for card currency
SignatureHmac SHA1 hash created with formula explained below

To calculate signature, create the HmacSHA1 hash of the following data:

Signature =HMAC-SHA1(data, key);
Data = baseCurrency+merchantOrderId+baseAmount
Key = Secret Key shared with the merchant at the time of on-boarding
Example data,
baseCurrency = "INR"
merchantOrderId = "OBE-JU89-13151-110"
baseAmount = "10000.00"
hashString = INROBE-JU89-13151-11010000.00

Step 2: Call LookupTask

Here, this is an object of a class that implements LookupApiListener. The following is a signature of LookupApiListener:

public interface LookupApiListener {
    void onLookupApiResponse(PayuResponse payuResponse);
}
interface LookupApiListener {
    fun onLookupApiResponse(payuResponse: PayuResponse?)   
}

Step 3: Get LookUp API response

After you execute LookupTask, the onLookupApiResponse callback method is called:

@Override
public void onLookupApiResponse(PayuResponse payuResponse){    
    
    //Fetch lookup Details using below code
    LookupDetails lookupDetails = payuResponse.getLookupDetails();     
    }
override fun onLookupApiResponse(payuResponse: PayuResponse?){    
    
    //Fetch lookup Details using below code
    val lookupDetails = payuResponse.lookupDetails
    }