Juspay Developer Guide

Welcome to the Juspay Developer Guide. You'll find comprehensive guides and documentation to help you start working with Juspay Docs as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started

Android Integration

Introduction

JusPay Safe Browser (codename: Godel) aims to reduce friction in Second Factor Authentication for Cards and Netbanking.

The library provides various convenience and security features for users to be able to complete the transaction quickly. The library also provides much deeper insight into the events occurring in the payment flow. With Godel, you will be able to provide a pleasing payments experience to your Android users.

This documentation explains the steps to integrate the library into your native Android application.

Get SDK

The library can be added as a direct dependency when you use Gradle. If you don't use Gradle, we provide a downloadable SDK which you can add as a project dependency. Before you initialize the Browser SDK, please call the following function from your Checkout Activity:

JuspayBrowserFragment.openJuspayConnection(context);

Versioning

For supporting the wide variety of minSdk-targetSdk versions we have baked in the SDK versions into the library version. The final version number is a concatenation of base number and minSdk-targetSdk.

The current base version being 0.6.25.3, the final library version is in the format of 0.6.25.3.xxxx.

Version Number minSdk targetSdk
0.6.25.3.1421 14 21
0.6.25.3.1423 14 23
0.6.25.3.1623 16 23
0.6.25.3.1625 16 25

Add the following maven repository to the build.gradle. Please make sure that you add it in the project dependency section and NOT the buildScript section.

// Add to build.gradle

repositories {
  mavenCentral()
  maven {
    url "https://s3-ap-southeast-1.amazonaws.com/godel-release/godel/"
  }
}

dependencies {
  compile 'in.juspay:godel:0.6.25.3.1423'

  // your other dependencies
  ...
  ...
}

Note: Godel library is using support library version 23.4.0

Brief changelog is available here

Setup Permissions

JusPay Safe browser currently supports all applications using version >= Android API version 14.

The following are the minimum set of permissions required for the library to work as expected:

<!-- File AndroidManifest.xml-->

<manifest ...>

  <!-- additional permissions -->
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.READ_SMS" />
  <uses-permission android:name="android.permission.RECEIVE_SMS" />
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

  <application>

    <!-- activity declaration -->
    <activity
        android:label="Processing your payment"
        android:name="in.juspay.godel.PaymentActivity"
        android:hardwareAccelerated="true"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustResize"
      >
    </activity>
  </application>
</manifest>

Start the browser

Instantiate BrowserCallback

Callback which will be invoked when a user completes the payment or cancels it midway. Whenever a payment is completed (successfully or not), the aggregator/gateway will send the user back to your website. Usually, you would pass single return_url or multiple URLs to aggregator to represent success, failure or cancel.

onTransactionAborted(JSONObject paymentDetails)

Method onTransactionAborted is invoked when the user clicks back button in the payment flow. We assume that the intent of the user is to cancel the transaction. Detailed information of the session is passed in the JSONObject parameter.

endUrlReached(WebView view, JSONObject paymentDetails)

Method endUrlReached is invoked when we encounter a URL which is identified by you as a return URL or the last URL in the payment flow. The matched URL will be passed in the URL key of the JSONObject parameter.

JusPay Browser expects endUrlRegexes as an input. This variable represents an array of String which are regular expressions to match the final return URL. You can send as many URLs as you want here. If the return flow (from the gateway to merchant) uses HTTP GET, shouldOverrideUrlLoading is used to check if the URL matches the regex and in case of POST, onPageStarted method will evaluate the regex. If matched, then endUrlReached is invoked by the browser. You will now have control of the user session.

public BrowserCallback callBack = new BrowserCallback() {

  @Override
  public void onPageStarted(WebView view, String url) {
    super.onPageStarted(view, url);
  }

  @Override
  public void onTransactionAborted(JSONObject paymentDetails) {
    GodelTracker.getInstance().trackPaymentStatus(transactionId, GodelTracker.FAILURE);
    JuspaySafeBrowser.exit();

    Toast.makeText(context,  "Transaction cancelled.", Toast.LENGTH_LONG).show();

    // Payment was not completed by the user. So, let's present the retry option to the user.
    NextActivity.this.retryPayment(); 
  }

  @Override
  public void onWebViewReady(WebView webView) {
    Log.d(TAG, "onWebViewReady: url " + webView.getUrl());
  }

  @Override
  public void endUrlReached(WebView view, JSONObject sessionInfo) {
    GodelTracker.getInstance().trackPaymentStatus(transactionId, GodelTracker.SUCCESS);
    JuspaySafeBrowser.exit();

    // Required action performed
    Toast.makeText(context, "Transaction completed. Maybe failure/success.", Toast.LENGTH_LONG).show();
    // Payment step has been completed by the user. Take the user to the next step.
    NextActivity.this.startNextActivity();
  }
};

If your aggregator uses HTTP GET to redirect the user to you, then the last URL will never hit your server. However, if HTTP POST is used, then the URL will hit your server (with POST parameters).

Deprecation Notice:

ontransactionAborted() and endUrlReached(String url) are now deprecated in favour of the above methods

paymentDetails JSON Object

paymentDetails json object provides a list of attributes to understand session of the payment. This object is passed via the onTransactionAborted method and endUrlReached method of BrowserCallback interface.

Find below the set of parameters which will be sent:

Variable
Description
Type
Example

inferred_payment_status

Overall payment Status inferred by Juspay Safe

String

SUCCES

payment_statuses

Payment status details inferred stage-wise

JSON

{
"bank_payment_status":"SUCCESS",
"pg_payment_status":"SUCCESS",
"aggregator_payment_status":"SUCCESS"
}

dropout_reasons

A JSON Object that has the user dropout reason

JSON

{
"dropoutReason":["User Aborted"],
"backPressed":true,
"networkStatus":"CONNECTED",
"authenticationStatus":"",
"potentialPaymentFlowError":""
}

realtime

A JSON Object that has the system metrics

JSON

{
"last_visited_url":"https://www.sampleurl.com/success",
"backPressed":true,
"otp_detected":"true",
"otp_approved":"auto",
"sms_permission":"true"
}

url*

The url at which transaction was completed.

String

  • Payment statuses (inferred_payment_status, bank_payment_status, pg_payment_status, aggregator_payment_status) can be one of: SUCCESS, FAILURE or UNKNOWN.

  • OTP Approved (in realtime) can be one of NA, auto or manual.

  • The attribute url shall be passed only for endUrlReached method

Create BrowserParams Object

BrowserParams class provides an easy-to-use interface to add all the parameters that must be sent to JusPay Safe browser. Create an instance of the class to get started:

BrowserParams browserParams = new BrowserParams();

Find below the set of parameters which must be sent:

Variable Description Type Required Default
url Start URL for payment String Yes
postData POST parameters that must be passed to the URL String No
merchantId Identifies the merchant. Eg. 'merchant’ String Yes
clientId ClientID defines the platform used. Eg. 'merchant_android’ String Yes
transactionId Represents the current transactionId String Yes
orderId Represents the order number assigned by the merchant String Yes
amount Amount of the transaction String Yes
customerId Unique identifier of the customer String No
customerEmail Email address of the customer String No
customerPhoneNumber Mobile number of the customer String No
displayNote (Deprecated) Short note about transaction shown to the customer. ex. 'Paying INR 200 for Order 123456' String No
remarks Remarks about transaction. This will be automatically filled up in the netbanking page. ex. 'Pay to merchant' String No
clearCookies If true, we will clear webView cookies whenever Juspay Webview is initialized. Boolean No False

See the example below:

BrowserParams browserParams = new BrowserParams();
browserParams.setMerchantId("shop");
browserParams.setClientId("shop_android");
browserParams.setOrderId("ord_111222");
browserParams.setTransactionId("txn_111222");
browserParams.setAmount("12019.50");

browserParams.setCustomerId("9988776655");
browserParams.setCustomerEmail("user@mail.com");
browserParams.setCustomerPhoneNumber("9988776655");

browserParams.setRemarks("Flight MUM DEL");

browserParams.setUrl(PAYMENT_URL);
browserParams.setPostData(PAYMENT_POST_DATA);

All values in postData should be URL encoded before setting browserParams.setPostData(PAYMENT_POST_DATA);. If you do not URL encode the values, then your gateway/aggregator will show error message in the browser.

browserParams.setDisplayNote() is deprecated. Please use OnScreenDisplay class.

Custom Parameters

Custom parameters let you add new dimensions which can be very useful for analytics. Please make sure that the dimensions you choose are dense. It does not make sense to put the mobile number or email address as a custom parameter.

Variable Description Required
udf_:var1 Custom Field No
udf_:var2 Custom Field No
udf_:var3 Custom Field No
Map<String,String> customParameters = new HashMap<String, String>();
customParameters.put("udf_category", "FLIGHT");
customParameters.put("udf_city","BANGALORE");
customParameters.put("udf_cardbrand","VISA");
browserParams.setCustomParameters(customParameters);

With the above, if you have categories such as FLIGHT, BUS, and TRAIN, then you can measure the success rate for each of these categories and compare them with each other.

Custom HTTP Headers

Sometimes you would want to pass more information as HTTP headers to the first URL. BrowserParams class accepts a Map of as custom headers. All the headers set here will be sent to WebView as HTTP headers.

Map<String, String> customHeaders = new HashMap<String, String>();
customHeaders.put("Accept-Encoding", "gzip, deflate, sdch");
customHeaders.put("Accept-Language", "en-US,en;q=0.8");
browserParams.setCustomHeaders(customHeaders);

Define endUrls

The array of Strings each of which will be interpreted as regular expressions. Every URL loaded (in onPageStarted) by the browser will be matched against each of the array items. If a match is found, then the browser stops further processing and delegates the control back to the app via BrowserCallback.

JuspaySafeBrowser.setEndUrls(new String[]{"https://shop\\.com/paymentResponse.*", 
    "https://beta\\.shop\\.com/paymentResponse.*"})

Hint: Be sure to escape the dots as required. Note the final .* is deliberately not escaped.

Start the Browser

Now, start the browser and wait for it to complete. This starts the payment activity and gives the callback when aborted or successful.

JuspaySafeBrowser.start(this, browserParams, callBack);

User Logout

User should be logged out of Juspay session whenever he logs out of the Merchant App. This ends the user session with Juspay Safe.

  JuspaySafeBrowser.performLogout(getApplicationContext());

UI Customisations

Styling Action Bar

Background color, background image and logo of ActionBar can be customized by setting appropriate attributes in BrowserParams. You can either pass background color or background image. If both are passed, priority will be given to the background image.

browserParams.setActionBarIcon(getResources().getDrawable(R.drawable.juspay_logo_white));
browserParams.setActionBarBackgroundColor(new ColorDrawable(0xFF0000BB));
browserParams.setActionBarBackgroundImage(getResources().getDrawable(R.drawable.abc_item_background_holo_light));

Adding Order Summary

You can give a brief order summary to the user by using the OnScreenDisplay object. This would show above the webview, just below the toolbar. Use one of the predefined views to construct a OnScreenDisplay object and pass it to the browser by calling browserFragment.showOnScreenDisplay(osd)

Travel

Onwards Journey

Create a TravelModel for onwards journey and pass it in the single-param constructor. For the best user experience set all the values as shown below.

TravelModel onwardsTravelModel = new OnScreenDisplay.TravelModelBuilder()
                        .setJourneyFromCity(new JourneyCity("Bangalore", "BLR", "8:00 AM"))
                        .setJourneyToCity(new JourneyCity("New Delhi", "DEL", "11:30 AM"))
                        .setJourneyFlightNumber("6E-522")
                        .setJourneySeatingClass("Economy")
                        .setJourneyAirlineName("Indigo")
                        .setJourneyDate("11 Sep 2016")
                        .setTravellersNameList(getTravellersList())
                        .createTravelModel();

OnScreenDisplay osd = OnScreenDisplay.Travel(onwardsTravelModel)
                        .setAmount("₹ 12300")
                        .build();

Return Journey

You can create two TravelModel like above pass them both in the two-params constructor.

OnScreenDisplay osd = OnScreenDisplay.Travel(onwardsTravelModel, returnTravelModel)
                        .setAmount("₹ 12300")
                        .build();

Multicity Journey

Create a list of TravelModel and pass it in the single list param constructor.

List<TravelModel> travelModelList = new ArrayList<TravelModel>();
traveModelList.add(firstTravelModel);
traveModelList.add(intermediateTravelModel);
traveModelList.add(lastTravelModel);

OnScreenDisplay osd = OnScreenDisplay.Travel(travelModelList)
                        .setAmount("₹ 12300")
                        .build();

Booking

Hotel Booking

For Hotel, booking use the constructor with the following parameters

Variable Description Required
bookingTitle Primary title. Appears on collapsed layout and on the top of the expanded view. Yes
bookingSubTitle Secondary Tite. Usually the address of the hotel. Yes
bookingShortDesc Short description of the stay. Usually stating the number of guests and nights. Yes
hotelBookingModel Model created using HotelModelBuilder Yes
OnScreenDisplay.HotelBooking("Hotel Maverick International",
        "Old Madras Road, Bangalore, Karnataka",
        "2 Guests | 3 Nights",
        new OnScreenDisplay.HotelModelBuilder()
                .setCheckInDate("23 Sept 2016")
                .setCheckInExtra("08:00 AM")
                .setCheckOutDate("25 Sept 2016")
                .setCheckOutExtra("11:00 PM")
                .setGuestList(getGuestList())
                .createHotelModel())
        .setAmount("₹ 12300")
        .build();

Event Booking

Event booking OSD for Movies, Events orders.

OnScreenDisplay.EventBooking(new OnScreenDisplay.EventModelBuilder()
            .setDate("24 Sep 2016")
            .setTime("7 PM")
            .setEventName("Star Wars: Force Awakens")
            .setVenue("Inox Forum")
            .setTicketCount(1)
            .setTicketDescription("Normal - G40, G41, G54")
            .createEventModel())
    .setAmount("₹ 12300")
    .build();

GeneralPurchase

This is a builder which can be used for E-Commerce, Recharge or Delivery.

Variable Description Required
orderTitle Primary title. Appears on collapsed layout and on the top of the expanded view. Yes
orderSubtitle Secondary Title. Usually the product's company name. Yes
purchaseDate Time or Date of the order. Yes
sellerName Seller name Yes
extras List displayed at bottom of the expanded view. Eg estimated delivery time, availed offer Yes
OnScreenDisplay.GeneralPurchase("Sony MDR 650-BT",
        "by Sony",
        "8:45 PM 14 Sept 2016",
        "CloudTail", extras)
        .setAmount("₹ 12300")
        .build();

Collapsed Only

If you don't want to show an expanded view in the OSD, you can use this OSD Type. The expansion would be disabled for this OSD type.

OnScreenDisplay.CollapsedOnly("Recharge for 9829880095")
        .setAmount("₹ 145")
        .build()

Generic Builder

A generic builder can be used to create the UI manually. Start by sending the order title in the OnScreenDisplay.Generic("MacBook Pro Retina") API. You can now access the following methods to build the UI:

Method Description
appendSingleLine Adds a single line text view
appendDoubleLine Adds a vertically stacked double line view with title and subtitle hierarchy
appendTripleLine Adds a vertically stacked triple line view with title, subtitle and a caption
appendDottedDivider A dotted line across the full width of the view
appendFullDivider A full line across the full width of the view
OnScreenDisplay.Generic("MacBook Pro")
        .appendTripleLine("Vimal Kumar", "#513, Adayar", "Chennai, 600002")
        .appendDottedDivider()
        .appendDoubleLine("Contact", "+91-9829880095")
        .appendDoubleLine("Order Id", "#1337")
        .setAmount("54,000")
        .build()

Send Payment Status

Once payment has been completed, you should inform us if the payment was successful. This is important to provide better analytics in identifying top areas of failure points. Payment status can be one of: SUCCESS, FAILURE or CANCELLED.

Among all the three techniques, sending the status from the server is the most reliable as the network between servers is much more robust.

From endUrlReached function

Since we always invoke endUrlReached method for all payment completions, you could send us the payment status at that point.

// Putting payment status
public BrowserCallback callBack = new BrowserCallback() {

  @Override
  public void onTransactionAborted(JSONObject paymentDetails) {
    GodelTracker.getInstance().trackPaymentStatus(transactionId, GodelTracker.FAILURE);
    JuspaySafeBrowser.exit();

    // Required action performed
  }

  @Override
  public void endUrlReached(WebView webView, JSONObject paymentDetails) {
    GodelTracker.getInstance().trackPaymentStatus(transactionId, GodelTracker.SUCCESS);
    JuspaySafeBrowser.exit();

    // Required action performed
  }

};

However, it may not always be possible to have the payment status at this point, especially if the aggregator uses HTTP POST for sending the payment details. In such cases, you can POST the status from the next activity or from your server.

From the next activity

public class PaymentCompleteActivity {

  public void onCreated(Bundle savedInstanceState) {
    String transactionId = getTransactionIdOfCurrentPayment();
    String status = getPaymentStatusFromServer(transactionId);
    GodelTracker.getInstance().trackPaymentStatus(transactionId, GodelTracker.PaymentStatus.SUCCESS);
  }

}

From your Server

Payment status can also be sent from your servers. Please make sure that the following parameters are sent correctly along with the status:

  • client_id
  • merchant_id
  • order_id
  • transaction_id

Data must be sent as a properly formatted JSON. Example payload:

{
  "data":[
    {
      "merchant_id":"shop",
      "client_id":"shop_android",
      "order_id":"ord_112233",
      "transaction_id":"txn_112233",
      "payment_status":"SUCCESS"
    }
  ]
}

Payment status can be one of: SUCCESS, FAILURE or CANCELLED. Example HTTP POST to send payment status is provided below:

# Post status directly to Juspay server
curl https://logs.juspay.in/godel/analytics \
  -H 'Content-Type: application/json' \
  -d '{"data":[{"merchant_id":"shop", "client_id":"shop_android", "order_id":"ord_112233", "transaction_id": "txn_112233", "payment_status":"SUCCESS"}]}'

Note: This is the preferred method for sending Status to JusPay. Please send if Failure also. Otherwise, the transactions will be categorized as unknown.

Proguard rules

Most part of JusPay's library is already compressed with ProGuard. If your application uses ProGuard as well (and we think you should if you don't already), then please do specify the following rule to avoid integration issues:

-keep class in.juspay.** {*;}

Integration checklist

  1. Ensure android:windowSoftInputMode="adjustResize" is stated for the PaymentActivity in AndroidManifest.xml. JusPay Safe browser only works in Portrait mode. So you should also fix the orientation as 'portrait'.

  2. Ensure that correct value is sent for the following:

    • merchantId
    • clientId
    • orderId
    • transactionId
    • amount
  3. Send payment_status via GodelTracker.trackPaymentStatus or POST this information to our servers directly. We would recommend server-side POST technique as it is 100% reliable.

  4. All the classes under in. juspay namespace should be kept out of ProGuard optimization.

  5. Lastly, please get your final build checked by our team. You may write to support@juspay.in for this.

Android Integration


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.