> ## 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.

# Custom Checkout Integration - Android

> Add UPI Intent support inside a WebView-based custom Cashfree checkout for Android by using the JS SDK and the steps documented in this integration guide.

Merchants integrating the Cashfree Web checkout using Cashfree JS SDK. But they are unable to see the UPI intent option on the checkout page as the Cashfree checkout page is opening on Webview.

This document provides guidance for merchants developing their applications on platforms such as `Android, React Native, Flutter, Cordova` who have integrated the Cashfree JS SDK.

<Note>If you using Cashfree Mobile SDK, then please follow cashfree official mobile sdk docs.</Note>

### Feature Flag based solution

Our checkout page provides the capability to display default UPI apps, including `PhonePe, GPay, and Paytm`, along with an option to pay via any UPI app. This feature ensures that these UPI apps are visible on the checkout page, regardless of whether they are installed on the user's device.

When a user selects a UPI app, merchants are responsible for handling the redirection. Only a minimal code snippet is required on the merchant's side to handle the UPI app click and manage the subsequent redirection process.

<AccordionGroup>
  <Accordion title="Android">
    <CodeGroup>
      ```java Android theme={"dark"}
      // Override shouldOverrideUrlLoading method in your webview.
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String request) {
         if (request != null) {
               if((request.startsWith("upi://pay") 
                   || request.startsWith("tez://") 
                   || request.startsWith("gpay://")
                   || request.startsWith("paytmmp://")
                   || request.startsWith("phonepe://")){
                      // Open UPI app from here
                      final Intent intent = new Intent();
                      intent.setAction(Intent.ACTION_VIEW);
                      intent.setData(Uri.parse(url));
                      PackageManager pm = getPackageManager();
                      final List<ResolveInfo> resInfo = pm.queryIntentActivities(intent, 0);
                      if (!resInfo.isEmpty()) {
                          startActivity(intent);
                      } else {
                         //handle no app scenario
                      }
                     return true;
                   }
         }
         return false;
      }
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="React-Native">
    <CodeGroup>
      ```js JS theme={"dark"}
      // Override onShouldStartLoadWithRequest method in your webview.
      onShouldStartLoadWithRequest={event => {
               const url  = event.url
               if((url.startsWith("upi://pay")
                  || url.startsWith("tez://")|| url.startsWith("gpay://")
                  || url.startsWith("paytmmp://")
                  || url.startsWith("phonepe://")) {
                Linking.canOpenURL(url).then(supported => {
                        if (supported) {
                              Linking.openURL(url);
                        }else{
                            console.log("Not able to open")
                        }
                      });
                      return false;
                }
              return true;
      }}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Flutter">
    <CodeGroup>
      ```js Dart theme={"dark"}
      // Override shouldOverrideUrlLoading method in your webview.
      shouldOverrideUrlLoading: (controller, navigationAction) async {
                var uri = navigationAction.request.url!;
                if (["upi", "tez","gpay", "paytmmp","phonepe"].contains(uri.scheme)) {
                  print("Opening PSP app");
                  await launchUrl(uri);
                  return NavigationActionPolicy.CANCEL;
                }
                return NavigationActionPolicy.ALLOW;
      }
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

<Note>To enable this flag, please fill out the [Support Form](https://merchant.cashfree.com/merchants/landing?env=prod\&raise_issue=1). they will enable this flag.</Note>

### Code based solution

You have to write some custom logic in your mobile app while opening Cashfree checkout page. When you are loading Webview, Please register `JS bridge` with name `Android` and implement few of its method.

<AccordionGroup>
  <Accordion title="Android">
    [Sample code](https://github.com/kishan-cashfree/CFWebIntegrationSample/blob/245b0d655475ad5f5595437efc1e6eb503774f68/app/src/main/java/com/cashfree/webintegration/MainActivity.kt#L87)
  </Accordion>

  <Accordion title="React-Native">
    In this case, you have to write android native module
    [Native Module](https://github.com/kishan-cashfree/CFWebIntegrationRN/tree/master/android/app/src/main/java/com/cfwebintegrationrn)

    Use these native module in you JS/TS code
    [JS code](https://github.com/kishan-cashfree/CFWebIntegrationRN/tree/master/native)

    [Sample Usage](https://github.com/kishan-cashfree/CFWebIntegrationRN/blob/master/WebSitePaymentScreen.tsx)
  </Accordion>

  <Accordion title="Flutter">
    In this case, you have to write android native module
    [Native Module](https://github.com/kishan-cashfree/CFSamplewebviewFL/tree/master/android/app/src/main/kotlin/com/example/cfsamplewebviewfl)

    Use these native module in you Dart code
    [Dart Code](https://github.com/kishan-cashfree/CFSamplewebviewFL/blob/master/lib/ui/webview/customwebview.dart)

    [Sample Usage](https://github.com/kishan-cashfree/CFSamplewebviewFL/blob/master/lib/main.dart)
  </Accordion>
</AccordionGroup>

<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/api-reference/payments/latest/orders/create">Create Order API</a></li>
    <li><a href="/docs/payments/online/go-live/whitelist">Domain Whitelisting</a></li>
    <li><a href="/docs/payments/manage/payment-methods#upi">UPI Intent Methods</a></li>
    <li><a href="/docs/payments/manage/payment-methods">Payment Methods</a></li>
    <li><a href="/docs/payments/online/web/redirect">Hosted Checkout Integration</a></li>
  </ul>
</div>
