---
page_source: https://juspay.io/in/docs/payment-page-enterprise/flutter/base-sdk-integration/open-hypercheckout-screen
page_title: 3. Open Hypercheckout Screen
---


## 3. Open Payment Page



Opening payment page requires you to call the process SDK API with process payload as input. 

Please note that it should not be called on an HyperSDK instance which has not been initiated. To verify if an instance is initiated, kindly refer to check SDK **isInitialised**  section under [code snippets](https://docs.juspay.in/payment-page-enterprise/android/resources/code-snippets).

Once the payment page is opened, your users can proceed with the transactions. Refer to steps below for details


### **3.1 Create OrderDetails Payload** 




### Step 1.1. Substep


Using your cart information, create the orderDetails payload as given below


### Payload
- **Base Parameters**:
  - Value:
    - **Order_id**:
      - Description: Unique Identifier for the order. Should be Alphanumeric with character length less than 21.
        
        Example:-order-id-9876580Note: If you have enabled **paymentAttempt**  event, then you can send **order_id**  in **resumePayment**  event.
      - Tags: String, Mandatory
    - **Merchant_id**:
      - Description: Merchant ID provided by Juspay during onboarding
      - Tags: String, Mandatory
    - **Amount**:
      - Description: Amount that the customer has to pay. Will accept stringified double or integer values with upto two decimal places. For example, "100.15" and "100" are valid input but "100.1532" is not valid.
        
        Example:-1.00
      - Tags: String, Mandatory
    - **Timestamp**:
      - Description: Epoch Unix timestamp in milliseconds
        
        Example:-1695029591000
      - Tags: String, Mandatory
    - **Customer_id**:
      - Description: It is the ID with which merchant refers to a customer object. This id is used to access the stored payment methods, allow EMI transactions and setup subscriptions.In case of guest login it should be an empty string.
        
        Example:-customer-id-007
      - Tags: String, Mandatory
    - **Customer_email**:
      - Description: Email address of the customer. If the backend gateway requires it, then you must send this value.**Constraints :** You are allowed to use alphanumeric characters and the following special characters:`!#$%&'*+-/=?^_.{|}~`@`
        
        `_`and `.` cannot appear at the beginning or end of the local part of the email address (before and after the `@`symbol).
        
        Example:-test@gmail.com
      - Tags: String, Mandatory
    - **Customer_phone**:
      - Description: Mobile number or fixed line number of the customer. If the backend gateway requires it, then you must send this value. We recommend passing a 10-digit number without including the "+91" or any mobile country code at the beginning.
        
        Example:-9999999912
      - Tags: String, Mandatory
    - **Return_url**:
      - Description: A fully qualified URL on which the customer will be redirected after payment completion. It is also required to provide the control back to SDK after the completion of transaction. This URL takes higher precedence over the common return URL configured in your account settings.
        
        **NOTE** :
        
              1. URL shouldn't contain any query parameters or Ip address
              2. URL should be a valid HTTPS endpoint that is reachable from Juspay servers
              3. Return URL should not redirect to a different URL
              4. Please ensure to pass a valid return URL in the session API call or configure it on the Juspay Dashboard. Not doing the same will lead the SDK not being closed post transaction completion
        
        Example:-[https://shop.merchant.com](https://shop.merchant.com)
      - Tags: String, Mandatory
    - **Order_type**:
      - Description: Applicable only for TPV Orders.
      - Value: TPV_PAYMENT
      - Tags: String, Conditional
    - **Features**:
      - Value:
        - **PaymentAttempt**:
          - Value:
            - **Enabled**:
              - Description: When passed as true merchant receives a payment attempt when the user clicks on proceed to pay on the payment page. Sample event -[https://juspay.io/in/docs/payment-page-enterprise/android/resources/order-updation-events#2.-paymentAttempt-Event](https://juspay.io/in/docs/payment-page-enterprise/android/resources/order-updation-events#2.-paymentAttempt-Event)
              - Value: true/false
              - Tags: Boolean, Optional
          - Tags: String, Optional
      - Tags: String, Optional
- **Mandate/Subscriptions Parameters Parameters**:
  - Value:
    - **Options.create_mandate**:
      - Description: Enum: 'REQUIRED' , "OPTIONAL'.
        
        Defines what kind mandate support is available during a session. Required to create a Mandate.
        
        Chose between the follow values based upon requirements :-
        
              * REQUIRED : Mandate is must for completing transaction. Only instruments which support Mandate will be shown
              * OPTIONAL : Mandate is a user choice for completing transaction.
        
        Example:-OPTIONAL
      - Tags: String, Mandatory
    - **Mandate.max_amount**:
      - Description: This is the maximum amount which can be debited via mandate. Required, only when amount type is variable. If amount type is fixed, amount parameter itself will be considered as max amount.
        
        Example:-1000.0
      - Tags: String, Mandatory
    - **Mandate.start_date**:
      - Description: Mandate start date in UNIX EPOCH timestamp (UTC timezone). The start date has to be today's date
        
        Example:-1633087969
      - Tags: String, Optional
    - **Mandate.end_date**:
      - Description: Mandate end date in UNIX EPOCH timestamp (UTC timezone). Post end date, mandate will move to **EXPIRED**  state and recurring mandate will not be allowed. By default value will be Mandate start date + 30 years
        
        Example:-1633088989
      - Tags: String, Optional
    - **Mandate.frequency**:
      - Description: Defines the frequency of mandate execution, how often a customer should be chargedData type **ENUM:** **ONETIME (Supported only by UPI)** **DAILY** **WEEKLY** **FORTNIGHTLY** **MONTHLY** **BIMONTHLY** **QUARTERLY** **HALFYEARLY** **YEARLY** **ASPRESENTED** 
        
        **Default:** `ASPRESENTED`
        
        **Note:** 1. Daily is not supported by Billdesk and Paytm (For cards)2. In UPI AutoPay, ONETIME frequency, Mandate is valid only for 90 Days
        
        Example:-ASPRESENTED
      - Tags: String, Mandatory
    - **Mandate.rule_value**:
      - Description: 1-7 when frequency is WEEKLY. In weekly, serial numbers start from Monday. Monday represents 1 and Sunday represents 7.
        
        1-16 when frequency is FORTNIGHTLY. This mandate is executed twice a month. First day of the month is represented by value '1' and ends with '15' on 15th day of the month. Then again starts with '1' for 16th of the month and ends with the last day of the month.
        
        1-31 when frequency is MONTHLY, BIMONTHLY, QUARTERLY, HALFYEARLY, or YEARLY.
        
        Not required when frequency is ONETIME, DAILY, ASPRESENTED. For Razorpay, rule_value will be considered as the last date of the week/month/year. For Paytm, rule_value will be considered as today's date/day
        
        Example:-1
      - Tags: String
    - **Mandate.amount_rule**:
      - Description: Data type **ENUM: FIXED, VARIABLE** .By default, it is considered as VARIABLE. In case of FIXED **amount_rule** 
        
        Example:-FIXED
      - Tags: String
    - **Mandate.revokable_by_customer**:
      - Description: If false, the mandate cannot be revoked by the customer once set. Applicable only for UPI mandate. It should be true for Recurring and true/false for **ONETIME** . By default value will be true
        
        Example:-false
      - Tags: Boolean
    - **Mandate.block_funds**:
      - Description: Set to `true` if funds have to be blocked while a mandate is being created. Should be true for **ONETIME**  and false for **Recurring** . By default value will be **TRUE**  for ONETIME and **FALSE**  for Recurring.
      - Tags: Boolean
- **User Defined Parameters**:
  - Value:
    - **Udf1 , udf2 , udf3 , udf4, udf5**:
      - Description: User Defined Parameter (UDF)
        
        The above field can be used to send any user defined parameters. These fields will not accept any special characters in value
        
        The UDF parameters for orders can be seen in the JUSPAY dashboard under each order
        
        Example:-user5349
      - Tags: String (Upto 255 Characters), No Special Characters Supported
    - **Udf6 , udf7 , udf8 , udf9 , udf10**:
      - Description: User Defined Parameter (UDF)
        
        This field can be used to send any user defined parameters
        
        The UDF parameters for orders can be seen in the JUSPAY dashboard under each order
        
        Example:-user_5349
      - Tags: String (Upto 255 Characters), Special Characters Supported
- **Metadata Parameters**:
  - Value:
    - **Metadata.JUSPAY:gateway_reference_id**:
      - Description: **Use this parameter only when you have use case of gateway reference ID.** For detailed information check [here](https://docs.juspay.in/resources/docs/common-resources/gateway-reference-id)
      - Tags: String
    - **Metadata.subvention_amount**:
      - Description: The amount for which the EMI interest should not be calculated. Ex: **metadata.subvention_amount=90**
      - Tags: String, Optional
    - **Metadata.webhook_url**:
      - Description: Merchant can pass dynamic webhook URL in this field. The webhook authentication would be same as the one configured on the dashboard. Ex: **metadata.webhook_url=** **[https://merchant.juspay/response](https://merchant.juspay/response)**
      - Tags: String, Optional
    - **Metadata.bank_account_details**:
      - Description: Applicable for TPV Orders.
        
        Either bank_account_number or bank_account_id is mandatory
      - Value:
        - **Bank_account_number**:
          - Description: Customer Bank account
          - Tags: String, Conditional
        - **Bank_ifsc**:
          - Description: IFSC code of bank
          - Tags: String, Optional
        - **Juspay_bank_code**:
          - Description: juspay bank code given in eligibility API. e.g. JP_HDFC
          - Tags: String, Optional
        - **Bank_beneficiary_name**:
          - Description: Name of account holder
          - Tags: String, Optional
        - **Bank_account_id**:
          - Description: bank account id provided by Juspay while storing bank account details
          - Tags: String, Conditional
        - **Bank_account_type**:
          - Description: Account type of the Customer Account
          - Value: CURRENT or SAVINGS
          - Tags: String, Conditional
      - Tags: Array, Conditional
- **Mutual_fund_details**:
  - Description: Contains the details of Mutual Fund.
  - Value:
    - **MemberId**:
      - Description: Member Id with ICCL or ARN_RIA with RTA.
      - Tags: String, Mandatory
    - **UserId**:
      - Description: Client Id with ICCL or USER_CODE with RTA.
      - Tags: String, Mandatory
    - **MfPartner**:
      - Description: NSE/BSE/KFIN/CAMS.
      - Tags: String, Mandatory
    - **OrderNumber**:
      - Description: Unique order number of each MF. Oder Number in ICCL or APPL_NO in RTA.
      - Tags: String, Mandatory
    - **Amount**:
      - Description: Individual MF amount within the array of MF being purchased.
      - Tags: String, Mandatory
    - **InvestmentType**:
      - Description: LUMPSU/ SIP
      - Tags: String, Mandatory
    - **FolioNumber**:
      - Description: Folio Number of the MF, used for RTA reporting. Mandatory for RTA reporting.
      - Tags: String, Optional
    - **PanNumber**:
      - Description: PAN Number of the user, used for RTA reporting. Mandatory for RTA reporting.
      - Tags: String, Optional
    - **AmcCode**:
      - Description: AMC Code of the MF, used for RTA reporting. Mandatory for RTA reporting.
      - Tags: String, Optional
    - **SchemeCode**:
      - Description: Scheme Code of the MF, used for RTA reporting. Mandatory for RTA reporting.
      - Tags: String, Optional
  - Tags: List, Optional
- **Basket**:
  - Description: To pass product specific information in the user’s basket/cart. This key is required to be passed as stringified JSON
  - Value:
    - **ProductName**:
      - Description: Name of the product
      - Tags: String, Conditional
    - **Id**:
      - Description: Product ID
      - Tags: String, Conditional
    - **Quantity**:
      - Description: Quantity of the product that User has in basket/cart
      - Tags: String, Conditional
    - **UnitPrice**:
      - Description: Price of the product
      - Tags: String, Conditional
  - Tags: String, Optional
- **Amount_info**:
  - Description: To pass amount breakup information for displaying surcharge, convenience fee or shipping fee. This key is required to be passed as stringified JSON.
    
    Example:`"amount_info": "{\"base_amount\":\"100\", \"add_on_amounts\": [{\"name\":\"SURCHARGE\",\"amount\":\"2\"}]}"`
  - Tags: String, Optional
- **Features**:
  - Description: To enable features like paymentAttempt.Example: 
    
    `\"features\":{\"paymentAttempt\":{\"enable\":true}}`
  - Value:
    - **PaymentAttempt**:
      - Description: This event is triggered whenever user attempts to make payment using any PO.[paymentAttempt Payload](https://juspay.io/in/docs/payment-page-enterprise/android/resources/order-updation-events#2.-paymentAttempt-Event)
        
        **resumePayment :**  In response to paymentAttempt, merchant needs to call the resumePayment event with `hyperServices.process` callStatus value true is indicative of merchant approval to proceed with the transaction, whereas false aborts the payment and SDK exits to return control back to merchant website.[resumePayment Payload](https://juspay.io/in/docs/payment-page-enterprise/android/resources/order-updation-events#3.-resumePayment-Event)
      - Value:
        - **Enable**:
          - Description: If true, then SDK will wait for resumePayment call before proceeding with the transaction.
          - Value: true/false
          - Tags: Boolean, Mandatory
      - Tags: String, Optional
  - Tags: String, Optional





### **3.2 Sign the OrderDetails Payload** 




### Step 1.1. Substep


To provide enterprise-grade security, it is required to create a RSA-SHA256 signature of the orderDetails payload created above. 

The orderDetails JSON payload first needs to be converted into a string and then signed using the Private key stored on the merchant server. Click here to know [How to Generate the Signature](https://docs.juspay.in/payment-page-enterprise/android/resources/generating-the-signature)

The orderDetails payload along with the signature are required to create the process payload as a next step




### **3.3 Create Process Payload** 




### Step 1.1. Substep


The process API takes a JSONObject as argument. This argument is also known as process payload.


### Payload
- **Action**:
  - Description: Pass `paymentPage` is to start the Hypercheckout screenPass `paymentManagement` to start the payment management interface for deleting saved cards and linking/unlinking wallets
  - Tags: String, Mandatory
- **MerchantId**:
  - Description: Merchant ID provided by Juspay during onboarding
  - Tags: String, Mandatory
- **ClientId**:
  - Description: Client ID provided by Juspay during onboarding
  - Tags: String, Mandatory
- **OrderId**:
  - Description: Unique identifier for the order. Should be **Alphanumeric with character length less than 21.** _Order ID at Juspay end is_ _**not**_ _case sensitive. We do not differentiate between upper and lower case values_
  - Tags: String, Mandatory
- **Amount**:
  - Description: Amount that the customer has to pay. Will accept stringified double or integer values with upto two decimal places. For example, "100.15" and "100" are valid input but "100.1532" is not valid.
    
    Example:-1.00
  - Tags: String, Mandatory
- **CustomerId**:
  - Description: It is the ID with which merchant refers to a customer object. This id is used to access the stored payment methods, allow EMI transactions and setup subscriptions.In case of guest login it should be an empty string.
    
    Example:-customer-id-007
  - Tags: String, Mandatory
- **CustomerEmail**:
  - Description: Email address of the customer. If the backend gateway requires it, then you must send this value.**Constraints :** You are allowed to use alphanumeric characters and the following special characters:`!#$%&'*+-/=?^_.{|}~`@`
    
    `_`and `.` cannot appear at the beginning or end of the local part of the email address (before and after the `@`symbol).
    
    Example:-test@gmail.com
  - Tags: String, Mandatory
- **CustomerMobile**:
  - Description: Mobile number or fixed line number of the customer. If the backend gateway requires it, then you must send this value. We recommend passing a 10-digit number without including the "+91" or any mobile country code at the beginning.
    
    Example:-9999999912
  - Tags: String, Mandatory
- **OrderDetails**:
  - Description: Stringify the JSON payload created in Step 3.1
  - Tags: String, Mandatory
- **Signature**:
  - Description: In signature, pass the Output of Step 3.2
    
    Example:-
    
    AZOn8jH8RPWSzrbZ0iiHSLjMdvnvDBkyKslgx4yDadtiQ49kqf8vFh7GMEC/aSARgfovwUOBoPPRTksV6IXNlwIBwuSLWeH7/dIBC+FdtgOR1UNhRGKM17xNg/A6iLufR880Pa31QT3JAWJtRPeQ3aGczsgsFc8NzbSNCQmV2w7ziSSUAwdpU8JWthkFc2oW23QTcMHXnk/EHXf9vAHUZS1x2vKMnrUE6JuTa8vNLlpAcsZ8ueGLvBuobx6lBltsyb8+DjWT+3+W4nt1xmH734g9aOkduLyQTvGIYDKCpnvWdR0J34SvgUnCnv5XzRm9+HQInZDSslJ+1q5hAe3PQQ==
  - Tags: String, Mandatory
- **MerchantKeyId**:
  - Description: Unique identifier against which merchant’s public key is stored with Juspay. Can be fetched from Juspay Dashboard. `Login>EC Operations>Settings>Security>RSA Key`
  - Tags: String, Mandatory
- **Language**:
  - Description: Pass the language value to localise payment experience in regional language. Accepted values are "english", "hindi", "telugu", "tamil", "bengali", "malayalam", "gujarati", "kannada", "marathi"
  - Tags: String
- **PayeeName**:
  - Description: Custom payeeName to override default payeeName in UPI-INTENT APP_May or may not reflect due to extra verification at UpiApps end which cannot be controlled by Juspay_
  - Tags: String
- **DisplayNote**:
  - Description: Custom displayNote to override default displayNote(transaction-note) in UPI-INTENT APP_May or may not reflect due to extra verification at UpiApps end which cannot be controlled by juspay_
  - Tags: String
- **Description**:
  - Description: Description for order to be displayed to the user on amountBar
    
    Example:-Complete your payment
  - Tags: String







#### Sample Process Payload Code Snippet:

```sample process payload
{
  "requestId": "8cbc3fad-8b3f-40c0-ae93-2d7e75a8624a",
  "service": "in.juspay.hyperpay",
  "payload": {
    "action": "paymentPage",
    "merchantId": "<your merchant id>",
    "clientId": "<your client id>",
    "orderId": "R1096438018",
    "amount": "1.00",
    "customerId": "1234567890",
    "customerEmail": "test@gmail.com",
    "customerMobile": "9739534710",
    "orderDetails": "{\"order_id\":\"R1096438018\",\"amount\":\"1.00\",\"customer_id\":\"1234567890\",\"merchant_id\":\"idea_preprod\",\"customer_email\":\"test007@gmail.com\",\"customer_phone\":\"1234567890\",\"return_url\":\"https:\\/\\/sandbox.juspay.in\\/end\",\"timestamp\":\"1571922200845\",\"basket\": \"[{\\\"productName\\\":\\\"ABC\\\",\\\"id\\\":\\\"123\\\",\\\"quantity\\\":1,\\\"unitPrice\\\":1.0}]\"}",
    "signature": "AZOn8jH8RPWSzrbZ0iiHSLjMdvnvDBkyKslgx4yDadtiQ49kqf8vFh7GMEC/aSARgfovwUOBoPPRTksV6IXNlwIBwuSLWeH7/dIBC+FdtgOR1UNhRGKM17xNg/A6iLufR880Pa31QT3JAWJtRPeQ3aGczsgsFc8NzbSNCQmV2w7ziSSUAwdpU8JWthkFc2oW23QTcMHXnk/EHXf9vAHUZS1x2vKMnrUE6JuTa8vNLlpAcsZ8ueGLvBuobx6lBltsyb8+DjWT+3+W4nt1xmH734g9aOkduLyQTvGIYDKCpnvWdR0J34SvgUnCnv5XzRm9+HQInZDSslJ+1q5hAe3PQQ==",
    "merchantKeyId": "2980",
    "language": "english"
  }
}
```



### **3.4 Call Process API** 




### Step 1.1. Substep


Pass the process payload created in `Step 3.3`, to `process API call.`

Process is to be called on the same instance of HyperService using which initiate API was triggered.


#### Java Code Snippet:

```java
hyperInstance.process(processPayload);
```

#### iOS - Swift Code Snippet:

```ios - swift
self.hyperInstance.process(processPayload)
```

#### iOS Objective-C Code Snippet:

```ios objective-c
[self.hyperInstance process:processPayload];
```

#### React Native - Javascript Code Snippet:

```react native - javascript
HyperSdkReact.process(JSON.stringify(processPayload));
```




#### Code Snippets: -

#### Java Code Snippet:

```java
package in.juspay.devtools;

import androidx.appcompat.app.AppCompatActivity;
import androidx.coordinatorlayout.widget.CoordinatorLayout;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import in.juspay.hypersdk.data.JuspayResponseHandler;
import in.juspay.hypersdk.ui.HyperPaymentsCallbackAdapter;
import org.json.JSONObject;
import okhttp3.*;
import java.io.IOException;
import java.util.Base64;
import android.webkit.WebView;
import in.juspay.hyperinteg.HyperServiceHolder;

public class CheckoutActivity extends AppCompatActivity {

    private Button processButton;
    private HyperServiceHolder hyperServicesHolder;
    private CoordinatorLayout coordinatorLayout;
    private ProgressDialog dialog;
    private String amountString;
    private int item1Price, item2Price, item1Count, item2Count;
    private TextView item1PriceTv, item2PriceTv, item1CountTv, item2CountTv, totalAmountTv, taxTv, totalPayableTv;
    private double taxPercent = 0.18;
    private ImageView backImage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_checkout);
    }

    @Override
    protected void onStart() {
        super.onStart();

        updatingUI();

        hyperServicesHolder = new HyperServiceHolder(this);
        hyperServicesHolder.setCallback(createHyperPaymentsCallbackAdapter());
        processButton = findViewById(R.id.rectangle_9);
        processButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dialog.show();
                try{
                    run();
                } catch (Exception e){

                }
            }
        });
        backImage = findViewById(R.id.imageView);
        backImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                onBackPressed();
            }
        });
    }

    // block:start:create-hyper-callback
    private HyperPaymentsCallbackAdapter createHyperPaymentsCallbackAdapter() {
        return new HyperPaymentsCallbackAdapter() {
            @Override
            public void onEvent(JSONObject jsonObject, JuspayResponseHandler responseHandler) {
                Intent redirect = new Intent(CheckoutActivity.this, ResponsePage.class);
                redirect.putExtra("responsePayload", jsonObject.toString());
                System.out.println("jsonObject>>> " +jsonObject);
                try {
                    String event = jsonObject.getString("event");
                    if (event.equals("hide_loader")) {
                        // Hide Loader
                        dialog.hide();
                    }
                    // Handle Process Result
                    // This case will reach once the Hypercheckout screen closes
                    // block:start:handle-process-result
                    else if (event.equals("process_result")) {
                        boolean error = jsonObject.optBoolean("error");
                        JSONObject innerPayload = jsonObject.optJSONObject("payload");
                        String status = innerPayload.optString("status");

                        if (!error) {
                            switch (status) {
                                case "charged":
                                    // Successful Transaction
                                    // check order status via S2S API
                                    redirect.putExtra("status", "OrderSuccess");
                                    startActivity(redirect);
                                    break;
                                case "cod_initiated":
                                    redirect.putExtra("status", "CODInitiated");
                                    startActivity(redirect);
                                    break;
                            }
                        } else {
                            switch (status) {
                                case "backpressed":
                                    // user back-pressed from PP without initiating transaction

                                    break;
                                case "user_aborted":
                                    // user initiated a txn and pressed back
                                    // check order status via S2S API
                                    Intent successIntent = new Intent(CheckoutActivity.this, ResponsePage.class);
                                    redirect.putExtra("status", "UserAborted");
                                    startActivity(redirect);
                                    break;
                                case "pending_vbv":
                                    redirect.putExtra("status", "PendingVBV");
                                    startActivity(redirect);
                                    break;
                                case "authorizing":
                                    // txn in pending state
                                    // check order status via S2S API
                                    redirect.putExtra("status", "Authorizing");
                                    startActivity(redirect);
                                    break;
                                case "authorization_failed":
                                    redirect.putExtra("status", "AuthorizationFailed");
                                    startActivity(redirect);
                                    break;
                                case "authentication_failed":
                                    redirect.putExtra("status", "AuthenticationFailed");
                                    startActivity(redirect);
                                    break;
                                case "api_failure":
                                    redirect.putExtra("status", "APIFailure");
                                    startActivity(redirect);
                                    break;
                                    // txn failed
                                    // check order status via S2S API
                                default:
                                    redirect.putExtra("status", "APIFailure");
                                    startActivity(redirect);
                                    break;
                            }
                        }
                    }
                    // block:end:handle-process-result
                } catch (Exception e) {
                    // merchant code...
                }
            }
        };
    }
    // block:end:create-hyper-callback



    //block:start:onBackPressed
    @Override
    public void onBackPressed() {
        boolean handleBackpress = hyperServicesHolder.onBackPressed();
        if(!handleBackpress) {
            super.onBackPressed();
        }

    }
    //block:end:onBackPressed

    private void updatingUI(){
        coordinatorLayout = findViewById(R.id.coordinatorLayout);
        dialog = new ProgressDialog(CheckoutActivity.this);
        dialog.setMessage("Processing...");

        Intent i = getIntent();
        item1Count = i.getIntExtra("item1Count", 1);
        item2Count = i.getIntExtra("item2Count", 1);
        item1Price = i.getIntExtra("item1Price", 1);
        item2Price = i.getIntExtra("item2Price", 1);

        item1PriceTv = findViewById(R.id.some_id1);
        item2PriceTv = findViewById(R.id.some_id2);
        item1CountTv = findViewById(R.id.x2);
        item2CountTv = findViewById(R.id.x3);

        item1CountTv.setText("x"+Integer.toString(item1Count));
        item2CountTv.setText("x"+Integer.toString(item2Count));
        int item1Amount = item1Price*item1Count;
        int item2Amount = item2Price*item2Count;
        item1PriceTv.setText("₹ "+Integer.toString(item1Amount));
        item2PriceTv.setText("₹ "+Integer.toString(item2Amount));

        totalAmountTv = findViewById(R.id.some_id);
        taxTv = findViewById(R.id.some_id3);
        totalPayableTv = findViewById(R.id.some_id5);

        int totalAmount = item1Amount + item2Amount;
        double tax = totalAmount * taxPercent;
        double totalPayable = totalAmount + tax;
        Helper helper = new Helper();
        amountString = Double.toString(helper.round(totalPayable, 2));
        String taxString = Double.toString(helper.round(tax, 2));
        totalAmountTv.setText("₹ "+Integer.toString(totalAmount));
        taxTv.setText("₹ "+taxString);
        totalPayableTv.setText("₹ "+amountString);
    }

    /*
    Optional Block
    These functions are only supposed to be implemented in case if you are overriding
    onActivityResult or onRequestPermissionsResult Life cycle hooks


    - onActivityResult
    - Handling onActivityResult hook and passing data to HyperServices Instance, to handle App Switch
    @Override
    public void onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        // block:start:onActivityResult

        // If super.onActivityResult is available use following:
        // super.onActivityResult(requestCode, resultCode, data);

        // In case super.onActivityResult is NOT available please use following:
        // if (data != null) {
        //    hyperServices.onActivityResult(requestCode, resultCode, data);
        // }

        // block:end:onActivityResult

        // Rest of your code.
    }


    - onRequestPermissionsResult
    - Handling onRequestPermissionsResult hook and passing data to HyperServices Instance, to OTP reading permissions
    @Override
    public void onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        // block:start:onRequestPermissionsResult

        //  If super.onRequestPermissionsResult is available use following:
        // super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        // In case super.onActivityResult is NOT available please use following:
        // hyperServices.onRequestPermissionsResult(requestCode, permissions, grantResults);

        // block:end:onRequestPermissionsResult
    }
     */
}

```

#### Kotlin Code Snippet:

```kotlin
package `in`.juspay.devtools

import `in`.juspay.hypersdk.data.JuspayResponseHandler
import `in`.juspay.hypersdk.ui.HyperPaymentsCallbackAdapter
import android.app.ProgressDialog
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.webkit.WebView
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.snackbar.Snackbar
import `in`.juspay.hyperinteg.HyperServiceHolder
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import org.json.JSONObject
import java.io.IOException
import java.util.*

class CheckoutActivity : AppCompatActivity() {
    var processButton: Button? = null
    var hyperServicesHolder: HyperServiceHolder? = null
    var coordinatorLayout: CoordinatorLayout? = null
    var dialog: ProgressDialog? = null
    var amountString: String? = null
    var item1Price = 0
    var item2Price = 0
    var item1Count = 0
    var item2Count = 0
    var item1PriceTv: TextView? = null
    var item2PriceTv: TextView? = null
    var item1CountTv: TextView? = null
    var item2CountTv: TextView? = null
    var totalAmountTv: TextView? = null
    var taxTv: TextView? = null
    var totalPayableTv: TextView? = null
    var taxPercent = 0.18
    var backImage: ImageView? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_checkout)
    }

    override fun onStart() {
        super.onStart()
        updatingUI()
        hyperServicesHolder = HyperServiceHolder(this)
        hyperServicesHolder!!.setCallback(createHyperPaymentsCallbackAdapter())
        processButton = findViewById(R.id.rectangle_9)
        processButton?.setOnClickListener(View.OnClickListener {
            dialog!!.show()
            try {
                run()
            } catch (e: Exception) {
            }
        })
        backImage = findViewById(R.id.imageView)
        backImage?.setOnClickListener(View.OnClickListener { onBackPressed() })
    }
    

    //block:start:create-hyper-callback
    private fun createHyperPaymentsCallbackAdapter(): HyperPaymentsCallbackAdapter {
        return object : HyperPaymentsCallbackAdapter() {
            override fun onEvent(jsonObject: JSONObject, responseHandler: JuspayResponseHandler?) {
                val redirect = Intent(this@CheckoutActivity, ResponsePage::class.java)
                redirect.putExtra("responsePayload", jsonObject.toString())
                try {
                    val event = jsonObject.getString("event")
                    if (event == "hide_loader") {
                        // Hide Loader
                        dialog!!.hide()
                    } else if (event == "process_result") {
                        //block:start:handle-process-result
                        val error = jsonObject.optBoolean("error")
                        val innerPayload = jsonObject.optJSONObject("payload")
                        val status = innerPayload.optString("status")
                        if (!error) {
                            when (status) {
                                "charged" -> {
                                    // Successful Transaction
                                    // check order status via S2S API
                                    redirect.putExtra("status", "OrderSuccess")
                                    startActivity(redirect)
                                }
                                "cod_initiated" -> {
                                    redirect.putExtra("status", "CODInitiated")
                                    startActivity(redirect)
                                }
                            }
                        } else {
                            when (status) {
                                "backpressed" -> {
                                }
                                "user_aborted" -> {
                                    // user initiated a txn and pressed back
                                    // check order status via S2S API
                                    val successIntent = Intent(
                                        this@CheckoutActivity,
                                        ResponsePage::class.java
                                    )
                                    redirect.putExtra("status", "UserAborted")
                                    startActivity(redirect)
                                }
                                "pending_vbv" -> {
                                    redirect.putExtra("status", "PendingVBV")
                                    startActivity(redirect)
                                }
                                "authorizing" -> {
                                    // txn in pending state
                                    // check order status via S2S API
                                    redirect.putExtra("status", "Authorizing")
                                    startActivity(redirect)
                                }
                                "authorization_failed" -> {
                                    redirect.putExtra("status", "AuthorizationFailed")
                                    startActivity(redirect)
                                }
                                "authentication_failed" -> {
                                    redirect.putExtra("status", "AuthenticationFailed")
                                    startActivity(redirect)
                                }
                                "api_failure" -> {
                                    redirect.putExtra("status", "APIFailure")
                                    startActivity(redirect)
                                }
                            }
                        }
                        // block:end:handle-process-result
                    }
                } catch (e: Exception) {
                    // merchant code...
                }
            }
        }
    }

    // block:end:create-hyper-callback
    fun showSnackbar(message: String?) {
        coordinatorLayout = findViewById(R.id.coordinatorLayout)
        val snackbar = Snackbar.make(coordinatorLayout!!, message!!, Snackbar.LENGTH_LONG)
        snackbar.show()
    }

    //block:start:onBackPressed
    override fun onBackPressed() {
        val handleBackpress: Boolean = hyperServicesHolder?.onBackPressed() == true
        if (handleBackpress) {
            super.onBackPressed()
        }
    }

    //block:end:onBackPressed
    
    /*
    Optional Block
    These functions are only supposed to be implemented in case if you are overriding
    onActivityResult or onRequestPermissionsResult Life cycle hooks


    - onActivityResult
    - Handling onActivityResult hook and passing data to HyperServices Instance, to handle App Switch
    @Override
    public void onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        // block:start:onActivityResult

        // If super.onActivityResult is available use following:
        // super.onActivityResult(requestCode, resultCode, data);

        // In case super.onActivityResult is NOT available please use following:
        // if (data != null) {
        //    hyperServices.onActivityResult(requestCode, resultCode, data);
        // }

        // block:end:onActivityResult

        // Rest of your code.
    }


    - onRequestPermissionsResult
    - Handling onRequestPermissionsResult hook and passing data to HyperServices Instance, to OTP reading permissions
    @Override
    public void onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        // block:start:onRequestPermissionsResult

        //  If super.onRequestPermissionsResult is available use following:
        // super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        // In case super.onActivityResult is NOT available please use following:
        // hyperServices.onRequestPermissionsResult(requestCode, permissions, grantResults);

        // block:end:onRequestPermissionsResult
    }
     */

    fun updatingUI() {
        dialog = ProgressDialog(this@CheckoutActivity)
        dialog!!.setMessage("Processing...")
        val i = intent
        item1Count = i.getIntExtra("item1Count", 1)
        item2Count = i.getIntExtra("item2Count", 1)
        item1Price = i.getIntExtra("item1Price", 1)
        item2Price = i.getIntExtra("item2Price", 1)
        item1PriceTv = findViewById(R.id.some_id1)
        item2PriceTv = findViewById(R.id.some_id2)
        item1CountTv = findViewById(R.id.x2)
        item2CountTv = findViewById(R.id.x3)
        item1CountTv?.setText("x" + Integer.toString(item1Count))
        item2CountTv?.setText("x" + Integer.toString(item2Count))
        val item1Amount = item1Price * item1Count
        val item2Amount = item2Price * item2Count
        item1PriceTv?.setText("₹ " + Integer.toString(item1Amount))
        item2PriceTv?.setText("₹ " + Integer.toString(item2Amount))
        totalAmountTv = findViewById(R.id.some_id)
        taxTv = findViewById(R.id.some_id3)
        totalPayableTv = findViewById(R.id.some_id5)
        val totalAmount = item1Amount + item2Amount
        val tax = totalAmount * taxPercent
        val totalPayable = totalAmount + tax
        amountString = java.lang.Double.toString(round(totalPayable, 2))
        val taxString = java.lang.Double.toString(round(tax, 2))
        totalAmountTv?.setText("₹ " + Integer.toString(totalAmount))
        taxTv?.setText("₹ $taxString")
        totalPayableTv?.setText("₹ $amountString")
    }

    companion object {
        fun round(value: Double, places: Int): Double {
            var value = value
            require(places >= 0)
            val factor = Math.pow(10.0, places.toDouble()).toLong()
            value = value * factor
            val tmp = Math.round(value)
            return tmp.toDouble() / factor
        }
    }
}

```


> **Warning**
> As soon as you sign up with Juspay, we set you up with a Dummy PG automatically. Using this Dummy PG, you can run test transactions with a pre-configured set of cards. You may also configure the test credentials of the gateway and use the respective test cards for completing the transaction journey. Please refer to the [Test Resources](/payment-page/android/resources/test-resources)page for more details.

