> ## Documentation Index
> Fetch the complete documentation index at: https://www.cashfree.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Android Element Integration

> Integrate the Cashfree Payment Gateway Element SDK into your Android application to accept payments via card, net banking, wallet, and UPI.

The Cashfree Payment Gateway Element SDK lets you build a fully custom payment experience within your Android application. Unlike the hosted checkout, you collect payment details directly in your own UI and pass them to the SDK, giving you complete control over the look and feel of your payment flow.

The SDK supports four payment methods: card, net banking, wallet, and UPI Intent.

<Note>
  This page describes the raw card flow, where your application collects the card number directly and is responsible for PCI DSS compliance. To avoid handling raw card numbers, use the [Android Custom Card Component](/docs/payments/online/element/custom-card/android-custom-card) instead, which captures the card number inside an SDK-managed view.
</Note>

## Prerequisites

Complete the following tasks before you start the integration:

* Create a [Cashfree Merchant Account](https://merchant.cashfree.com/merchants/signup).
* Log in to the [Merchant Dashboard](https://merchant.cashfree.com/auth/login) and generate an **App ID** and **Secret Key**. Learn how to [generate API keys](/docs/api-reference/authentication#generate-api-keys).
* Set your application's `minSdkVersion` to API level 19 or higher.

The integration consists of three steps:

<CardGroup cols={3}>
  <Card title="Step 1" icon="money-bill-wave" href="/docs/payments/online/element/mobile/android#step-1-create-an-order-server-side">
    Create an order
  </Card>

  <Card title="Step 2" icon="desktop" href="/docs/payments/online/element/mobile/android#step-2-open-the-payment-page-client-side">
    Open the payment page
  </Card>

  <Card title="Step 3" icon="circle-check" href="/docs/payments/online/element/mobile/android#step-3-confirm-the-payment-server-side">
    Confirm the payment
  </Card>
</CardGroup>

## Step 1: Create an order <Badge color="green">Server-side</Badge>

Create an order from your backend server before you process any payment.

<Note>This API requires your secret key. Create orders through your server only — do not call this API directly from your mobile application.</Note>

##### API request for creating an order

Here's a sample request for creating an order using your desired backend language. Cashfree offers backend [SDKs](/docs/api-reference/payments/sdk#payment-sdk) to simplify the integration process.

<CodeGroup>
  ```bash curl theme={"dark"}
  curl --location 'https://sandbox.cashfree.com/pg/orders' \
  --header 'X-Client-Secret: {{clientKey}}' \
  --header 'X-Client-Id: {{clientId}}' \
  --header 'x-api-version: 2025-01-01' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --data-raw '{
    "order_amount": 10.10,
    "order_currency": "INR",
    "customer_details": {
      "customer_id": "USER123",
      "customer_name": "joe",
      "customer_email": "joe.s@cashfree.com",
      "customer_phone": "+919876543210"
    },
    "order_meta": {
      "return_url": "https://b8af79f41056.eu.ngrok.io?order_id=order_123"
    }
  }'
  ```

  ```javascript nodejs theme={"dark"}
  import { Cashfree, CFEnvironment } from "cashfree-pg";

  const cashfree = new Cashfree(
  	CFEnvironment.PRODUCTION,
  	"{Client ID}",
  	"{Client Secret Key}"
  );

  function createOrder() {
  	var request = {
  		order_amount: "1",
  		order_currency: "INR",
  		customer_details: {
  			customer_id: "node_sdk_test",
  			customer_name: "",
  			customer_email: "example@gmail.com",
  			customer_phone: "9999999999",
  		},
  		order_meta: {
  			return_url:
  				"https://test.cashfree.com/pgappsdemos/return.php?order_id=order_123",
  		},
  		order_note: "",
  	};

  	cashfree
  		.PGCreateOrder(request)
  		.then((response) => {
  			console.log("Order created successfully:", response.data);
  		})
  		.catch((error) => {
  			console.error("Error setting up order request:", error.response.data);
  		});
  }
  ```

  ```python python theme={"dark"}
  from cashfree_pg.models.create_order_request import CreateOrderRequest
  from cashfree_pg.api_client import Cashfree
  from cashfree_pg.models.customer_details import CustomerDetails


  Cashfree.XClientId = {Client ID}
  Cashfree.XClientSecret = {Client Secret Key}
  Cashfree.XEnvironment = Cashfree.XSandbox
  x_api_version = "2023-08-01"

  def create_order():
          customerDetails = CustomerDetails(customer_id="123", customer_phone="9999999999")
          createOrderRequest = CreateOrderRequest(order_amount=1, order_currency="INR", customer_details=customerDetails)
          try:
              api_response = Cashfree().PGCreateOrder(x_api_version, createOrderRequest, None, None)
              print(api_response.data)
          except Exception as e:
              print(e)
  ```

  ```java java theme={"dark"}
  import com.cashfree.*;

  Cashfree.XClientId = {Client Key};
  Cashfree.XClientSecret = {Client Secret Key};
  Cashfree.XEnvironment = Cashfree.SANDBOX;

  static void createOrder() {
    CustomerDetails customerDetails = new CustomerDetails();
    customerDetails.setCustomerId("123");
    customerDetails.setCustomerPhone("9999999999");

    CreateOrderRequest request = new CreateOrderRequest();
    request.setOrderAmount(1.0);
    request.setOrderCurrency("INR");
    request.setCustomerDetails(customerDetails);
    try {
      Cashfree cashfree = new Cashfree();
      ApiResponse<OrderEntity> response = cashfree.PGCreateOrder("2023-08-01", request, null, null, null);
      System.out.println(response.getData().getOrderId());

    } catch (ApiException e) {
      throw new RuntimeException(e);
    }
  }
  ```

  ```go go theme={"dark"}
  import (
    cashfree "github.com/cashfree/cashfree-pg/v3"
  )

  func createOrder() {

  clientId := {Client ID}
  clientSecret := {Client Secret Key}
  cashfree.XClientId = &clientId
  cashfree.XClientSecret = &clientSecret
  cashfree.XEnvironment = cashfree.SANDBOX

  request := cashfree.CreateOrderRequest{
  		OrderAmount: 1,
  		CustomerDetails: cashfree.CustomerDetails{
  			CustomerId:    "1",
  			CustomerPhone: "9999999999",
  		},
  		OrderCurrency: "INR",
  		OrderSplits:   []cashfree.VendorSplit{},
  	}
  	version := "2023-08-01"
  	response, httpResponse, err := cashfree.PGCreateOrder(&version, &request, nil, nil, nil)
  	if err != nil {
  		fmt.Println(err.Error())
  	} else {
  		fmt.Println(httpResponse.StatusCode)
  		fmt.Println(response)
      }
  }
  ```

  ```csharp .net theme={"dark"}
  using cashfree_pg.Client;
  using cashfree_pg.Model;

  Cashfree.XClientId = {Client ID};
  Cashfree.XClientSecret = {Client Secret Key};
  Cashfree.XEnvironment = Cashfree.PRODUCTION;
  var cashfree = new Cashfree();
  var xApiVersion = "2023-08-01";

  void CreateOrder() {
      var customerDetails = new CustomerDetails("123", null, "9999999999");
      var createOrdersRequest = new CreateOrderRequest(null, 1.0, "INR", customerDetails);
      try {
          // Create Order
          var result = cashfree.PGCreateOrder(xApiVersion, createOrdersRequest, null, null, null);
          Console.WriteLine(result);
          Console.WriteLine(result.StatusCode);
          Console.WriteLine((result.Content as OrderEntity));
      } catch (ApiException e) {
          Console.WriteLine("Exception when calling PGCreateOrder: " + e.Message);
          Console.WriteLine("Status Code: " + e.ErrorCode);
          Console.WriteLine(e.StackTrace);
      }
  }
  ```

  ```php php theme={"dark"}
  \Cashfree\Cashfree::$XClientId = "<x-client-id>";
  \Cashfree\Cashfree::$XClientSecret = "<x-client-secret>";
  \Cashfree\Cashfree::$XEnvironment = Cashfree\Cashfree::$SANDBOX;

  $cashfree = new \Cashfree\Cashfree();

  $x_api_version = "2023-08-01";
  $create_orders_request = new \Cashfree\Model\CreateOrdersRequest();
  $create_orders_request->setOrderAmount(1.0);
  $create_orders_request->setOrderCurrency("INR");
  $customer_details = new \Cashfree\Model\CustomerDetails();
  $customer_details->setCustomerId("123");
  $customer_details->setCustomerPhone("9999999999");
  $create_orders_request->setCustomerDetails($customer_details);

  try {
      $result = $cashfree->PGCreateOrder($x_api_version, $create_orders_request);
      print_r($result);
  } catch (Exception $e) {
      echo 'Exception when calling PGCreateOrder: ', $e->getMessage(), PHP_EOL;
  }
  ```
</CodeGroup>

After successfully creating an order, you will receive a unique `order_id` and `payment_session_id` that you need for subsequent steps.

You can view the complete API request and response for `/orders` in the [Create Order API](/docs/api-reference/payments/latest/orders/create-order).

## Step 2: Open the payment page <Badge color="orange">Client-side</Badge>

After you create the order, open the payment page so the customer can provide payment details.

### 1. Set up the SDK

The Cashfree Android SDK is available on Maven Central. The latest version is [2.5.0](https://github.com/cashfree/nextgen-android). The SDK requires Android API level 19 or higher.

Add the following dependency to your app-level `build.gradle` file:

```gradle theme={"dark"}
implementation 'com.cashfree.pg:api:2.5.0'
```

### 2. Select a payment method

The Element SDK supports the following payment methods:

<Tabs>
  <Tab title="Card">
    In this flow, the customer enters their card details directly in your application UI. Your application receives the raw card number and passes it to the SDK, so your application remains in PCI DSS scope for card data. To avoid handling raw card numbers, use the [Android Custom Card Component](/docs/payments/online/element/custom-card/android-custom-card) instead.
  </Tab>

  <Tab title="Net banking">
    In this flow, you identify the customer's bank using a bank code. The SDK opens Cashfree's hosted net banking screen so the customer can log in and authorise the payment.
  </Tab>

  <Tab title="Wallet">
    In this flow, the customer pays using a wallet provider (for example, PhonePe) linked to their registered phone number. The SDK opens Cashfree's hosted wallet screen to complete the payment.
  </Tab>

  <Tab title="UPI Intent">
    In this flow, the SDK discovers the UPI apps installed on the customer's device and launches the selected app so the customer can authorise the payment.
  </Tab>
</Tabs>

### 3. Complete the payment

To complete the payment, follow these steps:

1. Set up the payment callback.
2. Create a `CFSession` object.
3. Create the payment object for the selected payment method.
4. Optionally, customise the theme.
5. Initiate the payment using `doPayment()`.

#### Set up the payment callback

The SDK exposes an interface `CFCheckoutResponseCallback` to receive callbacks from the SDK once the payment flow ends. This interface consists of two methods:

```java theme={"dark"}
public void onPaymentVerify(String orderID)
public void onPaymentFailure(CFErrorResponse cfErrorResponse, String orderID)
```

<Tip>Register the callback in your activity's `onCreate` method. This configuration also handles activity restart cases correctly.</Tip>

The following example shows how to implement the callback in your activity:

```java theme={"dark"}
public class YourActivity extends AppCompatActivity implements CFCheckoutResponseCallback {

    @Override
    public void onPaymentVerify(String orderID) {
        Log.e("onPaymentVerify", "verifyPayment triggered");
    }

    @Override
    public void onPaymentFailure(CFErrorResponse cfErrorResponse, String orderID) {
        Log.e("onPaymentFailure " + orderID, cfErrorResponse.getMessage());
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_element_checkout);
        try {
            // If you are using a fragment, add this line inside onCreate() of your Fragment.
            CFPaymentGatewayService.getInstance().setCheckoutCallback(this);
        } catch (CFException e) {
            e.printStackTrace();
        }
    }
}
```

#### Create a session

The `CFSession` object holds the session context for the payment. It accepts the `payment_session_id` and `order_id` obtained from [Step 1](#step-1-create-an-order-server-side), and the Cashfree environment (`.SANDBOX` or `.PRODUCTION`).

```java theme={"dark"}
CFSession cfSession = new CFSession.CFSessionBuilder()
        .setEnvironment(CFSession.Environment.SANDBOX) // or .PRODUCTION
        .setPaymentSessionID(paymentSessionID)
        .setOrderId(orderID)
        .build();
```

#### Create a payment object

The SDK provides a dedicated payment builder for each supported payment method. Build only the object that corresponds to the payment method your customer has selected.

<Tabs>
  <Tab title="Card">
    Use the following builders to create a card payment object. This is the raw card flow — your application passes the full card number to the SDK using `setCardNumber`.

    ```java theme={"dark"}
    CFCard cfCard = new CFCard.CFCardBuilder()
            .setCardHolderName(cardHolderName)
            .setCardNumber(cardNumber)
            .setCardExpiryMonth(cardMM)
            .setCardExpiryYear(cardYY)
            .setCVV(cardCVV)
            .setChannel("post")
            .build();

    CFCardPayment cfCardPayment = new CFCardPayment.CFCardPaymentBuilder()
            .setSession(cfSession)
            .setCard(cfCard)
            .build();
    ```

    <Note>
      `setChannel` is a required field on the card builder. The SDK uses this value to determine how to process the card payment. Contact [Cashfree Support](https://merchant.cashfree.com/merchants/landing?env=prod\&raise_issue=1) to confirm the correct channel value for flows that require native OTP authentication.
    </Note>
  </Tab>

  <Tab title="Net banking">
    The `setBankCode` field accepts the four-digit bank code of the customer's bank.

    ```java theme={"dark"}
    CFNetBanking cfNetBanking = new CFNetBanking.CFNetBankingBuilder()
            .setBankCode(bankCode) // required, 4-digit bank code
            .build();

    CFNetBankingPayment cfNetBankingPayment = new CFNetBankingPayment.CFNetBankingPaymentBuilder()
            .setSession(cfSession)
            .setCfNetBanking(cfNetBanking)
            .build();
    ```
  </Tab>

  <Tab title="Wallet">
    The `setProvider` field accepts the wallet provider identifier (for example, `phonepe`), and `setPhone` accepts the customer's registered phone number.

    ```java theme={"dark"}
    CFWallet cfWallet = new CFWallet.CFWalletBuilder()
            .setProvider(channel) // required, for example "phonepe"
            .setPhone(phone)      // required
            .build();

    CFWalletPayment cfWalletPayment = new CFWalletPayment.CFWalletPaymentBuilder()
            .setSession(cfSession)
            .setCfWallet(cfWallet)
            .build();
    ```

    <Note>
      Confirm the complete list of supported wallet provider values with [Cashfree Support](https://merchant.cashfree.com/merchants/landing?env=prod\&raise_issue=1) before you go live.
    </Note>
  </Tab>

  <Tab title="UPI Intent">
    Use the following builder to create a UPI Intent payment object. The `setUPIID` field accepts the package name of the UPI app your customer selected.

    ```java theme={"dark"}
    CFUPI cfupi = new CFUPI.CFUPIBuilder()
            .setMode(CFUPI.Mode.INTENT)
            .setUPIID(packageName)
            .build();

    CFUPIPayment cfupiPayment = new CFUPIPayment.CFUPIPaymentBuilder()
            .setSession(cfSession)
            .setCfUPI(cfupi)
            .build();
    ```

    <Note>
      To get the package name, use `CFUPIUtil.getInstalledUPIApps` to fetch the UPI apps installed on the customer's device:

      ```java theme={"dark"}
      CFUPIUtil.getInstalledUPIApps(this, new CFUPIUtil.UPIAppsCallback() {
          @Override
          public void onUPIAppsFetched(ArrayList<CFUPIApp> upiAppList) {
              if (upiAppList != null && !upiAppList.isEmpty()) {
                  CFUPIApp upiApp = upiAppList.get(0); // CFUPIApp exposes getDisplayName() and getAppId()
                  String packageName = upiApp.getAppId();
              }
          }
      });
      ```

      `onUPIAppsFetched` is invoked on a background thread. Wrap any UI updates in `runOnUiThread()`.
    </Note>
  </Tab>
</Tabs>

#### Customise the theme (optional)

Apply a custom theme to the payment screen to match your application's visual design. Use the `CFTheme` builder to set colours for the navigation bar, buttons, and text, then apply the theme to your payment object before you call `doPayment()`.

```java theme={"dark"}
CFTheme theme = new CFTheme.CFThemeBuilder()
        .setNavigationBarBackgroundColor("#6A2222") // sets the status bar and toolbar colour
        .setNavigationBarTextColor("#FFFFFF")        // sets the toolbar text colour
        .setButtonBackgroundColor("#6Aaaaa")          // sets the primary button background colour
        .setButtonTextColor("#FFFFFF")                // sets the primary button text colour
        .setPrimaryTextColor("#11385b")               // sets the primary text colour
        .setSecondaryTextColor("#808080")             // sets the secondary text colour
        .build();

cfCardPayment.setTheme(theme);
// or: cfNetBankingPayment.setTheme(theme);
// or: cfWalletPayment.setTheme(theme);
// or: cfupiPayment.setTheme(theme);
```

#### Initiate the payment

Call `doPayment()` to open the Cashfree payment screen for the selected method. The example below uses `cfCardPayment`. Replace it with `cfNetBankingPayment`, `cfWalletPayment`, or `cfupiPayment` for your selected payment method.

```java theme={"dark"}
// Replace YourActivity with your activity class name.
CFCorePaymentGatewayService.getInstance().doPayment(YourActivity.this, cfCardPayment);
```

#### Sample code

The following example shows a complete integration, including session creation, payment object setup for each method, and payment initiation.

<AccordionGroup>
  <Accordion title="Element checkout sample">
    ```java theme={"dark"}
    package com.cashfree.sdk_sample.java;

    import androidx.appcompat.app.AppCompatActivity;

    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;

    import com.cashfree.pg.api.CFPaymentGatewayService;
    import com.cashfree.pg.core.api.CFCorePaymentGatewayService;
    import com.cashfree.pg.core.api.CFSession;
    import com.cashfree.pg.core.api.CFTheme;
    import com.cashfree.pg.core.api.callback.CFCheckoutResponseCallback;
    import com.cashfree.pg.core.api.card.CFCard;
    import com.cashfree.pg.core.api.card.CFCardPayment;
    import com.cashfree.pg.core.api.exception.CFException;
    import com.cashfree.pg.core.api.netbanking.CFNetBanking;
    import com.cashfree.pg.core.api.netbanking.CFNetBankingPayment;
    import com.cashfree.pg.core.api.upi.CFUPI;
    import com.cashfree.pg.core.api.upi.CFUPIPayment;
    import com.cashfree.pg.core.api.utils.CFErrorResponse;
    import com.cashfree.pg.core.api.utils.CFUPIApp;
    import com.cashfree.pg.core.api.utils.CFUPIUtil;
    import com.cashfree.pg.core.api.wallet.CFWallet;
    import com.cashfree.pg.core.api.wallet.CFWalletPayment;

    public class ElementCheckoutActivity extends AppCompatActivity implements CFCheckoutResponseCallback {

        String orderID = "ORDER_ID";
        String paymentSessionID = "PAYMENT_SESSION_ID";
        CFSession.Environment cfEnvironment = CFSession.Environment.SANDBOX;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_element_checkout);
            try {
                CFPaymentGatewayService.getInstance().setCheckoutCallback(this);
            } catch (CFException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onPaymentVerify(String orderID) {
            Log.e("onPaymentVerify", "verifyPayment triggered");
        }

        @Override
        public void onPaymentFailure(CFErrorResponse cfErrorResponse, String orderID) {
            Log.e("onPaymentFailure " + orderID, cfErrorResponse.getMessage());
        }

        public void doCardPayment(View view) {
            try {
                CFSession cfSession = new CFSession.CFSessionBuilder()
                        .setEnvironment(cfEnvironment)
                        .setPaymentSessionID(paymentSessionID)
                        .setOrderId(orderID)
                        .build();
                CFCard cfCard = new CFCard.CFCardBuilder()
                        .setCardHolderName(cardHolderName)
                        .setCardNumber(cardNumber)
                        .setCardExpiryMonth(cardMM)
                        .setCardExpiryYear(cardYY)
                        .setCVV(cardCVV)
                        .setChannel("post")
                        .build();
                CFTheme theme = new CFTheme.CFThemeBuilder()
                        .setNavigationBarBackgroundColor("#6A2222")
                        .setNavigationBarTextColor("#FFFFFF")
                        .setButtonBackgroundColor("#6Aaaaa")
                        .setButtonTextColor("#FFFFFF")
                        .setPrimaryTextColor("#11385b")
                        .setSecondaryTextColor("#808080")
                        .build();
                CFCardPayment cfCardPayment = new CFCardPayment.CFCardPaymentBuilder()
                        .setSession(cfSession)
                        .setCard(cfCard)
                        .build();
                cfCardPayment.setTheme(theme);
                CFCorePaymentGatewayService.getInstance().doPayment(ElementCheckoutActivity.this, cfCardPayment);
            } catch (CFException exception) {
                exception.printStackTrace();
            }
        }

        public void doNetBankingPayment(View view) {
            try {
                CFSession cfSession = new CFSession.CFSessionBuilder()
                        .setEnvironment(cfEnvironment)
                        .setPaymentSessionID(paymentSessionID)
                        .setOrderId(orderID)
                        .build();
                CFNetBanking cfNetBanking = new CFNetBanking.CFNetBankingBuilder()
                        .setBankCode(bankCode)
                        .build();
                CFTheme theme = new CFTheme.CFThemeBuilder()
                        .setNavigationBarBackgroundColor("#6A2222")
                        .setNavigationBarTextColor("#FFFFFF")
                        .setButtonBackgroundColor("#6Aaaaa")
                        .setButtonTextColor("#FFFFFF")
                        .setPrimaryTextColor("#11385b")
                        .setSecondaryTextColor("#808080")
                        .build();
                CFNetBankingPayment cfNetBankingPayment = new CFNetBankingPayment.CFNetBankingPaymentBuilder()
                        .setSession(cfSession)
                        .setCfNetBanking(cfNetBanking)
                        .build();
                cfNetBankingPayment.setTheme(theme);
                CFCorePaymentGatewayService.getInstance().doPayment(ElementCheckoutActivity.this, cfNetBankingPayment);
            } catch (CFException exception) {
                exception.printStackTrace();
            }
        }

        public void doWalletPayment(View view) {
            try {
                CFSession cfSession = new CFSession.CFSessionBuilder()
                        .setEnvironment(cfEnvironment)
                        .setPaymentSessionID(paymentSessionID)
                        .setOrderId(orderID)
                        .build();
                CFWallet cfWallet = new CFWallet.CFWalletBuilder()
                        .setProvider(channel)
                        .setPhone(phone)
                        .build();
                CFTheme theme = new CFTheme.CFThemeBuilder()
                        .setNavigationBarBackgroundColor("#6A2222")
                        .setNavigationBarTextColor("#FFFFFF")
                        .setButtonBackgroundColor("#6Aaaaa")
                        .setButtonTextColor("#FFFFFF")
                        .setPrimaryTextColor("#11385b")
                        .setSecondaryTextColor("#808080")
                        .build();
                CFWalletPayment cfWalletPayment = new CFWalletPayment.CFWalletPaymentBuilder()
                        .setSession(cfSession)
                        .setCfWallet(cfWallet)
                        .build();
                cfWalletPayment.setTheme(theme);
                CFCorePaymentGatewayService.getInstance().doPayment(ElementCheckoutActivity.this, cfWalletPayment);
            } catch (CFException exception) {
                exception.printStackTrace();
            }
        }

        public void doUPIIntentPayment(View view) {
            CFUPIUtil.getInstalledUPIApps(this, new CFUPIUtil.UPIAppsCallback() {
                @Override
                public void onUPIAppsFetched(ArrayList<CFUPIApp> upiAppList) {
                    // Invoked on a background thread — wrap UI updates in runOnUiThread().
                    if (upiAppList != null && !upiAppList.isEmpty()) {
                        CFUPIApp upiApp = upiAppList.get(0);
                        initiateUPIPayment(upiApp.getAppId());
                    }
                }
            });
        }

        private void initiateUPIPayment(String packageName) {
            try {
                CFSession cfSession = new CFSession.CFSessionBuilder()
                        .setEnvironment(cfEnvironment)
                        .setPaymentSessionID(paymentSessionID)
                        .setOrderId(orderID)
                        .build();
                CFUPI cfupi = new CFUPI.CFUPIBuilder()
                        .setMode(CFUPI.Mode.INTENT)
                        .setUPIID(packageName)
                        .build();
                CFTheme theme = new CFTheme.CFThemeBuilder()
                        .setNavigationBarBackgroundColor("#6A2222")
                        .setNavigationBarTextColor("#FFFFFF")
                        .setButtonBackgroundColor("#6Aaaaa")
                        .setButtonTextColor("#FFFFFF")
                        .setPrimaryTextColor("#11385b")
                        .setSecondaryTextColor("#808080")
                        .build();
                CFUPIPayment cfupiPayment = new CFUPIPayment.CFUPIPaymentBuilder()
                        .setSession(cfSession)
                        .setCfUPI(cfupi)
                        .build();
                cfupiPayment.setTheme(theme);
                cfupiPayment.setLoaderEnable(true);
                CFCorePaymentGatewayService.getInstance().doPayment(ElementCheckoutActivity.this, cfupiPayment);
            } catch (CFException exception) {
                exception.printStackTrace();
            }
        }

    }
    ```
  </Accordion>
</AccordionGroup>

#### Sample GitHub code

<AccordionGroup>
  <Accordion title="Android Element integration">
    [GitHub sample](https://github.com/cashfree/nextgen-android/blob/d65184fa0fad01d8916b758847973ac890db0591/app/src/main/java/com/cashfree/sdk_sample/java/ElementCheckoutActivity.java)
  </Accordion>
</AccordionGroup>

## Step 3: Confirm the payment <Badge color="green">Server-side</Badge>

After the SDK delivers a callback via `onPaymentVerify`, confirm the payment status from your backend before taking any action. The SDK callback signals only that the payment flow has ended. It does not guarantee a successful payment.

To verify an order you can call our `/pg/orders` endpoint from your backend. You can also use our SDK to achieve the same.

<CodeGroup>
  ```bash curl theme={"dark"}
  curl --request GET \
       --url https://sandbox.cashfree.com/pg/orders/{order_id} \
       --header 'accept: application/json' \
       --header 'x-api-version: 2025-01-01' \
       --header 'x-client-id: "YOUR APP ID GOES HERE"' \
       --header 'x-client-secret: "YOUR SECRET KEY GOES HERE"'
  ```

  ```javascript nodejs theme={"dark"}
  cashfree
  .PGFetchOrder("<order_id>")
  .then((response) => {
  	console.log("Order fetched successfully:", response.data);
  })
  .catch((error) => {
  	console.error("Error:", error.response.data.message);
  });
  ```

  ```python python theme={"dark"}
  from cashfree_pg.models.create_order_request import CreateOrderRequest
  from cashfree_pg.api_client import Cashfree
  from cashfree_pg.models.customer_details import CustomerDetails
  from cashfree_pg.models.order_meta import OrderMeta

  Cashfree.XClientId = "<x-client-id>"
  Cashfree.XClientSecret = "<x-client-secret>"
  Cashfree.XEnvironment = Cashfree.SANDBOX
  x_api_version = "2023-08-01"

  try:
      api_response = Cashfree().PGFetchOrder(x_api_version, "order_3242X4jQ5f0S9KYxZO9mtDL1Kx2Y7u", None)
      print(api_response.data)
  except Exception as e:
      print(e)

  ```

  ```java java theme={"dark"}
  import com.cashfree.*;
  //other code

  try {
      Cashfree.XClientId = "<x-client-id>";
      Cashfree.XClientSecret = "<x-client-secret>";
      Cashfree.XEnvironment = Cashfree.SANDBOX;

      Cashfree cashfree = new Cashfree();
      String xApiVersion = "2023-08-01";

      ApiResponse<OrderEntity> responseFetchOrder = cashfree.PGFetchOrder(xApiVersion, "<order_id>", null, null, null);
      System.out.println(response.getData().getOrderId());
  } catch (ApiException e) {
      throw new RuntimeException(e);
  }
  ```

  ```go go theme={"dark"}
  version := "2023-08-01"
  response, httpResponse, err := cashfree.PGFetchOrder(&version, "<order_id>", nil, nil, nil)
  if err != nil {
  	fmt.Println(err.Error())
  } else {
  	fmt.Println(httpResponse.StatusCode)
  	fmt.Println(response)
  }
  ```

  ```csharp .net theme={"dark"}
  using cashfree_pg.Client;
  using cashfree_pg.Model;

  Cashfree.XClientId = "<x-client-id>";
  Cashfree.XClientSecret = "<x-client-secret>";
  Cashfree.XEnvironment = Cashfree.SANDBOX;
  var cashfree = new Cashfree();
  var xApiVersion = "2023-08-01";

  try {
      var result = cashfree.PGFetchOrder(xApiVersion, "<order_id>>", null, null);
      Console.WriteLine(result);
      Console.WriteLine(result.StatusCode);
      Console.WriteLine((result.Content as OrderEntity));
  } catch (ApiException e) {
      Console.WriteLine("Exception when calling PGFetchOrder: " + e.Message);
      Console.WriteLine("Status Code: " + e.ErrorCode);
      Console.WriteLine(e.StackTrace);
  }
  ```

  ```php php theme={"dark"}
  $x_api_version = "2023-08-01";
  try {
      $response = $cashfree->PGFetchOrder($x_api_version, "<order_id>");
      print_r($response);
  } catch (Exception $e) {
      echo 'Exception when calling PGFetchOrder: ', $e->getMessage(), PHP_EOL;
  }
  ```
</CodeGroup>

<Note>
  Always verify the order status from your backend before you deliver goods or services to the customer. You can use the [Get Order API](/docs/api-reference/payments/latest/orders/get-order) for this. An order is successful when the `order_status` is `PAID`.
</Note>

## Testing

After you integrate a payment method, verify that it behaves as expected. Follow these steps to test:

1. Trigger a payment using each method you've integrated.
2. Confirm that the SDK opens the correct payment screen for the method (Cashfree's hosted card, net banking, or wallet screen, or the selected UPI app).
3. Confirm that `onPaymentVerify` or `onPaymentFailure` is called when the payment flow ends.

Use the [sandbox environment](/docs/payments/online/resources/sandbox-environment) to test payments before you go live.

## Error codes

To confirm the error returned in your Android application, you can view the error codes exposed by the SDK.

<Accordion title="Show error codes">
  The SDK validation errors are grouped by category as follows:

  ### Session errors

  | Error code               | Message                                      |
  | ------------------------ | -------------------------------------------- |
  | `SESSION_OBJECT_MISSING` | The "session" is missing in the request.     |
  | `PAYMENT_OBJECT_MISSING` | The "payment" is missing in the request.     |
  | `ENVIRONMENT_MISSING`    | The "environment" is missing in the request. |
  | `ORDER_ID_MISSING`       | The "order\_id" is missing in the request.   |

  ### Card errors

  | Error code                  | Message                                           |
  | --------------------------- | ------------------------------------------------- |
  | `CARD_OBJECT_MISSING`       | The CFCard object is missing in the request.      |
  | `CARD_NUMBER_MISSING`       | The "card\_number" is missing in the request.     |
  | `CARD_EXPIRY_MONTH_MISSING` | The "card\_expiry\_mm" is missing in the request. |
  | `CARD_EXPIRY_YEAR_MISSING`  | The "card\_expiry\_yy" is missing in the request. |
  | `CARD_CVV_MISSING`          | The "card\_cvv" is missing in the request.        |
  | `CHANNEL_MISSING`           | The "channel" is missing in the request.          |

  ### Net banking errors

  | Error code                  | Message                                            |
  | --------------------------- | -------------------------------------------------- |
  | `NETBANKING_OBJECT_MISSING` | The CFNetbanking object is missing in the request. |
  | `NB_BANK_CODE_MISSING`      | The "bank\_code" is missing in the request.        |

  ### Wallet errors

  | Error code               | Message                                                      |
  | ------------------------ | ------------------------------------------------------------ |
  | `WALLET_OBJECT_MISSING`  | The CFWallet object is missing in the request.               |
  | `WALLET_CHANNEL_MISSING` | The "channel" is missing in the wallet payment request.      |
  | `WALLET_PHONE_MISSING`   | The "phone number" is missing in the wallet payment request. |

  ### UPI errors

  | Error code                | Message                                                                                                                                                            |
  | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
  | `UPI_OBJECT_MISSING`      | The CFUPI object is missing in the request.                                                                                                                        |
  | `UPI_ID_MISSING`          | The "upi\_id" is missing in the request.                                                                                                                           |
  | `INVALID_UPI_APP_ID_SENT` | The id sent is invalid. The value has to be one of the following: "tez://", "phonepe://", "paytm://", "bhim://". See the note in the CFUPI class for more details. |
  | `NO_UPI_APP_AVAILABLE`    | You don't have any UPI apps installed or ready for payment.                                                                                                        |

  ### Callback and general errors

  | Error code                    | Message                                                                                                   |
  | ----------------------------- | --------------------------------------------------------------------------------------------------------- |
  | `MISSING_CALLBACK`            | The callback is missing in the request.                                                                   |
  | `INVALID_PAYMENT_OBJECT_SENT` | The payment object that's set doesn't match any payment mode. Set the correct payment mode and try again. |
  | `WRONG_CALLING_CONTEXT`       | Calling context must be activity or fragment.                                                             |
</Accordion>

### Other options

The following optional configurations let you customise SDK behaviour and enable logging for troubleshooting.

<AccordionGroup>
  <Accordion title="(Optional) Custom initialisation of the SDK">
    If you want to initialise the SDK yourself, follow these steps. Initialise the SDK in your Application class to avoid runtime issues.

    <Steps>
      <Step title="Add the following to your values.xml file">
        `<bool name="cashfree_pg_core_auto_initialize_enabled">false</bool>`
      </Step>

      <Step title="Initialise the SDK yourself before attempting payment">
        ```java theme={"dark"}
        Executors.newSingleThreadExecutor().execute(() -> {
            CFPaymentGatewayService.initialize(getApplicationContext());
        });
        ```
      </Step>
    </Steps>
  </Accordion>

  <Accordion title="(Optional) Enable logging to debug issues">
    To enable SDK logging, add the following entry to your `values.xml` file:

    `<integer name="cashfree_pg_logging_level">3</integer>`

    The following logging levels are available, listed from least to most verbose:

    | Level   | Value |
    | ------- | ----- |
    | VERBOSE | 2     |
    | DEBUG   | 3     |
    | INFO    | 4     |
    | WARN    | 5     |
    | ERROR   | 6     |
    | ASSERT  | 7     |
  </Accordion>
</AccordionGroup>

<div
  className="callout info"
  style={{
backgroundColor: 'light-dark(#f9f7fd, #2d1b4e)',
borderColor: 'light-dark(#cdbaef, #6930ca)',
color: 'light-dark(#000000, #ffffff)'
}}
>
  <p style={{fontSize: '1.3em', fontWeight: '500', marginBottom: '16px'}}>Affiliate partner program</p>

  <p>As a developer building payment experiences for your clients, you can earn additional income while providing them with industry-leading payment solutions.</p>

  <p>Join the <a href="https://partner.cashfree.com/partner-ui/authentication/signup?source-action=Affiliate%20Program%20LP&action=Sign%20Up&button-id=StartNow_CashfreeAffiliatePartnerProgram">Cashfree affiliate partner program</a> and get rewarded every time your clients use Cashfree.</p>

  <p>**What you get:**</p>

  <ul>
    <li>Earn up to 0.25% commission on every transaction.</li>
    <li>Become a trusted fintech partner for your clients.</li>
    <li>Access to a dedicated partner manager for expert support.</li>
  </ul>

  <p>**What your clients get:**</p>

  <ul>
    <li>Instant activation and go live in minutes.</li>
    <li>Industry-best success rate across all payment modes.</li>
    <li>Effortless acceptance of international payments in 140+ currencies.</li>
  </ul>

  <p>Get started today. <a href="https://partner.cashfree.com/partner-ui/authentication/signup?source-action=Affiliate%20Program%20LP&action=Sign%20Up&button-id=StartNow_BecomeAPartner">Become a partner now</a>.</p>
</div>

<div class="hidden" data-table-of-contents="bottom">
  <p class="mt-4 font-medium flex items-center gap-2 related-docs-heading">
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="w-4 h-4">
      <path d="M3 4h7a2 2 0 0 1 2 2v13a2 2 0 0 0-2-2H3z" />

      <path d="M21 4h-7a2 2 0 0 0-2 2v13a2 2 0 0 1 2-2h7z" />
    </svg>

    <span>Related topics</span>
  </p>

  <ul>
    <li><a href="/docs/docs/api-reference/payments/latest/orders/create-order">Create Order API</a></li>
    <li><a href="/docs/docs/api-reference/payments/latest/orders/get-order">Get Order API</a></li>
    <li><a href="/docs/docs/payments/online/element/custom-card/android-custom-card">Android Custom Card Component</a></li>
    <li><a href="/docs/docs/payments/online/element/overview">Element Overview</a></li>
    <li><a href="https://github.com/cashfree/nextgen-android" target="_blank">Android SDK on GitHub</a></li>
  </ul>
</div>
