ExpressCheckout Module
Introduction
The Express Checkout SDK provides an easier way for merchants to directly call Express Checkout APIs securely from the client Android device. The SDK is an API layer without any UI and simplifies integration effort.
Get the SDK
The Android SDK library can be added as a direct dependency when you use Gradle. 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.
repositories {
mavenCentral()
maven {
url "https://maven.juspay.in/jp-build-packages/release/"
}
}
Add the following compile dependency to your project. Once again make sure you don’t accidentally add it to script dependencies.
dependencies {
compile 'in.juspay:godel-ec:1.0.7.28'
}
PreFetching Juspay Assets
Since the SDK uses a MicroService architecture on top of Android, it is highly recommended to call preFetch. Calling the function before SDK initiation will download the latest code and update it locally. It should be called a good amount of time before SDK initiation as it might take some time to download the assets (the earlier, the better).
PaymentActivity.preFetch(activity, clientId);
Note: ClientId is of the format "merchantId_android".
Initializing Bundle Parameters
The parameters are grouped into three major components:
- Payments SDK parameters
- Service parameters
- Custom parameters
Payments SDK Parameters
Clients must make sure to add these required metrics while invoking PaymentsSDK. These parameters are crucial in initiating the SDK and for analytics. Find below the set of parameters which needs to be passed:
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| PaymentConstants.MERCHANT_ID | MerchantId given by Juspay ExpressCheckout while registration. | Yes | String |
| PaymentConstants.CLIENT_ID | ClientID is a merchant SDK identifier. Eg. 'merchantId_android'. | Yes | String |
| PaymentConstants.ORDER_ID | Merchant OrderID created at Juspay during create_order server call. Mandatory for initiating Payments | Yes | String |
| PaymentConstants.AMOUNT | Amount of the transaction. | No | String |
| PaymentConstants.CUSTOMER_ID | Unique identifier of the customer. | No | String |
| PaymentConstants.CUSTOMER_EMAIL | Customer's email address. | No | String |
| PaymentConstants.CUSTOMER_MOBILE | Customer's phone number. | No | String |
| PaymentConstants.ENV | Can be either PaymentConstants.ENVIRONMENT.SANDBOX or PaymentConstants.ENVIRONMENT.PRODUCTION | No | String |
Service Parameters
The service Parameters are specific to the type of service being invoked. For accessing the Express Checkout APIs, the following parameters need to be passed in addition to the Payment SDK parameters described above.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| PaymentConstants.SERVICE | The type of service, a client wants to invoke. "in.juspay.ec" | Yes | String |
| PaymentConstants.CLIENT_AUTH_TOKEN | The payment session token obtained from Juspay Servers from create_order API call | Yes | String |
| PaymentConstants.END_URLS | 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. | Yes | ArrayList |
| PaymentConstants.PAYLOAD | JSON string to be passed. This parameter defines the action to be performed by the SDK. Refer Payload section below. | Yes | String |
Custom Parameters
Custom Parameters are meant for future use in case we decide to add new parameters for merchant specific requirements and analytical purposes. Custom Parameters are always prefixed with "udf_" and preferred to be a String type value.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| udf_ | Custom Field | No | String |
| udf_ | Custom Field | No | String |
Sample Code
Below is a sample code for initializing Juspay SDK
Bundle juspayBundle = new Bundle();
// Base Parameters
juspayBundle.putString(PaymentConstants.MERCHANT_ID, getJuspayMerchantID());
juspayBundle.putString(PaymentConstants.CLIENT_ID, getJuspayClientId());
juspayBundle.putString(PaymentConstants.ORDER_ID, getOrderId());
juspayBundle.putString(PaymentConstants.AMOUNT, getOrderAmount());
juspayBundle.putString(PaymentConstants.CUSTOMER_ID, getCustomerId());
juspayBundle.putString(PaymentConstants.CLIENT_EMAIL, getCustomerEmail());
juspayBundle.putString(PaymentConstants.CLIENT_MOBILE_NO, getCustomerMobile());
juspayBundle.putString(PaymentConstants.ENV, PaymentConstants.ENVIRONMENT.PRODUCTION);
// Service Parameters for in.juspay.ec
juspayBundle.putString(PaymentConstants.SERVICE, "in.juspay.ec");
juspayBundle.putString(PaymentConstants.CLIENT_AUTH_TOKEN , getJuspayClientAuthToken());
juspayBundle.putStringArrayList(PaymentConstants.END_URLS, getEndUrls());
juspayBundle.putString(PaymentConstants.PAYLOAD, juspayPayload.toString());
Starting the SDK
SDK can be started as a new activity or attached as a Fragment to the merchant activity.
Activity Based Integration
To start the SDK as an Android Activity, you can use the following snippet:
// Start Payment Activity
Intent juspayIntent = new Intent(this, PaymentActivity.class);
juspayIntent.putExtras(juspayBundle);
startActivityForResult(juspayIntent, JUSPAY_REQUEST_CODE);
Response will be handled in onActivityResult of your calling Activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); //mandatory
if(requestCode == JUSPAY_REQUEST_CODE) {
if(resultCode == Activity.RESULT_OK) { // Success Response
Log.d("success_response", data.getStringExtra(PaymentConstants.PAYLOAD));
} else if (resultCode == Activity.RESULT_CANCELLED) { // Failure or Abort Response
Log.d("failure_response", data.getStringExtra(PaymentConstants.PAYLOAD));
}
}
}
Fragment Based Integration
To attach the SDK as a Fragment to your existing activity, you can use the following snippet:
Create a PaymentFragment instance:
PaymentFragment fragment = new PaymentFragment();
Create a Callback Listener to listen for events:
JuspayCallback juspayCallback = new JuspayCallback() {
@Override
public void onResult(int requestCode, int resultCode, @Nullable Intent intent) {
Log.d("MerchantActivity", "onResult: " + requestCode + " resultCode " + resultCode);
removeFragment(fragment);
fragment = null;
}
};
fragment.setJuspayCallback(juspayCallback);
Pass the back pressed event to the fragment:
@Override
public void onBackPressed() {
if(fragment != null && fragment.isAdded()) {
fragment.backPressHandler(true);
} else {
super.onBackPressed();
}
}
Pass the onActivityResult to fragment by calling super:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); //mandatory
...
...
// Merchant Code
}
Attach the fragment to your Activity:
fragment.setArguments(juspayBundle);
fragment.setJuspayCallback(juspayCallback);
showFragment(fragment);
Attaching custom webviewclient. (during payments)
fragment.setWebViewClient(new SampleWebViewClient(fragment.getWebView(), fragment));
Note: Please note that the custom webviewclient should extend JuspayWebViewClient. And set it before attaching it to the activity.
Response handling
Please find below sample success and failure responses for any payment. Please make sure to get the final status checked from Express Checkout server.
Sample Payment Success Response
| Field | Type | Value |
|---|---|---|
| responsePayload | json string | "{orderId : String, status : String}" |
{
orderId : "order_1234",
status : "CHARGED"
}
Sample Error Response
| Field | Type | Value |
|---|---|---|
| responsePayload | json string | "{code : int , status : string, response : json }" |
{
code : 0,
status : "AUTHENTICATION_FAILED"
response : { errorCode: string, errorMessage : String}
}
Payment Payload
This section contains all the possible payloads for the in.juspay.ec service. Upon completion, the “onActivityResult” shall be invoked. The payload can be called from intent.getStringExtra(PaymentConstants.PAYLOAD)".
The payload is passed as Stringified JSON in PaymentConstants.PAYLOAD. This payload determines the action to be performed by the SDK. Please ensure that the correct payload is passed based on your existing configuration with Juspay and User action.
The following Operations are used to perform all activities related to Payment from the Mobile Application.
Credit/Debit Card Payment
This operation is called while making a card transaction from the client device. The same operation can be used for both stored cards and new cards with appropriate parameters. The details of the saved cards can be fetched through List stored cards API.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| opName | Must be cardTxn | Yes | String |
| paymentMethod | Mandatory only for ATMPIN authType, should be from supported banks. | Yes | String |
| authType | Default is null. ATMPIN for DebitCard authentication through ATM PIN (if enabled). | Only for ATM PIN transactions | String |
| cardToken | This is a one-time use token for paying through a saved card. Can be generated from List Stored Cards operation | String | |
| cardNumber | 16-19 digit card number entered by the user. | Only for fresh card transactions. | String |
| cardExpMonth | The expiry month of the card that can be found on the card | Mandatory for fresh card transaction | String |
| cardExpYear | The expiry month of the card that can be found on the card | Mandatory for fresh card transaction | String |
| nameOnCard | Name present on card | No | String |
| cardSecurityCode | CVV of the card. If CVV not present on the card, send an empty string. | Yes | String |
| saveToLocker | For a new card transaction, determines whether the card needs to be saved for future use. Default is false. True if the user accepts to save the card to the locker. | No | Boolean |
| isEmi | Default is set to FALSE | No | Boolean |
| emiBank | Represents the Card Issuing Bank. Refer EMI Support Matrix | No | String |
| emiTenure | Tenure of EMI in months. Refer EMI Support Matrix | No | String |
| emiType | Type of EMI ie STANDARD_EMI or NO_COST_EMI | No | String |
// STORED CARD TRANSACTION
JSONObject juspayPayload = new JSONObject();
juspayPayload.put("opName","cardTxn");
juspayPayload.put("cardToken",storedCardObject.cardToken);
juspayPayload.put("cardSecurityCode",””);
juspayPayload.put("isEmi",””);
juspayPayload.put("emiBank",””);
juspayPayload.put("emiTenure",””);
juspayPayload.put("emiType",””);
// NEW CARD TRANSACTION
JSONObject juspayPayload = new JSONObject();
juspayPayload.put("opName","cardTxn");
juspayPayload.put("cardNumber","");
juspayPayload.put("cardExpMonth",””);
juspayPayload.put("cardExpYear",””);
juspayPayload.put("nameOnCard",””);
juspayPayload.put("cardSecurityCode",””);
juspayPayload.put("saveToLocker",””);
juspayPayload.put("isEmi",””);
juspayPayload.put("emiBank",””);
juspayPayload.put("emiTenure",””);
juspayPayload.put("emiType",””);
Refer here to understand more about the API.
Netbanking Transaction
The Bank selected by the user needs to be passed in the paymentMethod Parameter. Please ensure to pass the correct string in this Parameter. The list of banks enabled through Juspay can be generated from the List Enabled Payment Methods operation.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| opName | Must be nbTxn | Yes | String |
| paymentMethod | Based on the bank selected by the user | Yes | String |
// NETBANKING TRANSACTION
JSONObject juspayPayload = new JSONObject();
juspayPayload.put("opName","nbTxn");
juspayPayload.put("paymentMethod",”NB_HDFC”);
Refer here to understand more about the API.
UPI Transaction
UPI transactions can happen through either the webcollect flow (user enters his VPA) or intent flow (user selects one of the UPI enabled Apps on his android phone).
Juspay provides a standalone UPI SDK that supports webcollect and intent flow along with the required UI to enabled seamless UPI payments. However, merchants can also call Juspay with directly with the VPA(webcollect) or Android App package name (intent).
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| opName | Must be upiTxn | Yes | String |
| paymentMethod | Must be UPI | Yes | String |
| displayNote | Any message to be displayed on UPI loading page/ Intent PSP UPI Application | No | String |
| upiSdkPresent | Depends on UPI Payment Gateway. | Yes | Boolean |
| custVpa | For webcollect transactions. UPI Collect request would be sent to this VPA. | No | String |
| payWithApp | Package name of UPI app, for direct intent transactions | No | String |
// UPI TRANSACTION
JSONObject juspayPayload = new JSONObject();
juspayPayload.put("opName","upiTxn");
juspayPayload.put("paymentMethod","UPI");
juspayPayload.put("displayNote","merch");
juspayPayload.put("upiSdkPresent",true);
juspayPayload.put("custVpa","");
juspayPayload.put("payWithApp","");
Reference
- Refer here to understand more about UPI web collect API.
- Refer here to understand more about UPI intent API.
- Please confirm with Juspay support team if UPI SDK is supported for your Payment Gateway
Note: Please confirm with the Juspay team whether your Payment Aggregator is supported for the specific flow before integration.
Wallet Transaction
Juspay supports most wallets in India for both redirection and Link & Pay flows.
In redirection mode, the user is taken to the wallet URL for payment where the user is required to enter his credentials and log in. The user needs to link his wallet every time.
For Link & Pay, the user can link his wallet to the Merchant using a one-time authentication. Post that, the wallet balance can be displayed on the merchant page itself. If sufficient balance is present, the wallet balance can be used for the payment. For insufficient balance, the user will be redirected to add money to the wallet page.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| opName | Must be walletTxn | Yes | String |
| paymentMethod | Name of Wallet select by user | Yes | String |
| directWalletToken | Wallet token for direct debit transactions | No | String |
| sdkPresent | Name of SDK in Merchant App for SDK transactions | No | String |
| walletMobileNumber | Mobile number to which wallet is linked. Used only for GooglePay | No | String |
| shouldLink | Pass true if wallet needs to be linked. Used only for PayPal | No | Boolean |
| Wallet Flow | sdkPresent value |
|---|---|
| Amazon pay redirection | ANDROID_AMAZONPAY_NONTOKENIZED |
| Amazon link and pay | ANDROID_AMAZONPAY_TOKENIZED |
| PayPal redirection/automatic | ANDROID_PAYPAL |
| PhonePe | ANDROID_PHONEPE |
| Googlepay | ANDROID_GOOGLEPAY |
| SIMPL | ANDROID_SIMPL |
// WALLET TRANSACTION
JSONObject juspayPayload = new JSONObject();
juspayPayload.put("opName","walletTxn");
juspayPayload.put("paymentMethod","walletObject.walletName");
juspayPayload.put("directWalletToken","walletObject.walletToken");
juspayPayload.put("sdkPresent",""walletObject.walletSdkName"");
juspayPayload.put("walletMobileNumber","walletObject.mobileNumber");
juspayPayload.put("shouldLink","walletObject.shouldLink");
Note: Please confirm with Juspay team whether your Payment Aggregator is supported for the specific flow before integration.
The directWalletToken is required for wallets enabled for direct debit through Juspay and if the user has already linked the wallet. For wallets which the customer is not linked, the wallet should first be linked through createWallet* operation and then allowed to make payment.
Note*
createWallet is not required for PayPal. For PayPal RT flow, linking happens via wallet transaction with shouldLink:true only.
For PayPal Link and Pay flow, linking happens via wallet transaction with shouldLink:true only along with metadata.PAYPAL:direct_wallet_version:v2 passed in Juspay Order Create request. Please refer to https://developer.juspay.in/reference#create-order-1 for specific parameters related to PayPal Link and Pay.Refer to https://developer.juspay.in/reference#googlepay-integration for GooglePay Integration.
The sdkPresent Param is used when wallet SDK is integrated into your app and Juspay is required to call the appropriate SDK for payment.
When both directWalletToken and sdkPresent are null, the transaction is considered as a wallet redirection transaction. The redirection URL will be loaded on the browser and transaction completed.
Refer here to understand more about wallet direct debit API.
Refer here to understand more about wallet redirection API.
Displaying Payment Options
The below operations needs to be called before the payment page is shown to the user. This helps merchants to decide on the payment options to be shown to the user. These details can also be fetched through server calls also through respective APIs. It is not required to create an order for calling these operations.
- List wallets with an updated balance
- List saved cards
- List enabled payment options
- Check for device-specific App/SDK
List wallets with an updated balance
This operation needs to be called before loading the payment page to get the details of the wallets of the user. This operation gives a list of linked wallets and their balances for the passed customerId.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| opName | must be refreshWalletBalances | Yes | String |
// LIST ALL LINKED WALLETS WITH UPDATED BALANCES
JSONObject juspayPayload = new JSONObject();
juspayPayload.put("opName","refreshWalletBalances");
Response Payload:
Please get the status of the wallet from _"linked" flag in the response.
{
total::Int,
offset::Int,
object::String,
list::Array
{
wallet::String,
token::String,
object::String,
linked::Boolean,
id::String,
lastRefreshed::String,
currentBalance:: Number,
metadata :: Json // Optional. Example: {"email": "[email protected]","payerId":"abcdef"}
},
count::Int
}
{
{
wallet:: String,
token:: String,
linked:: Boolean,
walletId :: String,
currentBalance:: Number,
lastRefreshed:: String,
},{},{}
}
List saved cards
This operation needs to be called before loading the payment page to get the details of the cards stored by the user.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| opName | must be cardList | Yes | String |
// LIST STORED CARDS
JSONObject juspayPayload = new JSONObject();
juspayPayload.put("opName","cardList");
Response Payload:
{
"customer_id": "guest_user",
"merchantId": "guest",
"cards": [
{
"card_token": "2ea1fc4d-cbeb-4df7-b03d-97198e5c5e4e",
"card_reference": "20d67719b2249ccd375f44fd98817a47",
"card_fingerprint": "f6f6ac14a9438561404e8ec0776d",
"card_number": "5264-XXXXXXXX-3394",
"card_isin": "526419",
"card_exp_year": "2014",
"card_exp_month": "10",
"card_type": "DEBIT",
"card_issuer": "HDFC BANK",
"card_brand": "MASTERCARD",
"nickname": "",
"name_on_card": "Real Card",
"expired": true
}
]
}
List enabled payment options
This operation gives the details of all eligible payment methods enabled for the merchant via Juspay. Any payment option not shown as part of this operation, must not be sent to Juspay for processing.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| opName | must be getPaymentMethods | Yes | String |
// LIST ENABLED PAYMENT METHODS
JSONObject juspayPayload = new JSONObject();
juspayPayload.put("opName","getPaymentMethods");
Response Payload:
{
"payment_methods":
[
{
"payment_method_type": "CARD",
"payment_method": "VISA",
"description": "Visa"
},
{
"payment_method_type": "CARD",
"payment_method": "MASTER",
"description": "Master Card"
},
{
"payment_method_type": "NB",
"payment_method": "NB_HDFC",
"description": "HDFC"
},
{
"payment_method_type": "WALLET",
"payment_method": "PAYTM",
"description": "Paytm"
},
]
}
Delete Card
This operation is used to delete a previously saved card from the user account.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| opName | must be deletecard | Yes | String |
| cardToken | This is a one time use token specific to a saved card that can be retrieved from List Stored Cards call | Yes | String |
// CHECK FOR DEVICE SPECIFIC APP/SDK
JSONObject juspayPayload = new JSONObject();
juspayPayload.put("opName","deleteCard");
juspayPayload.put("cardToken","c75a9fca-1121-418e-973c-47d5c4971456");
Response Payload:
The deleted field is a boolean which will confirm if the delete activity was successful. Will be true when the card is deleted.
{
card_token :: string
card_reference :: string
deleted :: boolean,
}
Tokenize Card
(opName : tokenizeCard)
| Field | Type | Description |
|---|---|---|
| opName* | String | Must be tokenizeCard |
| cardNumber* | String | 16-19 digit card number. |
| cardExpYear* | String | Expiry year on card |
| cardExpMonth* | String | Expiry Month on card |
| cardSecurityCode* | String | CVV of the card. If CVV not present on card, send an empty string. |
| nameOnCard | String | Name on card. |
Check for device-specific App/SDK
This operation helps the merchant to check for any device-specific App or SDK required before displaying a payment option on the UI or allowing the user to make a payment.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| opName | must be isDeviceReady | Yes | String |
| sdkPresent | sdk to be checked on the device | Yes | String |
// CHECK FOR DEVICE SPECIFIC APP/SDK
JSONObject juspayPayload = new JSONObject();
juspayPayload.put("opName","isDeviceReady");
juspayPayload.put("sdkPresent","ANDROID_GOOGLEPAY");
Response Payload:
{
{
status : boolean,
message : string
}
}
Please consider the app/SDK to be present on the Merchant device when the status returns true.
Linking User Wallet
The Juspay SDK supports linking the User Wallet to the merchant account, which enables one-click payment through wallets. The following operations allow merchants to execute the link and Pay flow from client side.
While it is not mandatory to create an order in Juspay Backend for utilizing these operations, the sessionToken needs to be freshly generated using the get_customer_token API. Refer here. (need to add API reference)
Refresh Wallet
The refreshWallet operation can be used to check if a particular wallet is already linked for a customer, update latest balance and generate a new token if already linked. Please note that the token is of one time usage only.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| opName | must be refreshWallet | Yes | String |
| walletId | WalletID given by Juspay. Not required for Wallet SDK Integration(Ex: AmazonPay) | Yes | String |
| sdkWalletIdentifier | Seller Id only for AmazonPay | Yes | String |
| walletName | Name of the Wallet | No | String |
// REFRESH WALLET
JSONObject juspayPayload = new JSONObject();
juspayPayload.put("opName","refreshWallet");
juspayPayload.put("walletId","walletObject.walletID");
juspayPayload.put("walletName","walletObject.walletName");
Please get the status of the wallet from _"linked" flag in the response.
Response Payload Format:
{
wallet :: String,
token :: String,
linked :: Boolean,
walletId :: String,
currentBalance :: Number,
lastRefreshed :: String
}
| Field | Type | When wallet is linked | When wallet is not linked |
|---|---|---|---|
| wallet | String | Name of the wallet | Name of the wallet |
| token | String | One-time use token to be used for making a direct debit transaction | Null |
| linked | Boolean | TRUE | FALSE |
| walletId | String | walletID generated by Juspay. Unique for a user, merchant, wallet combination. Not present for AMAZONPAY | NA |
| currentBalance | Number | Wallet balance of the customer | NULL |
| lastRefreshed | String | Timestamp when the balance was last updated in UTC. | NULL |
Refer here for more on refreshWallet API.
Create Wallet to trigger OTP
The createWallet operation is to be called when the User clicks on Link Account for a specific wallet on the Payment page. An OTP would be triggered to the mobile number linked to the customer_ID on Juspay.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| opName | must be createWallet | Yes | String |
| walletName | Name of the wallet | Yes | String |
| sdkWalletIdentifier | Any specific identifier for SDK wallet Integration. | No | String |
| mobileNumber | MobileNumber to which wallet needs to be linked. Not required if the same mobile number is previously mapped against customer entity | No | String |
Refer here for more on createWallet API.
// CREATE WALLET TO TRIGGER OTP
JSONObject juspayPayload = new JSONObject();
juspayPayload.put("opName","createWallet");
juspayPayload.put("walletName",walletObject.walletName);
juspayPayload.put("sdkWalletIdentifier",walletObject.sdkWalletIdentifier);
juspayPayload.put("mobileNumber",walletObject.mobileNumber);
Note:
- The UI for entering the OTP has to be handled by the Merchant.
- sdkWalletIdentifier is required for specific usecases where Merchant has integrated with Wallet SDKs independantly and needs to pass specific parameters to the SDK. eg. AmazonPay SellerId.
- The walletId parameter in the response will need to persisted and submitted along with the OTP.
- The operation can be called for resend OTP also.
Link Wallet
The linkWallet operation can be used for submitting the OTP entered by the User.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| opName | must be linkWallet | Yes | String |
| walletId | WalletID of the particular wallet | Yes | String |
| otp | OTP entered by the user | Yes | String |
// LINK WALLET TO SUBMIT OTP
JSONObject juspayPayload = new JSONObject();
juspayPayload.put("opName","linkWallet");
juspayPayload.put("walletId",walletObject.walletId);
juspayPayload.put("otp",walletObject.otp);
When the OTP is entered correctly, the wallet will be linked and the updated balance will be passed in the response.
For incorrect OTP, appropriate error messages will be passed.
Refer here for more on linkWallet API.
Delink Wallet
This operation helps the user to delink a previously linked wallet.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| opName | must be delinkWallet | Yes | String |
| walletId | WalletID of the particular wallet | Yes | String |
| walletName | Name of the wallet | Yes | String |
// DELINK WALLET
JSONObject juspayPayload = new JSONObject();
juspayPayload.put("opName","delinkWallet");
juspayPayload.put("walletId",walletObject.walletId);
juspayPayload.put("walletName",walletObject.walletName);
Once delinked, users will have to link their wallet again to make payment.
Refer here for more on delinkWallet API.
Eligibility
(opName : eligibility)
| Field | Type | Description |
|---|---|---|
| opName* | String | Must be eligibility |
Response:
| Field | Type | Value |
|---|---|---|
| code | String | SUCCESS |
| payload | Json | { paymentMethodsEligibility :: [{ status :: String, isEligible :: Boolean, paymentMethodType :: String, eligibilityStrategy :: String, paymentMethod :: String, description :: String, balance :: Number }] } |
Note: Order_id or amount should be passed in base params to check the eligibility.
Integration checklist
Please ensure that the following items are checked off before release to have a cleaner integration:
- Ensure that correct value is sent for MERCHANT_ID and CLIENT_ID to identify the Merchant.
- Send a unique ORDER_ID to cross-check data with Juspay.
- Please ensure that customer details are already updated on Juspay backend.
- Make sure to pass backpress event onBackPressed and call super.onActivityResult (in case of Fragment Based Integration).
- Get the final build tested by Juspay's QA team.
Juspay Safe Module
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 the SDK
The Android SDK library can be added as a direct dependency when you use Gradle. 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.
repositories {
mavenCentral()
maven {
url "https://maven.juspay.in/jp-build-packages/release/"
}
}
Add the following compile dependency to your project. Once again make sure you don’t accidentally add it to script dependencies.
dependencies {
compile 'in.juspay:godel-core:1.0.7'
}
Brief change log is available here
PreFetching Juspay Assets
Since the SDK uses a Micro Service architecture on top of Android, it is highly recommended to call the preFetch api.
PaymentActivity.preFetch(activity, clientId);
Note: ClientId is of the format "merchantId_android".
Initializing Bundle Parameters
Since the SDK is an enhanced Payments Orchestrator, the input is typically a bunch of basic Payments payload, passed via Bundle.
The parameters are grouped into three major components:
- Payments SDK parameters
- Service parameters
- Custom parameters
Payments SDK Parameters
Clients must make sure to add these required metrics while invoking PaymentsSDK. These parameters are crucial in initiating the SDK and for analytical purposes. Find below the set of parameters which needs to be passed:
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| PaymentConstants.MERCHANT_ID | MerchantId is given by Juspay | Yes | String |
| PaymentConstants.CLIENT_ID | ClientID created in Merchant Portal. Eg. 'merchant_android'. | Yes | String |
| PaymentConstants.TRANSACTION_ID | Represents the current transactionId. | No | String |
| PaymentConstants.ORDER_ID | OrderID is the alternative to transactionId. | No | String |
| PaymentConstants.AMOUNT | Amount of the transaction. | Yes | String |
| PaymentConstants.CUSTOMER_ID | Unique identifier of the customer. | No | String |
| PaymentConstants.CUSTOMER_EMAIL | Customer's email address. | No | String |
| PaymentConstants.CUSTOMER_MOBILE | Customer's phone number. | No | String |
| PaymentConstants.ENV | Can be either PaymentConstants.ENVIRONMENT.SANDBOX or PaymentConstants.ENVIRONMENT.PRODUCTION | No | String |
Service Parameters
The service Parameters are specific to the type of service being invoked. For initializing the JuspaySafe Browser, the following parameters need to be passed in addition to the Payment SDK parameters described above.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| PaymentConstants.SERVICE | The type of service, client wants to invoke. "in.juspay.godel" for JuspaySafe Browser | Yes | String |
| PaymentConstants.END_URLS | 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. | Yes (For Activity Based Integration) | ArrayList |
| PaymentConstants.URL | Start URL for payment | Yes | String |
| PaymentConstants.POST_DATA | POST parameters that must be passed to the URL | No | String |
| "clearCookies" | If true, we will clear WebView cookies whenever Juspay Webview is initialized. Default will be false | No | Boolean |
Custom Parameters
Custom Parameters are meant for future use in case we decide to add new parameters for merchant specific requirements and analytical purposes. Custom Parameters are always prefixed with "udf_" and preferred to be a String type value.
| Variable | Description | Mandatory | Type |
|---|---|---|---|
| udf_<var1 | Custom Field | No | String |
| udf_<var2 | Custom Field | No | String |
Sample Parameters
Below is a sample set of params for starting the SDK:
Bundle juspayBundle = new Bundle();
// Base Parameters
juspayBundle.putString(PaymentConstants.MERCHANT_ID, getJuspayMerchantID());
juspayBundle.putString(PaymentConstants.CLIENT_ID, getJuspayClientId());
juspayBundle.putString(PaymentConstants.ORDER_ID, getOrderId());
juspayBundle.putString(PaymentConstants.AMOUNT, getOrderAmount());
juspayBundle.putString(PaymentConstants.CUSTOMER_ID, getCustomerId());
juspayBundle.putString(PaymentConstants.CLIENT_EMAIL, getCustomerEmail());
juspayBundle.putString(PaymentConstants.CLIENT_MOBILE_NO, getCustomerMobile());
juspayBundle.putString(PaymentConstants.ENV, PaymentConstants.ENVIRONMENT.PRODUCTION);
// Service Parameters for in.juspay.ec
juspayBundle.putString(PaymentConstants.SERVICE, "in.juspay.godel");
juspayBundle.putStringArrayList(PaymentConstants.END_URLS, getEndUrls());
juspayBundle.putString(PaymentConstants.URL, startUrl);
Starting the SDK
SDK can be started as a new activity or attached as a Fragment to the merchant activity.
Activity Based Integration
To start the SDK as an Android Activity, you can use the following snippet:
// Start Payment Activity
Intent juspayIntent = new Intent(this, PaymentActivity.class);
juspayIntent.putExtras(juspayBundle);
startActivityForResult(juspayIntent, JUSPAY_REQUEST_CODE);
Response will be handled in onActivityResult of your calling Activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); //mandatory
if(requestCode == JUSPAY_REQUEST_CODE) {
if(resultCode == Activity.RESULT_OK) { // Success Response
Log.d("success_response", data.getStringExtra(PaymentConstants.PAYLOAD));
} else if (resultCode == Activity.RESULT_CANCELLED) { // Failure or Abort Response
Log.d("failure_response", data.getStringExtra(PaymentConstants.PAYLOAD));
}
}
}
Fragment Based Integration
To attach the SDK as a Fragment to your existing activity, you can use the following snippet:
Create a PaymentFragment instance:
PaymentFragment fragment = new PaymentFragment();
Create a Callback Listener to listen for events:
JuspayCallback juspayCallback = new JuspayCallback() {
@Override
public void onResult(int requestCode, int resultCode, @Nullable Intent intent) {
Log.d("MerchantActivity", "onResult: " + requestCode + " resultCode " + resultCode);
removeFragment(fragment);
fragment = null;
}
};
fragment.setJuspayCallback(juspayCallback);
Pass the back pressed event to the fragment:
@Override
public void onBackPressed() {
if(fragment != null && fragment.isAdded()) {
fragment.backPressHandler(true);
} else {
super.onBackPressed();
}
}
Pass the onActivityResult to fragment by calling super:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); //mandatory
...
...
// Merchant Code
}
Attach the fragment to your Activity:
fragment.setArguments(juspayBundle);
fragment.setJuspayCallback(juspayCallback);
showFragment(fragment);
Attaching custom webviewclient. (during payments)
fragment.setWebViewClient(new SampleWebViewClient(fragment.getWebView(), fragment));
Response Payload Details
The response payload will be sent in data.getStringExtra(PaymentConstants.PAYLOAD). Find below the set of parameters which will be sent:
| Variable | Description | Type | Example |
|---|---|---|---|
| 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 | "https://www.sampleurl.com/success" |
Send Payment Status
As soon as the payment is over, send us the notification on the status of the payment. These responses are crucial in order to track transaction success/failure metrics.
GodelTracker.getInstance().trackPaymentStatus(:transactionId,
GodelTracker.SUCCESS);
Payment status can be one of: SUCCESS, FAILURE or CANCELLED.
POSTing from Server
To minimize the chances of missing payment status, we would recommend you to POST this information to our servers directly using the following call. This could be in addition to the call on GodelTracker in the client.
POST https://logs.juspay.in/godel/analytics
HTTP/1.1
Content-Type: application/json
{
"data": [{
"merchant_id": "your_merchant_id",
"client_id": "your_client_id",
"order_id": "ORD141231112205308",
"transaction_id": "ORD141231112205308",
"payment_status": "SUCCESS"
}]
}
In the above, we recommend that you send both order_id and transaction_id if you are initializing the fragment with these. However, one of them would suffice as long as uniqueness is achieved.
We rely greatly on the payment status metrics to fine tune our system (both current and future versions). Failure to send status metrics might result in us disabling the enhancements for your customers.
Integration checklist
- Make sure to pass back press event onBackPressed and call super.onActivityResult (in case of Fragment-Based Integration).
- 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.
- Get the final build tested by Juspay's QA team.
Updated 2 months ago